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 <mitko@qlogic.com>
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@qlogic.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
This commit is contained in:
Mitko Haralanov 2011-07-14 13:40:24 +00:00 committed by Roland Dreier
parent 4356d0b64b
commit e800bd032c

View File

@ -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; int lsb, ret = 0, setforce = 0;
u16 lcmd, licmd; u16 lcmd, licmd;
unsigned long flags; unsigned long flags;
u32 tmp = 0;
switch (which) { switch (which) {
case QIB_IB_CFG_LIDLMC: 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; maskr = IBA7220_IBC_WIDTH_MASK;
lsb = IBA7220_IBC_WIDTH_SHIFT; lsb = IBA7220_IBC_WIDTH_SHIFT;
setforce = 1; setforce = 1;
spin_lock_irqsave(&ppd->lflags_lock, flags);
ppd->lflags |= QIBL_IB_FORCE_NOTIFY;
spin_unlock_irqrestore(&ppd->lflags_lock, flags);
break; break;
case QIB_IB_CFG_SPD_ENB: /* set allowed Link speeds */ 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; goto bail;
} }
qib_set_ib_7220_lstate(ppd, lcmd, licmd); 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; goto bail;
case QIB_IB_CFG_HRTBT: /* set Heartbeat off/enable/auto */ case QIB_IB_CFG_HRTBT: /* set Heartbeat off/enable/auto */