Skip to content

Commit 6f9d839

Browse files
orospPaolo Abeni
authored andcommitted
ice: fix SMA and U.FL pin state changes affecting paired pin
SMA and U.FL pins share physical signal paths in pairs (SMA1/U.FL1 and SMA2/U.FL2) controlled by the PCA9575 GPIO expander. Each pair can only have one active pin at a time: SMA1 output and U.FL1 output share the same CGU output, SMA2 input and U.FL2 input share the same CGU input. The PCA9575 register bits determine which connector in each pair owns the signal path. The driver does not account for this pairing in two places: ice_dpll_ufl_pin_state_set() modifies PCA9575 bits and disables the backing CGU pin without checking whether the U.FL pin is currently active. Disconnecting an already inactive U.FL pin flips bits that the paired SMA pin relies on, breaking its connection. ice_dpll_sma_direction_set() does not propagate direction changes to the paired U.FL pin. For SMA2/U.FL2 the ICE_SMA2_UFL2_RX_DIS bit is never managed, so U.FL2 stays disconnected after SMA2 switches to output. For both pairs the backing CGU pin of the U.FL side is never enabled when a direction change activates it, so userspace sees the pin as disconnected even though the routing is correct. Fix by guarding the U.FL disconnect path against inactive pins and by updating the paired U.FL pin fully on SMA direction changes: manage ICE_SMA2_UFL2_RX_DIS for the SMA2/U.FL2 pair and enable the backing CGU pin whenever the peer becomes active. Fixes: 2dd5d03 ("ice: redesign dpll sma/u.fl pins control") Signed-off-by: Petr Oros <poros@redhat.com> Tested-by: Alexander Nowlin <alexander.nowlin@intel.com> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Link: https://patch.msgid.link/20260427-jk-iwl-net-petr-oros-fixes-v1-8-cdcb48303fd8@intel.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 56a643a commit 6f9d839

1 file changed

Lines changed: 49 additions & 1 deletion

File tree

drivers/net/ethernet/intel/ice/ice_dpll.c

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1171,6 +1171,8 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p,
11711171
enum dpll_pin_direction direction,
11721172
struct netlink_ext_ack *extack)
11731173
{
1174+
struct ice_dplls *d = &p->pf->dplls;
1175+
struct ice_dpll_pin *peer;
11741176
u8 data;
11751177
int ret;
11761178

@@ -1189,8 +1191,9 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p,
11891191
case ICE_DPLL_PIN_SW_2_IDX:
11901192
if (direction == DPLL_PIN_DIRECTION_INPUT) {
11911193
data &= ~ICE_SMA2_DIR_EN;
1194+
data |= ICE_SMA2_UFL2_RX_DIS;
11921195
} else {
1193-
data &= ~ICE_SMA2_TX_EN;
1196+
data &= ~(ICE_SMA2_TX_EN | ICE_SMA2_UFL2_RX_DIS);
11941197
data |= ICE_SMA2_DIR_EN;
11951198
}
11961199
break;
@@ -1202,6 +1205,34 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p,
12021205
ret = ice_dpll_pin_state_update(p->pf, p,
12031206
ICE_DPLL_PIN_TYPE_SOFTWARE,
12041207
extack);
1208+
if (ret)
1209+
return ret;
1210+
1211+
/* When a direction change activates the paired U.FL pin, enable
1212+
* its backing CGU pin so the pin reports as connected. Without
1213+
* this the U.FL routing is correct but the CGU pin stays disabled
1214+
* and userspace sees the pin as disconnected. Do not disable the
1215+
* backing pin when U.FL becomes inactive because the SMA pin may
1216+
* still be using it.
1217+
*/
1218+
peer = &d->ufl[p->idx];
1219+
if (peer->active) {
1220+
struct ice_dpll_pin *target;
1221+
enum ice_dpll_pin_type type;
1222+
1223+
if (peer->output) {
1224+
target = peer->output;
1225+
type = ICE_DPLL_PIN_TYPE_OUTPUT;
1226+
} else {
1227+
target = peer->input;
1228+
type = ICE_DPLL_PIN_TYPE_INPUT;
1229+
}
1230+
ret = ice_dpll_pin_enable(&p->pf->hw, target,
1231+
d->eec.dpll_idx, type, extack);
1232+
if (!ret)
1233+
ret = ice_dpll_pin_state_update(p->pf, target,
1234+
type, extack);
1235+
}
12051236

12061237
return ret;
12071238
}
@@ -1253,6 +1284,14 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
12531284
data &= ~ICE_SMA1_MASK;
12541285
enable = true;
12551286
} else if (state == DPLL_PIN_STATE_DISCONNECTED) {
1287+
/* Skip if U.FL1 is not active, setting TX_EN
1288+
* while DIR_EN is set would also deactivate
1289+
* the paired SMA1 output.
1290+
*/
1291+
if (data & (ICE_SMA1_DIR_EN | ICE_SMA1_TX_EN)) {
1292+
ret = 0;
1293+
goto unlock;
1294+
}
12561295
data |= ICE_SMA1_TX_EN;
12571296
enable = false;
12581297
} else {
@@ -1267,6 +1306,15 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
12671306
data &= ~ICE_SMA2_UFL2_RX_DIS;
12681307
enable = true;
12691308
} else if (state == DPLL_PIN_STATE_DISCONNECTED) {
1309+
/* Skip if U.FL2 is not active, setting
1310+
* UFL2_RX_DIS could also disable the paired
1311+
* SMA2 input.
1312+
*/
1313+
if (!(data & ICE_SMA2_DIR_EN) ||
1314+
(data & ICE_SMA2_UFL2_RX_DIS)) {
1315+
ret = 0;
1316+
goto unlock;
1317+
}
12701318
data |= ICE_SMA2_UFL2_RX_DIS;
12711319
enable = false;
12721320
} else {

0 commit comments

Comments
 (0)