Skip to content

Commit 8ee887d

Browse files
Mike Marciniszynrolandd
authored andcommitted
IB/qib: Fix over-scheduling of QSFP work
Don't over-schedule QSFP work on driver initialization. It could end up being run simultaneously on two different CPUs resulting in bad EEPROM reads. In combination with setting the physical IB link state prior to the IBC being brought out of reset, this can cause the link state machine to start training early with wrong settings. Signed-off-by: Mitko Haralanov <[email protected]> Signed-off-by: Mike Marciniszyn <[email protected]> Signed-off-by: Roland Dreier <[email protected]>
1 parent 042f36e commit 8ee887d

File tree

2 files changed

+8
-20
lines changed

2 files changed

+8
-20
lines changed

drivers/infiniband/hw/qib/qib_iba7322.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2307,19 +2307,11 @@ static int qib_7322_bringup_serdes(struct qib_pportdata *ppd)
23072307
SYM_LSB(IBCCtrlA_0, MaxPktLen);
23082308
ppd->cpspec->ibcctrl_a = ibc; /* without linkcmd or linkinitcmd! */
23092309

2310-
/* initially come up waiting for TS1, without sending anything. */
2311-
val = ppd->cpspec->ibcctrl_a | (QLOGIC_IB_IBCC_LINKINITCMD_DISABLE <<
2312-
QLOGIC_IB_IBCC_LINKINITCMD_SHIFT);
2313-
2314-
ppd->cpspec->ibcctrl_a = val;
23152310
/*
23162311
* Reset the PCS interface to the serdes (and also ibc, which is still
23172312
* in reset from above). Writes new value of ibcctrl_a as last step.
23182313
*/
23192314
qib_7322_mini_pcs_reset(ppd);
2320-
qib_write_kreg(dd, kr_scratch, 0ULL);
2321-
/* clear the linkinit cmds */
2322-
ppd->cpspec->ibcctrl_a &= ~SYM_MASK(IBCCtrlA_0, LinkInitCmd);
23232315

23242316
if (!ppd->cpspec->ibcctrl_b) {
23252317
unsigned lse = ppd->link_speed_enabled;
@@ -2385,6 +2377,14 @@ static int qib_7322_bringup_serdes(struct qib_pportdata *ppd)
23852377
ppd->cpspec->ibcctrl_a |= SYM_MASK(IBCCtrlA_0, IBLinkEn);
23862378
set_vls(ppd);
23872379

2380+
/* initially come up DISABLED, without sending anything. */
2381+
val = ppd->cpspec->ibcctrl_a | (QLOGIC_IB_IBCC_LINKINITCMD_DISABLE <<
2382+
QLOGIC_IB_IBCC_LINKINITCMD_SHIFT);
2383+
qib_write_kreg_port(ppd, krp_ibcctrl_a, val);
2384+
qib_write_kreg(dd, kr_scratch, 0ULL);
2385+
/* clear the linkinit cmds */
2386+
ppd->cpspec->ibcctrl_a = val & ~SYM_MASK(IBCCtrlA_0, LinkInitCmd);
2387+
23882388
/* be paranoid against later code motion, etc. */
23892389
spin_lock_irqsave(&dd->cspec->rcvmod_lock, flags);
23902390
ppd->p_rcvctrl |= SYM_MASK(RcvCtrl_0, RcvIBPortEnable);

drivers/infiniband/hw/qib/qib_qsfp.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -480,18 +480,6 @@ void qib_qsfp_init(struct qib_qsfp_data *qd,
480480
udelay(20); /* Generous RST dwell */
481481

482482
dd->f_gpio_mod(dd, mask, mask, mask);
483-
/* Spec says module can take up to two seconds! */
484-
mask = QSFP_GPIO_MOD_PRS_N;
485-
if (qd->ppd->hw_pidx)
486-
mask <<= QSFP_GPIO_PORT2_SHIFT;
487-
488-
/* Do not try to wait here. Better to let event handle it */
489-
if (!qib_qsfp_mod_present(qd->ppd))
490-
goto bail;
491-
/* We see a module, but it may be unwise to look yet. Just schedule */
492-
qd->t_insert = get_jiffies_64();
493-
queue_work(ib_wq, &qd->work);
494-
bail:
495483
return;
496484
}
497485

0 commit comments

Comments
 (0)