aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMitko Haralanov <mitko@qlogic.com>2011-10-19 18:46:40 -0400
committerRoland Dreier <roland@purestorage.com>2011-10-21 18:08:20 -0400
commitdde05cbdf8b1c404344c370fe6e18ff160d6da6a (patch)
tree6c480da3c7e8e41ad6b24a51eaa27caeb6ea22b2 /drivers
parent44d75d3d92304a1df8131f48b38de08df9011fa2 (diff)
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 <mitko@qlogic.com> Signed-off-by: Mike Marciniszyn <mike.marciniszyn@qlogic.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/hw/qib/qib_iba7322.c120
-rw-r--r--drivers/infiniband/hw/qib/qib_init.c4
-rw-r--r--drivers/infiniband/hw/qib/qib_qsfp.c25
-rw-r--r--drivers/infiniband/hw/qib/qib_qsfp.h2
4 files changed, 94 insertions, 57 deletions
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c
index 708f4fea6afa..86575fbcaef7 100644
--- a/drivers/infiniband/hw/qib/qib_iba7322.c
+++ b/drivers/infiniband/hw/qib/qib_iba7322.c
@@ -2381,17 +2381,17 @@ static int qib_7322_bringup_serdes(struct qib_pportdata *ppd)
2381 ppd->cpspec->ibcctrl_a |= SYM_MASK(IBCCtrlA_0, IBLinkEn); 2381 ppd->cpspec->ibcctrl_a |= SYM_MASK(IBCCtrlA_0, IBLinkEn);
2382 set_vls(ppd); 2382 set_vls(ppd);
2383 2383
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
2384 /* be paranoid against later code motion, etc. */ 2389 /* be paranoid against later code motion, etc. */
2385 spin_lock_irqsave(&dd->cspec->rcvmod_lock, flags); 2390 spin_lock_irqsave(&dd->cspec->rcvmod_lock, flags);
2386 ppd->p_rcvctrl |= SYM_MASK(RcvCtrl_0, RcvIBPortEnable); 2391 ppd->p_rcvctrl |= SYM_MASK(RcvCtrl_0, RcvIBPortEnable);
2387 qib_write_kreg_port(ppd, krp_rcvctrl, ppd->p_rcvctrl); 2392 qib_write_kreg_port(ppd, krp_rcvctrl, ppd->p_rcvctrl);
2388 spin_unlock_irqrestore(&dd->cspec->rcvmod_lock, flags); 2393 spin_unlock_irqrestore(&dd->cspec->rcvmod_lock, flags);
2389 2394
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
2395 /* Also enable IBSTATUSCHG interrupt. */ 2395 /* Also enable IBSTATUSCHG interrupt. */
2396 val = qib_read_kreg_port(ppd, krp_errmask); 2396 val = qib_read_kreg_port(ppd, krp_errmask);
2397 qib_write_kreg_port(ppd, krp_errmask, 2397 qib_write_kreg_port(ppd, krp_errmask,
@@ -5229,6 +5229,8 @@ static int qib_7322_ib_updown(struct qib_pportdata *ppd, int ibup, u64 ibcs)
5229 QIBL_IB_AUTONEG_INPROG))) 5229 QIBL_IB_AUTONEG_INPROG)))
5230 set_7322_ibspeed_fast(ppd, ppd->link_speed_enabled); 5230 set_7322_ibspeed_fast(ppd, ppd->link_speed_enabled);
5231 if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) { 5231 if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) {
5232 struct qib_qsfp_data *qd =
5233 &ppd->cpspec->qsfp_data;
5232 /* unlock the Tx settings, speed may change */ 5234 /* unlock the Tx settings, speed may change */
5233 qib_write_kreg_port(ppd, krp_tx_deemph_override, 5235 qib_write_kreg_port(ppd, krp_tx_deemph_override,
5234 SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, 5236 SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0,
@@ -5236,6 +5238,12 @@ static int qib_7322_ib_updown(struct qib_pportdata *ppd, int ibup, u64 ibcs)
5236 qib_cancel_sends(ppd); 5238 qib_cancel_sends(ppd);
5237 /* on link down, ensure sane pcs state */ 5239 /* on link down, ensure sane pcs state */
5238 qib_7322_mini_pcs_reset(ppd); 5240 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 }
5239 spin_lock_irqsave(&ppd->sdma_lock, flags); 5247 spin_lock_irqsave(&ppd->sdma_lock, flags);
5240 if (__qib_sdma_running(ppd)) 5248 if (__qib_sdma_running(ppd))
5241 __qib_sdma_process_event(ppd, 5249 __qib_sdma_process_event(ppd,
@@ -5591,38 +5599,62 @@ static void qsfp_7322_event(struct work_struct *work)
5591 5599
5592 qd = container_of(work, struct qib_qsfp_data, work); 5600 qd = container_of(work, struct qib_qsfp_data, work);
5593 ppd = qd->ppd; 5601 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);
5595 5604
5596 /* 5605 /* Delay for 20 msecs to allow ModPrs resistor to setup */
5597 * Some QSFP's not only do not respond until the full power-up 5606 mdelay(QSFP_MODPRS_LAG_MSEC);
5598 * time, but may behave badly if we try. So hold off responding 5607
5599 * to insertion. 5608 if (!qib_qsfp_mod_present(ppd))
5600 */ 5609 /* Set the physical link to disabled */
5601 while (1) { 5610 qib_set_ib_7322_lstate(ppd, 0,
5602 u64 now = get_jiffies_64(); 5611 QLOGIC_IB_IBCC_LINKINITCMD_DISABLE);
5603 if (time_after64(now, pwrup)) 5612 else {
5604 break; 5613 /*
5605 msleep(20); 5614 * Some QSFP's not only do not respond until the full power-up
5606 } 5615 * time, but may behave badly if we try. So hold off responding
5607 ret = qib_refresh_qsfp_cache(ppd, &qd->cache); 5616 * to insertion.
5608 /* 5617 */
5609 * Need to change LE2 back to defaults if we couldn't 5618 while (1) {
5610 * read the cable type (to handle cable swaps), so do this 5619 u64 now = get_jiffies_64();
5611 * even on failure to read cable information. We don't 5620 if (time_after64(now, pwrup))
5612 * get here for QME, so IS_QME check not needed here. 5621 break;
5613 */ 5622 msleep(20);
5614 if (!ret && !ppd->dd->cspec->r1) { 5623 }
5615 if (QSFP_IS_ACTIVE_FAR(qd->cache.tech)) 5624
5616 le2 = LE2_QME; 5625 ret = qib_refresh_qsfp_cache(ppd, &qd->cache);
5617 else if (qd->cache.atten[1] >= qib_long_atten && 5626
5618 QSFP_IS_CU(qd->cache.tech)) 5627 /*
5619 le2 = LE2_5m; 5628 * Need to change LE2 back to defaults if we couldn't
5620 else 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
5621 le2 = LE2_DEFAULT; 5642 le2 = LE2_DEFAULT;
5622 } else 5643 ibsd_wr_allchans(ppd, 13, (le2 << 7), BMASK(9, 7));
5623 le2 = LE2_DEFAULT; 5644 /*
5624 ibsd_wr_allchans(ppd, 13, (le2 << 7), BMASK(9, 7)); 5645 * We always change parameteters, since we can choose
5625 init_txdds_table(ppd, 0); 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 }
5626} 5658}
5627 5659
5628/* 5660/*
@@ -5726,7 +5758,8 @@ static void set_no_qsfp_atten(struct qib_devdata *dd, int change)
5726 /* now change the IBC and serdes, overriding generic */ 5758 /* now change the IBC and serdes, overriding generic */
5727 init_txdds_table(ppd, 1); 5759 init_txdds_table(ppd, 1);
5728 /* Re-enable the physical state machine on mezz boards 5760 /* 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 */
5730 if (IS_QMH(dd) || IS_QME(dd)) 5763 if (IS_QMH(dd) || IS_QME(dd))
5731 qib_set_ib_7322_lstate(ppd, 0, 5764 qib_set_ib_7322_lstate(ppd, 0,
5732 QLOGIC_IB_IBCC_LINKINITCMD_SLEEP); 5765 QLOGIC_IB_IBCC_LINKINITCMD_SLEEP);
@@ -7148,7 +7181,8 @@ static void find_best_ent(struct qib_pportdata *ppd,
7148 } 7181 }
7149 } 7182 }
7150 7183
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. */
7152 if (!override && QSFP_IS_ACTIVE(qd->tech)) { 7186 if (!override && QSFP_IS_ACTIVE(qd->tech)) {
7153 *sdr_dds = txdds_sdr + ppd->dd->board_atten; 7187 *sdr_dds = txdds_sdr + ppd->dd->board_atten;
7154 *ddr_dds = txdds_ddr + ppd->dd->board_atten; 7188 *ddr_dds = txdds_ddr + ppd->dd->board_atten;
@@ -7465,12 +7499,6 @@ static int serdes_7322_init_new(struct qib_pportdata *ppd)
7465 u32 le_val, rxcaldone; 7499 u32 le_val, rxcaldone;
7466 int chan, chan_done = (1 << SERDES_CHANS) - 1; 7500 int chan, chan_done = (1 << SERDES_CHANS) - 1;
7467 7501
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
7474 /* Clear cmode-override, may be set from older driver */ 7502 /* Clear cmode-override, may be set from older driver */
7475 ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), 5, 10, 0 << 14, 1 << 14); 7503 ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), 5, 10, 0 << 14, 1 << 14);
7476 7504
@@ -7656,6 +7684,12 @@ static int serdes_7322_init_new(struct qib_pportdata *ppd)
7656 /* VGA output common mode */ 7684 /* VGA output common mode */
7657 ibsd_wr_allchans(ppd, 12, (3 << 2), BMASK(3, 2)); 7685 ibsd_wr_allchans(ppd, 12, (3 << 2), BMASK(3, 2));
7658 7686
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
7659 return 0; 7693 return 0;
7660} 7694}
7661 7695
diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c
index 21ffa7c0915f..b093a0b53b2f 100644
--- a/drivers/infiniband/hw/qib/qib_init.c
+++ b/drivers/infiniband/hw/qib/qib_init.c
@@ -585,10 +585,6 @@ int qib_init(struct qib_devdata *dd, int reinit)
585 continue; 585 continue;
586 } 586 }
587 587
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);
592 portok++; 588 portok++;
593 } 589 }
594 590
diff --git a/drivers/infiniband/hw/qib/qib_qsfp.c b/drivers/infiniband/hw/qib/qib_qsfp.c
index 3374a52232c1..e06c4ed383f1 100644
--- a/drivers/infiniband/hw/qib/qib_qsfp.c
+++ b/drivers/infiniband/hw/qib/qib_qsfp.c
@@ -273,18 +273,12 @@ int qib_refresh_qsfp_cache(struct qib_pportdata *ppd, struct qib_qsfp_cache *cp)
273 int ret; 273 int ret;
274 int idx; 274 int idx;
275 u16 cks; 275 u16 cks;
276 u32 mask;
277 u8 peek[4]; 276 u8 peek[4];
278 277
279 /* ensure sane contents on invalid reads, for cable swaps */ 278 /* ensure sane contents on invalid reads, for cable swaps */
280 memset(cp, 0, sizeof(*cp)); 279 memset(cp, 0, sizeof(*cp));
281 280
282 mask = QSFP_GPIO_MOD_PRS_N; 281 if (!qib_qsfp_mod_present(ppd)) {
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) {
288 ret = -ENODEV; 282 ret = -ENODEV;
289 goto bail; 283 goto bail;
290 } 284 }
@@ -444,6 +438,19 @@ const char * const qib_qsfp_devtech[16] = {
444 438
445static const char *pwr_codes = "1.5W2.0W2.5W3.5W"; 439static const char *pwr_codes = "1.5W2.0W2.5W3.5W";
446 440
441int 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
447/* 454/*
448 * Initialize structures that control access to QSFP. Called once per port 455 * Initialize structures that control access to QSFP. Called once per port
449 * on cards that support QSFP. 456 * on cards that support QSFP.
@@ -452,7 +459,6 @@ void qib_qsfp_init(struct qib_qsfp_data *qd,
452 void (*fevent)(struct work_struct *)) 459 void (*fevent)(struct work_struct *))
453{ 460{
454 u32 mask, highs; 461 u32 mask, highs;
455 int pins;
456 462
457 struct qib_devdata *dd = qd->ppd->dd; 463 struct qib_devdata *dd = qd->ppd->dd;
458 464
@@ -480,8 +486,7 @@ void qib_qsfp_init(struct qib_qsfp_data *qd,
480 mask <<= QSFP_GPIO_PORT2_SHIFT; 486 mask <<= QSFP_GPIO_PORT2_SHIFT;
481 487
482 /* Do not try to wait here. Better to let event handle it */ 488 /* Do not try to wait here. Better to let event handle it */
483 pins = dd->f_gpio_mod(dd, 0, 0, 0); 489 if (!qib_qsfp_mod_present(qd->ppd))
484 if (pins & mask)
485 goto bail; 490 goto bail;
486 /* We see a module, but it may be unwise to look yet. Just schedule */ 491 /* We see a module, but it may be unwise to look yet. Just schedule */
487 qd->t_insert = get_jiffies_64(); 492 qd->t_insert = get_jiffies_64();
diff --git a/drivers/infiniband/hw/qib/qib_qsfp.h b/drivers/infiniband/hw/qib/qib_qsfp.h
index c109bbdc90ac..786a92a25c25 100644
--- a/drivers/infiniband/hw/qib/qib_qsfp.h
+++ b/drivers/infiniband/hw/qib/qib_qsfp.h
@@ -34,6 +34,7 @@
34 34
35#define QSFP_DEV 0xA0 35#define QSFP_DEV 0xA0
36#define QSFP_PWR_LAG_MSEC 2000 36#define QSFP_PWR_LAG_MSEC 2000
37#define QSFP_MODPRS_LAG_MSEC 20
37 38
38/* 39/*
39 * Below are masks for various QSFP signals, for Port 1. 40 * Below are masks for various QSFP signals, for Port 1.
@@ -181,6 +182,7 @@ struct qib_qsfp_data {
181 182
182extern int qib_refresh_qsfp_cache(struct qib_pportdata *ppd, 183extern int qib_refresh_qsfp_cache(struct qib_pportdata *ppd,
183 struct qib_qsfp_cache *cp); 184 struct qib_qsfp_cache *cp);
185extern int qib_qsfp_mod_present(struct qib_pportdata *ppd);
184extern void qib_qsfp_init(struct qib_qsfp_data *qd, 186extern void qib_qsfp_init(struct qib_qsfp_data *qd,
185 void (*fevent)(struct work_struct *)); 187 void (*fevent)(struct work_struct *));
186extern void qib_qsfp_deinit(struct qib_qsfp_data *qd); 188extern void qib_qsfp_deinit(struct qib_qsfp_data *qd);