Skip to content

Commit dde05cb

Browse files
Mitko Haralanovrolandd
authored andcommitted
IB/qib: Hold links until tuning data is available
Hold the link state machine until the tuning data is read from the QSFP EEPROM so correct tuning settings are applied before the state machine attempts to bring the link up. Link is also held on cable unplug in case a different cable is used. Signed-off-by: Mitko Haralanov <[email protected]> Signed-off-by: Mike Marciniszyn <[email protected]> Signed-off-by: Roland Dreier <[email protected]>
1 parent 44d75d3 commit dde05cb

File tree

4 files changed

+94
-57
lines changed

4 files changed

+94
-57
lines changed

drivers/infiniband/hw/qib/qib_iba7322.c

Lines changed: 77 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2381,17 +2381,17 @@ static int qib_7322_bringup_serdes(struct qib_pportdata *ppd)
23812381
ppd->cpspec->ibcctrl_a |= SYM_MASK(IBCCtrlA_0, IBLinkEn);
23822382
set_vls(ppd);
23832383

2384+
/* Hold the link state machine for mezz boards */
2385+
qib_set_ib_7322_lstate(ppd, 0,
2386+
QLOGIC_IB_IBCC_LINKINITCMD_DISABLE);
2387+
2388+
23842389
/* be paranoid against later code motion, etc. */
23852390
spin_lock_irqsave(&dd->cspec->rcvmod_lock, flags);
23862391
ppd->p_rcvctrl |= SYM_MASK(RcvCtrl_0, RcvIBPortEnable);
23872392
qib_write_kreg_port(ppd, krp_rcvctrl, ppd->p_rcvctrl);
23882393
spin_unlock_irqrestore(&dd->cspec->rcvmod_lock, flags);
23892394

2390-
/* Hold the link state machine for mezz boards */
2391-
if (IS_QMH(dd) || IS_QME(dd))
2392-
qib_set_ib_7322_lstate(ppd, 0,
2393-
QLOGIC_IB_IBCC_LINKINITCMD_DISABLE);
2394-
23952395
/* Also enable IBSTATUSCHG interrupt. */
23962396
val = qib_read_kreg_port(ppd, krp_errmask);
23972397
qib_write_kreg_port(ppd, krp_errmask,
@@ -5229,13 +5229,21 @@ static int qib_7322_ib_updown(struct qib_pportdata *ppd, int ibup, u64 ibcs)
52295229
QIBL_IB_AUTONEG_INPROG)))
52305230
set_7322_ibspeed_fast(ppd, ppd->link_speed_enabled);
52315231
if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) {
5232+
struct qib_qsfp_data *qd =
5233+
&ppd->cpspec->qsfp_data;
52325234
/* unlock the Tx settings, speed may change */
52335235
qib_write_kreg_port(ppd, krp_tx_deemph_override,
52345236
SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0,
52355237
reset_tx_deemphasis_override));
52365238
qib_cancel_sends(ppd);
52375239
/* on link down, ensure sane pcs state */
52385240
qib_7322_mini_pcs_reset(ppd);
5241+
/* schedule the qsfp refresh which should turn the link
5242+
off */
5243+
if (ppd->dd->flags & QIB_HAS_QSFP) {
5244+
qd->t_insert = get_jiffies_64();
5245+
schedule_work(&qd->work);
5246+
}
52395247
spin_lock_irqsave(&ppd->sdma_lock, flags);
52405248
if (__qib_sdma_running(ppd))
52415249
__qib_sdma_process_event(ppd,
@@ -5591,38 +5599,62 @@ static void qsfp_7322_event(struct work_struct *work)
55915599

55925600
qd = container_of(work, struct qib_qsfp_data, work);
55935601
ppd = qd->ppd;
5594-
pwrup = qd->t_insert + msecs_to_jiffies(QSFP_PWR_LAG_MSEC);
5602+
pwrup = qd->t_insert +
5603+
msecs_to_jiffies(QSFP_PWR_LAG_MSEC - QSFP_MODPRS_LAG_MSEC);
55955604

5596-
/*
5597-
* Some QSFP's not only do not respond until the full power-up
5598-
* time, but may behave badly if we try. So hold off responding
5599-
* to insertion.
5600-
*/
5601-
while (1) {
5602-
u64 now = get_jiffies_64();
5603-
if (time_after64(now, pwrup))
5604-
break;
5605-
msleep(20);
5606-
}
5607-
ret = qib_refresh_qsfp_cache(ppd, &qd->cache);
5608-
/*
5609-
* Need to change LE2 back to defaults if we couldn't
5610-
* read the cable type (to handle cable swaps), so do this
5611-
* even on failure to read cable information. We don't
5612-
* get here for QME, so IS_QME check not needed here.
5613-
*/
5614-
if (!ret && !ppd->dd->cspec->r1) {
5615-
if (QSFP_IS_ACTIVE_FAR(qd->cache.tech))
5616-
le2 = LE2_QME;
5617-
else if (qd->cache.atten[1] >= qib_long_atten &&
5618-
QSFP_IS_CU(qd->cache.tech))
5619-
le2 = LE2_5m;
5620-
else
5605+
/* Delay for 20 msecs to allow ModPrs resistor to setup */
5606+
mdelay(QSFP_MODPRS_LAG_MSEC);
5607+
5608+
if (!qib_qsfp_mod_present(ppd))
5609+
/* Set the physical link to disabled */
5610+
qib_set_ib_7322_lstate(ppd, 0,
5611+
QLOGIC_IB_IBCC_LINKINITCMD_DISABLE);
5612+
else {
5613+
/*
5614+
* Some QSFP's not only do not respond until the full power-up
5615+
* time, but may behave badly if we try. So hold off responding
5616+
* to insertion.
5617+
*/
5618+
while (1) {
5619+
u64 now = get_jiffies_64();
5620+
if (time_after64(now, pwrup))
5621+
break;
5622+
msleep(20);
5623+
}
5624+
5625+
ret = qib_refresh_qsfp_cache(ppd, &qd->cache);
5626+
5627+
/*
5628+
* Need to change LE2 back to defaults if we couldn't
5629+
* read the cable type (to handle cable swaps), so do this
5630+
* even on failure to read cable information. We don't
5631+
* get here for QME, so IS_QME check not needed here.
5632+
*/
5633+
if (!ret && !ppd->dd->cspec->r1) {
5634+
if (QSFP_IS_ACTIVE_FAR(qd->cache.tech))
5635+
le2 = LE2_QME;
5636+
else if (qd->cache.atten[1] >= qib_long_atten &&
5637+
QSFP_IS_CU(qd->cache.tech))
5638+
le2 = LE2_5m;
5639+
else
5640+
le2 = LE2_DEFAULT;
5641+
} else
56215642
le2 = LE2_DEFAULT;
5622-
} else
5623-
le2 = LE2_DEFAULT;
5624-
ibsd_wr_allchans(ppd, 13, (le2 << 7), BMASK(9, 7));
5625-
init_txdds_table(ppd, 0);
5643+
ibsd_wr_allchans(ppd, 13, (le2 << 7), BMASK(9, 7));
5644+
/*
5645+
* We always change parameteters, since we can choose
5646+
* values for cables without eeproms, and the cable may have
5647+
* changed from a cable with full or partial eeprom content
5648+
* to one with partial or no content.
5649+
*/
5650+
init_txdds_table(ppd, 0);
5651+
/* The physical link is being re-enabled only when the
5652+
previous state was DISABLED. This should only happen when
5653+
the cable has been physically pulled. */
5654+
if (ppd->lflags & QIBL_IB_LINK_DISABLED)
5655+
qib_set_ib_7322_lstate(ppd, 0,
5656+
QLOGIC_IB_IBCC_LINKINITCMD_SLEEP);
5657+
}
56265658
}
56275659

56285660
/*
@@ -5726,7 +5758,8 @@ static void set_no_qsfp_atten(struct qib_devdata *dd, int change)
57265758
/* now change the IBC and serdes, overriding generic */
57275759
init_txdds_table(ppd, 1);
57285760
/* Re-enable the physical state machine on mezz boards
5729-
* now that the correct settings have been set. */
5761+
* now that the correct settings have been set.
5762+
* QSFP boards are handles by the QSFP event handler */
57305763
if (IS_QMH(dd) || IS_QME(dd))
57315764
qib_set_ib_7322_lstate(ppd, 0,
57325765
QLOGIC_IB_IBCC_LINKINITCMD_SLEEP);
@@ -7148,7 +7181,8 @@ static void find_best_ent(struct qib_pportdata *ppd,
71487181
}
71497182
}
71507183

7151-
/* Lookup serdes setting by cable type and attenuation */
7184+
/* Active cables don't have attenuation so we only set SERDES
7185+
* settings to account for the attenuation of the board traces. */
71527186
if (!override && QSFP_IS_ACTIVE(qd->tech)) {
71537187
*sdr_dds = txdds_sdr + ppd->dd->board_atten;
71547188
*ddr_dds = txdds_ddr + ppd->dd->board_atten;
@@ -7465,12 +7499,6 @@ static int serdes_7322_init_new(struct qib_pportdata *ppd)
74657499
u32 le_val, rxcaldone;
74667500
int chan, chan_done = (1 << SERDES_CHANS) - 1;
74677501

7468-
/*
7469-
* Initialize the Tx DDS tables. Also done every QSFP event,
7470-
* for adapters with QSFP
7471-
*/
7472-
init_txdds_table(ppd, 0);
7473-
74747502
/* Clear cmode-override, may be set from older driver */
74757503
ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), 5, 10, 0 << 14, 1 << 14);
74767504

@@ -7656,6 +7684,12 @@ static int serdes_7322_init_new(struct qib_pportdata *ppd)
76567684
/* VGA output common mode */
76577685
ibsd_wr_allchans(ppd, 12, (3 << 2), BMASK(3, 2));
76587686

7687+
/*
7688+
* Initialize the Tx DDS tables. Also done every QSFP event,
7689+
* for adapters with QSFP
7690+
*/
7691+
init_txdds_table(ppd, 0);
7692+
76597693
return 0;
76607694
}
76617695

drivers/infiniband/hw/qib/qib_init.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -585,10 +585,6 @@ int qib_init(struct qib_devdata *dd, int reinit)
585585
continue;
586586
}
587587

588-
/* let link come up, and enable IBC */
589-
spin_lock_irqsave(&ppd->lflags_lock, flags);
590-
ppd->lflags &= ~QIBL_IB_LINK_DISABLED;
591-
spin_unlock_irqrestore(&ppd->lflags_lock, flags);
592588
portok++;
593589
}
594590

drivers/infiniband/hw/qib/qib_qsfp.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -273,18 +273,12 @@ int qib_refresh_qsfp_cache(struct qib_pportdata *ppd, struct qib_qsfp_cache *cp)
273273
int ret;
274274
int idx;
275275
u16 cks;
276-
u32 mask;
277276
u8 peek[4];
278277

279278
/* ensure sane contents on invalid reads, for cable swaps */
280279
memset(cp, 0, sizeof(*cp));
281280

282-
mask = QSFP_GPIO_MOD_PRS_N;
283-
if (ppd->hw_pidx)
284-
mask <<= QSFP_GPIO_PORT2_SHIFT;
285-
286-
ret = ppd->dd->f_gpio_mod(ppd->dd, 0, 0, 0);
287-
if (ret & mask) {
281+
if (!qib_qsfp_mod_present(ppd)) {
288282
ret = -ENODEV;
289283
goto bail;
290284
}
@@ -444,6 +438,19 @@ const char * const qib_qsfp_devtech[16] = {
444438

445439
static const char *pwr_codes = "1.5W2.0W2.5W3.5W";
446440

441+
int qib_qsfp_mod_present(struct qib_pportdata *ppd)
442+
{
443+
u32 mask;
444+
int ret;
445+
446+
mask = QSFP_GPIO_MOD_PRS_N <<
447+
(ppd->hw_pidx * QSFP_GPIO_PORT2_SHIFT);
448+
ret = ppd->dd->f_gpio_mod(ppd->dd, 0, 0, 0);
449+
450+
return !((ret & mask) >>
451+
((ppd->hw_pidx * QSFP_GPIO_PORT2_SHIFT) + 3));
452+
}
453+
447454
/*
448455
* Initialize structures that control access to QSFP. Called once per port
449456
* on cards that support QSFP.
@@ -452,7 +459,6 @@ void qib_qsfp_init(struct qib_qsfp_data *qd,
452459
void (*fevent)(struct work_struct *))
453460
{
454461
u32 mask, highs;
455-
int pins;
456462

457463
struct qib_devdata *dd = qd->ppd->dd;
458464

@@ -480,8 +486,7 @@ void qib_qsfp_init(struct qib_qsfp_data *qd,
480486
mask <<= QSFP_GPIO_PORT2_SHIFT;
481487

482488
/* Do not try to wait here. Better to let event handle it */
483-
pins = dd->f_gpio_mod(dd, 0, 0, 0);
484-
if (pins & mask)
489+
if (!qib_qsfp_mod_present(qd->ppd))
485490
goto bail;
486491
/* We see a module, but it may be unwise to look yet. Just schedule */
487492
qd->t_insert = get_jiffies_64();

drivers/infiniband/hw/qib/qib_qsfp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
#define QSFP_DEV 0xA0
3636
#define QSFP_PWR_LAG_MSEC 2000
37+
#define QSFP_MODPRS_LAG_MSEC 20
3738

3839
/*
3940
* Below are masks for various QSFP signals, for Port 1.
@@ -181,6 +182,7 @@ struct qib_qsfp_data {
181182

182183
extern int qib_refresh_qsfp_cache(struct qib_pportdata *ppd,
183184
struct qib_qsfp_cache *cp);
185+
extern int qib_qsfp_mod_present(struct qib_pportdata *ppd);
184186
extern void qib_qsfp_init(struct qib_qsfp_data *qd,
185187
void (*fevent)(struct work_struct *));
186188
extern void qib_qsfp_deinit(struct qib_qsfp_data *qd);

0 commit comments

Comments
 (0)