Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: 2dd5d03c77e2 ("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>

authored by

Petr Oros and committed by
Paolo Abeni
6f9d8393 56a643ae

+49 -1
+49 -1
drivers/net/ethernet/intel/ice/ice_dpll.c
··· 1171 1171 enum dpll_pin_direction direction, 1172 1172 struct netlink_ext_ack *extack) 1173 1173 { 1174 + struct ice_dplls *d = &p->pf->dplls; 1175 + struct ice_dpll_pin *peer; 1174 1176 u8 data; 1175 1177 int ret; 1176 1178 ··· 1191 1189 case ICE_DPLL_PIN_SW_2_IDX: 1192 1190 if (direction == DPLL_PIN_DIRECTION_INPUT) { 1193 1191 data &= ~ICE_SMA2_DIR_EN; 1192 + data |= ICE_SMA2_UFL2_RX_DIS; 1194 1193 } else { 1195 - data &= ~ICE_SMA2_TX_EN; 1194 + data &= ~(ICE_SMA2_TX_EN | ICE_SMA2_UFL2_RX_DIS); 1196 1195 data |= ICE_SMA2_DIR_EN; 1197 1196 } 1198 1197 break; ··· 1205 1202 ret = ice_dpll_pin_state_update(p->pf, p, 1206 1203 ICE_DPLL_PIN_TYPE_SOFTWARE, 1207 1204 extack); 1205 + if (ret) 1206 + return ret; 1207 + 1208 + /* When a direction change activates the paired U.FL pin, enable 1209 + * its backing CGU pin so the pin reports as connected. Without 1210 + * this the U.FL routing is correct but the CGU pin stays disabled 1211 + * and userspace sees the pin as disconnected. Do not disable the 1212 + * backing pin when U.FL becomes inactive because the SMA pin may 1213 + * still be using it. 1214 + */ 1215 + peer = &d->ufl[p->idx]; 1216 + if (peer->active) { 1217 + struct ice_dpll_pin *target; 1218 + enum ice_dpll_pin_type type; 1219 + 1220 + if (peer->output) { 1221 + target = peer->output; 1222 + type = ICE_DPLL_PIN_TYPE_OUTPUT; 1223 + } else { 1224 + target = peer->input; 1225 + type = ICE_DPLL_PIN_TYPE_INPUT; 1226 + } 1227 + ret = ice_dpll_pin_enable(&p->pf->hw, target, 1228 + d->eec.dpll_idx, type, extack); 1229 + if (!ret) 1230 + ret = ice_dpll_pin_state_update(p->pf, target, 1231 + type, extack); 1232 + } 1208 1233 1209 1234 return ret; 1210 1235 } ··· 1284 1253 data &= ~ICE_SMA1_MASK; 1285 1254 enable = true; 1286 1255 } else if (state == DPLL_PIN_STATE_DISCONNECTED) { 1256 + /* Skip if U.FL1 is not active, setting TX_EN 1257 + * while DIR_EN is set would also deactivate 1258 + * the paired SMA1 output. 1259 + */ 1260 + if (data & (ICE_SMA1_DIR_EN | ICE_SMA1_TX_EN)) { 1261 + ret = 0; 1262 + goto unlock; 1263 + } 1287 1264 data |= ICE_SMA1_TX_EN; 1288 1265 enable = false; 1289 1266 } else { ··· 1306 1267 data &= ~ICE_SMA2_UFL2_RX_DIS; 1307 1268 enable = true; 1308 1269 } else if (state == DPLL_PIN_STATE_DISCONNECTED) { 1270 + /* Skip if U.FL2 is not active, setting 1271 + * UFL2_RX_DIS could also disable the paired 1272 + * SMA2 input. 1273 + */ 1274 + if (!(data & ICE_SMA2_DIR_EN) || 1275 + (data & ICE_SMA2_UFL2_RX_DIS)) { 1276 + ret = 0; 1277 + goto unlock; 1278 + } 1309 1279 data |= ICE_SMA2_UFL2_RX_DIS; 1310 1280 enable = false; 1311 1281 } else {