From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.14]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3A3DA3BFAE0 for ; Wed, 26 Aug 2026 09:49:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.14 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737743; cv=none; b=ciJ5whVMI9DFwkkehhH/iSmKIgokWEVG/eitqUHMZLVUTLtInaoNLqdZf+263PZa0o22J8la433MRVu/WWXFzmmrSyCR8LnMP9mFq5s1vyTeRdiCZhvvysee2PB3Hun+NgGfg3qGHboXXeHahwQ6AKU30BUnd1aSrCN/LblfX0E= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737743; c=relaxed/simple; bh=V4W7KOtsjsnY4yHHWe5hb+AdAGYAbZLZ7R/sQDp5ISc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WQzhZr8K2Zo9iLcDyc8QShuCOeD6kB6Gp/LK9JdJqwncTXnm1LZGtBD85h9ujrL95Lz+iOBv2pBqysehMRsVgTqKBmq/3JGO/QU82TSEaXqshfmy4GNUh12vvwpVyfDfdWifse+dsVX27Q727Kdmzhd7z0h7h6zm2ybq/ghcacQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=QyTWHZZk; arc=none smtp.client-ip=192.198.163.14 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="QyTWHZZk" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1787737741; x=1819273741; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=V4W7KOtsjsnY4yHHWe5hb+AdAGYAbZLZ7R/sQDp5ISc=; b=QyTWHZZkuKnh8XxMd8hQ5nNGCQM+KUE2cKEbzYa0OrYeNlaWXS4e6jB5 vDMZJvpfb6UHPFNT+TivKVdbuMo/s1w3CturUwhbxZnfZ0nWJbVGsHXUb k5SOC2fzdrJMh4gl9IrgxvAtI8ng7erF4HQOV97jpvz6QRdepDp0Pvaf4 Z4QnbO8+BQcdpAH4HJV4ojfyGH3a/kpd+pfQOU9HxvTnPWKSFORSiZ1k4 EnL+/UNZQfHw0CxqcE1HJ27VZFdeFHLysKohdTnYBoVnvtcEJn4eEry/z hFgGEBLUDO4efXajnqAfrT3/snrMp3PgzqJtUEft0aCAJ25Juv5Bdw6vF g==; X-CSE-ConnectionGUID: KLJ7wZfaSYW3AR7V9vVvXQ== X-CSE-MsgGUID: imerr6YZTUSsCvwF04VcJA== X-IronPort-AV: E=McAfee;i="6800,10657,11886"; a="88232962" X-IronPort-AV: E=Sophos;i="6.25,244,1779174000"; d="scan'208";a="88232962" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by fmvoesa108.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Aug 2026 02:48:58 -0700 X-CSE-ConnectionGUID: 1UbTnaqoTvajhB2pLYJtzA== X-CSE-MsgGUID: hQJ5GjLQRoCASmWnTVD8yA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,244,1779174000"; d="scan'208";a="261404824" Received: from gnrd8.igk.intel.com (HELO GNRD8) ([10.123.232.137]) by fmviesa009.fm.intel.com with ESMTP; 26 Aug 2026 02:48:56 -0700 From: Sergey Temerkhanov To: intel-wired-lan@lists.osuosl.org Cc: netdev@vger.kernel.org Subject: [PATCH iwl-next v4 6/6] ice: dpll: Rework the SMA control logic to match the requirements Date: Wed, 26 Aug 2026 09:48:49 +0000 Message-ID: <20260826094849.4112016-7-sergey.temerkhanov@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260826094849.4112016-1-sergey.temerkhanov@intel.com> References: <20260826094849.4112016-1-sergey.temerkhanov@intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Przemyslaw Korba --- drivers/net/ethernet/intel/ice/ice_dpll.c | 172 ++++++++++++++++++---- 1 file changed, 146 insertions(+), 26 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index 6a51b2482a5b..1cea8ebbfd94 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -1345,28 +1345,37 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p, { struct ice_dplls *d = &p->pf->dplls; struct ice_dpll_pin *peer; - u8 data; - int ret; + struct ice_dpll_pin *target = NULL; + struct ice_dpll_pin_config peer_config; + enum ice_dpll_pin_type type = 0; + u8 data, old_data = 0; + int peer_dpll_idx, restore_err, ret; if (p->direction == direction && p->active) return 0; ret = ice_read_sma_ctrl(&p->pf->hw, &data); if (ret) return ret; + old_data = data; 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; + data &= ~ICE_SMA2_TX_EN; } 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: @@ -1378,7 +1387,7 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p, ICE_DPLL_PIN_TYPE_SOFTWARE, extack); if (ret) - return ret; + goto restore_sma; /* When a direction change activates the paired U.FL pin, enable * its backing CGU pin so the pin reports as connected. Without @@ -1389,27 +1398,44 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p, */ peer = p->muxed; if (peer->active) { - struct ice_dpll_pin *target; - enum ice_dpll_pin_type type; - int peer_ret; - if (peer->output) { target = peer->output; type = ICE_DPLL_PIN_TYPE_OUTPUT; - } else { + } else if (peer->input) { target = peer->input; type = ICE_DPLL_PIN_TYPE_INPUT; + } else { + ret = -EINVAL; + goto restore_sma; } - peer_ret = ice_dpll_get_fallback_idx(d, target); - if (peer_ret < 0) - peer_ret = d->eec.dpll_idx; - ret = ice_dpll_pin_enable(&p->pf->hw, target, peer_ret, type, - extack); - if (!ret) - ret = ice_dpll_pin_state_update(p->pf, target, - type, extack); + + ret = ice_dpll_pin_config_get(p->pf, target, type, + &peer_config, extack); + if (ret) + goto restore_sma; + + peer_dpll_idx = ice_dpll_get_fallback_idx(d, target); + if (peer_dpll_idx < 0) + peer_dpll_idx = d->eec.dpll_idx; + ret = ice_dpll_pin_enable(&p->pf->hw, target, peer_dpll_idx, + type, extack); + if (ret) + goto restore_peer; + ret = ice_dpll_pin_state_update(p->pf, target, type, extack); + if (ret) + goto restore_peer; } + return 0; + +restore_peer: + restore_err = + ice_dpll_pin_config_restore(p->pf, target, type, &peer_config, + extack, ret); + if (restore_err) + ret = restore_err; +restore_sma: + ice_dpll_restore_sma_ctrl(p->pf, old_data, ret); return ret; } @@ -1667,11 +1693,15 @@ ice_dpll_sma_pin_state_set(const struct dpll_pin *pin, void *pin_priv, struct netlink_ext_ack *extack) { struct ice_dpll_pin *sma = pin_priv, *target; + struct ice_dpll_pin *peer_target = NULL; struct ice_dpll *d = dpll_priv; struct ice_pf *pf = sma->pf; - enum ice_dpll_pin_type type; + enum ice_dpll_pin_type peer_type = 0, type; + struct ice_dpll_pin_config old_config; + struct ice_dpll_pin_config peer_config; + u8 old_data = 0; bool enable; - int ret; + int peer_dpll_idx, restore_err, ret = -EINVAL; if (ice_dpll_is_reset(pf, extack)) return -EBUSY; @@ -1679,6 +1709,10 @@ ice_dpll_sma_pin_state_set(const struct dpll_pin *pin, void *pin_priv, mutex_lock(&pf->dplls.lock); switch (state) { case DPLL_PIN_STATE_SELECTABLE: + /* Reject direction-mismatched requests: SELECTABLE + OUTPUT + * is an invalid combination, return -EINVAL in this case + * immediately instead of disabling the pin. + */ if (sma->direction == DPLL_PIN_DIRECTION_OUTPUT) { enable = false; ret = -EINVAL; @@ -1687,6 +1721,10 @@ ice_dpll_sma_pin_state_set(const struct dpll_pin *pin, void *pin_priv, enable = true; break; case DPLL_PIN_STATE_CONNECTED: + /* Reject direction-mismatched requests: CONNECTED + INPUT + * is an invalid combination, return -EINVAL in this case + * immediately instead of disabling the pin. + */ if (sma->direction == DPLL_PIN_DIRECTION_INPUT) { enable = false; ret = -EINVAL; @@ -1722,13 +1760,95 @@ 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; + switch (sma->idx) { + case ICE_DPLL_PIN_SW_1_IDX: + data &= ~ICE_SMA1_TX_EN; + break; + case ICE_DPLL_PIN_SW_2_IDX: + data &= ~ICE_SMA2_UFL2_RX_DIS; + data &= ~ICE_SMA2_TX_EN; + break; + default: + ret = -EINVAL; + goto unlock; + } + ret = ice_write_sma_ctrl(&pf->hw, data); + if (ret) + goto restore_sma_ctrl; + ret = ice_dpll_sw_pins_update(pf); + if (ret) + goto restore_sma_ctrl; + + ret = ice_dpll_pin_config_get(pf, target, type, &old_config, + extack); + 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_target; + /* Refresh target state before peer-side operations. */ ret = ice_dpll_pin_state_update(pf, target, type, extack); + if (ret) + goto restore_target; + + if (sma->muxed && sma->muxed->active) { + ice_dpll_get_peer_target(sma->muxed, &peer_target, + &peer_type); + if (!peer_target) { + ret = -EINVAL; + goto restore_target; + } + + ret = ice_dpll_pin_config_get(pf, peer_target, peer_type, + &peer_config, extack); + if (ret) + goto restore_target; + + peer_dpll_idx = + ice_dpll_get_fallback_idx(&pf->dplls, peer_target); + if (peer_dpll_idx < 0) + peer_dpll_idx = d->dpll_idx; + ret = ice_dpll_pin_enable(&pf->hw, peer_target, + peer_dpll_idx, peer_type, extack); + if (ret) + goto restore_peer; + ret = ice_dpll_pin_state_update(pf, peer_target, peer_type, + extack); + if (ret) + goto restore_peer; + } + } 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_peer: + restore_err = + ice_dpll_pin_config_restore(pf, peer_target, peer_type, + &peer_config, extack, ret); + if (restore_err) + ret = restore_err; +restore_target: + restore_err = + ice_dpll_pin_config_restore(pf, target, type, &old_config, + extack, ret); + if (restore_err) + ret = restore_err; +restore_sma_ctrl: + restore_err = ice_dpll_restore_sma_ctrl(pf, old_data, ret); + if (restore_err) + ret = restore_err; unlock: mutex_unlock(&pf->dplls.lock); -- 2.53.0