From e800bd032c2623b10ef38a4d7d646e3e3c7bb3ad Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Thu, 14 Jul 2011 13:40:24 +0000 Subject: [PATCH] IB/qib: Update active link width Update the active link width on QLE7220 chips when link goes down if chip width does not match shadowed width. Signed-off-by: Mitko Haralanov Signed-off-by: Mike Marciniszyn Signed-off-by: Roland Dreier --- drivers/infiniband/hw/qib/qib_iba7220.c | 26 ++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c index c765a2eb04cf..e1f947446c2a 100644 --- a/drivers/infiniband/hw/qib/qib_iba7220.c +++ b/drivers/infiniband/hw/qib/qib_iba7220.c @@ -2434,6 +2434,7 @@ static int qib_7220_set_ib_cfg(struct qib_pportdata *ppd, int which, u32 val) int lsb, ret = 0, setforce = 0; u16 lcmd, licmd; unsigned long flags; + u32 tmp = 0; switch (which) { case QIB_IB_CFG_LIDLMC: @@ -2467,9 +2468,6 @@ static int qib_7220_set_ib_cfg(struct qib_pportdata *ppd, int which, u32 val) maskr = IBA7220_IBC_WIDTH_MASK; lsb = IBA7220_IBC_WIDTH_SHIFT; setforce = 1; - spin_lock_irqsave(&ppd->lflags_lock, flags); - ppd->lflags |= QIBL_IB_FORCE_NOTIFY; - spin_unlock_irqrestore(&ppd->lflags_lock, flags); break; case QIB_IB_CFG_SPD_ENB: /* set allowed Link speeds */ @@ -2643,6 +2641,28 @@ static int qib_7220_set_ib_cfg(struct qib_pportdata *ppd, int which, u32 val) goto bail; } qib_set_ib_7220_lstate(ppd, lcmd, licmd); + + maskr = IBA7220_IBC_WIDTH_MASK; + lsb = IBA7220_IBC_WIDTH_SHIFT; + tmp = (ppd->cpspec->ibcddrctrl >> lsb) & maskr; + /* If the width active on the chip does not match the + * width in the shadow register, write the new active + * width to the chip. + * We don't have to worry about speed as the speed is taken + * care of by set_7220_ibspeed_fast called by ib_updown. + */ + if (ppd->link_width_enabled-1 != tmp) { + ppd->cpspec->ibcddrctrl &= ~(maskr << lsb); + ppd->cpspec->ibcddrctrl |= + (((u64)(ppd->link_width_enabled-1) & maskr) << + lsb); + qib_write_kreg(dd, kr_ibcddrctrl, + ppd->cpspec->ibcddrctrl); + qib_write_kreg(dd, kr_scratch, 0); + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags |= QIBL_IB_FORCE_NOTIFY; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + } goto bail; case QIB_IB_CFG_HRTBT: /* set Heartbeat off/enable/auto */