diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/infiniband/hw/qib/qib_iba7322.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index d3b493824cdc..dbbb0e85afe4 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c | |||
@@ -623,6 +623,7 @@ struct qib_chippport_specific { | |||
623 | u8 ibmalfusesnap; | 623 | u8 ibmalfusesnap; |
624 | struct qib_qsfp_data qsfp_data; | 624 | struct qib_qsfp_data qsfp_data; |
625 | char epmsgbuf[192]; /* for port error interrupt msg buffer */ | 625 | char epmsgbuf[192]; /* for port error interrupt msg buffer */ |
626 | u8 bounced; | ||
626 | }; | 627 | }; |
627 | 628 | ||
628 | static struct { | 629 | static struct { |
@@ -1742,6 +1743,8 @@ static void handle_serdes_issues(struct qib_pportdata *ppd, u64 ibcst) | |||
1742 | } | 1743 | } |
1743 | } | 1744 | } |
1744 | 1745 | ||
1746 | static int qib_7322_set_ib_cfg(struct qib_pportdata *, int, u32); | ||
1747 | |||
1745 | /* | 1748 | /* |
1746 | * This is per-pport error handling. | 1749 | * This is per-pport error handling. |
1747 | * will likely get it's own MSIx interrupt (one for each port, | 1750 | * will likely get it's own MSIx interrupt (one for each port, |
@@ -1878,7 +1881,23 @@ static noinline void handle_7322_p_errors(struct qib_pportdata *ppd) | |||
1878 | IB_PHYSPORTSTATE_DISABLED) | 1881 | IB_PHYSPORTSTATE_DISABLED) |
1879 | qib_set_ib_7322_lstate(ppd, 0, | 1882 | qib_set_ib_7322_lstate(ppd, 0, |
1880 | QLOGIC_IB_IBCC_LINKINITCMD_DISABLE); | 1883 | QLOGIC_IB_IBCC_LINKINITCMD_DISABLE); |
1881 | else | 1884 | else { |
1885 | u32 lstate; | ||
1886 | /* | ||
1887 | * We need the current logical link state before | ||
1888 | * lflags are set in handle_e_ibstatuschanged. | ||
1889 | */ | ||
1890 | lstate = qib_7322_iblink_state(ibcs); | ||
1891 | |||
1892 | if (IS_QMH(dd) && !ppd->cpspec->bounced && | ||
1893 | ltstate == IB_PHYSPORTSTATE_LINKUP && | ||
1894 | (lstate >= IB_PORT_INIT && | ||
1895 | lstate <= IB_PORT_ACTIVE)) { | ||
1896 | ppd->cpspec->bounced = 1; | ||
1897 | qib_7322_set_ib_cfg(ppd, QIB_IB_CFG_LSTATE, | ||
1898 | IB_LINKCMD_DOWN | IB_LINKINITCMD_POLL); | ||
1899 | } | ||
1900 | |||
1882 | /* | 1901 | /* |
1883 | * Since going into a recovery state causes the link | 1902 | * Since going into a recovery state causes the link |
1884 | * state to go down and since recovery is transitory, | 1903 | * state to go down and since recovery is transitory, |
@@ -1892,6 +1911,7 @@ static noinline void handle_7322_p_errors(struct qib_pportdata *ppd) | |||
1892 | ltstate != IB_PHYSPORTSTATE_RECOVERY_WAITRMT && | 1911 | ltstate != IB_PHYSPORTSTATE_RECOVERY_WAITRMT && |
1893 | ltstate != IB_PHYSPORTSTATE_RECOVERY_IDLE) | 1912 | ltstate != IB_PHYSPORTSTATE_RECOVERY_IDLE) |
1894 | qib_handle_e_ibstatuschanged(ppd, ibcs); | 1913 | qib_handle_e_ibstatuschanged(ppd, ibcs); |
1914 | } | ||
1895 | } | 1915 | } |
1896 | if (*msg && iserr) | 1916 | if (*msg && iserr) |
1897 | qib_dev_porterr(dd, ppd->port, "%s error\n", msg); | 1917 | qib_dev_porterr(dd, ppd->port, "%s error\n", msg); |
@@ -7282,8 +7302,8 @@ static void ibsd_wr_allchans(struct qib_pportdata *ppd, int addr, unsigned data, | |||
7282 | static void serdes_7322_los_enable(struct qib_pportdata *ppd, int enable) | 7302 | static void serdes_7322_los_enable(struct qib_pportdata *ppd, int enable) |
7283 | { | 7303 | { |
7284 | u64 data = qib_read_kreg_port(ppd, krp_serdesctrl); | 7304 | u64 data = qib_read_kreg_port(ppd, krp_serdesctrl); |
7285 | printk(KERN_INFO QIB_DRV_NAME " Turning LOS %s for port %d\n", | 7305 | printk(KERN_INFO QIB_DRV_NAME " IB%u:%u Turning LOS %s\n", |
7286 | (enable ? "on" : "off"), ppd->port); | 7306 | ppd->dd->unit, ppd->port, (enable ? "on" : "off")); |
7287 | if (enable) | 7307 | if (enable) |
7288 | data |= SYM_MASK(IBSerdesCtrl_0, RXLOSEN); | 7308 | data |= SYM_MASK(IBSerdesCtrl_0, RXLOSEN); |
7289 | else | 7309 | else |