aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/hfi1/chip.c85
-rw-r--r--drivers/infiniband/hw/hfi1/chip.h1
2 files changed, 65 insertions, 21 deletions
diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c
index b2ed4b9cda6e..1c810d65721a 100644
--- a/drivers/infiniband/hw/hfi1/chip.c
+++ b/drivers/infiniband/hw/hfi1/chip.c
@@ -1066,6 +1066,8 @@ static int read_idle_sma(struct hfi1_devdata *dd, u64 *data);
1066static int thermal_init(struct hfi1_devdata *dd); 1066static int thermal_init(struct hfi1_devdata *dd);
1067 1067
1068static void update_statusp(struct hfi1_pportdata *ppd, u32 state); 1068static void update_statusp(struct hfi1_pportdata *ppd, u32 state);
1069static int wait_phys_link_offline_substates(struct hfi1_pportdata *ppd,
1070 int msecs);
1069static int wait_logical_linkstate(struct hfi1_pportdata *ppd, u32 state, 1071static int wait_logical_linkstate(struct hfi1_pportdata *ppd, u32 state,
1070 int msecs); 1072 int msecs);
1071static void log_state_transition(struct hfi1_pportdata *ppd, u32 state); 1073static void log_state_transition(struct hfi1_pportdata *ppd, u32 state);
@@ -10305,6 +10307,7 @@ static int goto_offline(struct hfi1_pportdata *ppd, u8 rem_reason)
10305{ 10307{
10306 struct hfi1_devdata *dd = ppd->dd; 10308 struct hfi1_devdata *dd = ppd->dd;
10307 u32 previous_state; 10309 u32 previous_state;
10310 int offline_state_ret;
10308 int ret; 10311 int ret;
10309 10312
10310 update_lcb_cache(dd); 10313 update_lcb_cache(dd);
@@ -10326,28 +10329,11 @@ static int goto_offline(struct hfi1_pportdata *ppd, u8 rem_reason)
10326 ppd->offline_disabled_reason = 10329 ppd->offline_disabled_reason =
10327 HFI1_ODR_MASK(OPA_LINKDOWN_REASON_TRANSIENT); 10330 HFI1_ODR_MASK(OPA_LINKDOWN_REASON_TRANSIENT);
10328 10331
10329 /* 10332 offline_state_ret = wait_phys_link_offline_substates(ppd, 10000);
10330 * Wait for offline transition. It can take a while for 10333 if (offline_state_ret < 0)
10331 * the link to go down. 10334 return offline_state_ret;
10332 */
10333 ret = wait_physical_linkstate(ppd, PLS_OFFLINE, 10000);
10334 if (ret < 0)
10335 return ret;
10336
10337 /*
10338 * Now in charge of LCB - must be after the physical state is
10339 * offline.quiet and before host_link_state is changed.
10340 */
10341 set_host_lcb_access(dd);
10342 write_csr(dd, DC_LCB_ERR_EN, ~0ull); /* watch LCB errors */
10343
10344 /* make sure the logical state is also down */
10345 ret = wait_logical_linkstate(ppd, IB_PORT_DOWN, 1000);
10346 if (ret)
10347 force_logical_link_state_down(ppd);
10348
10349 ppd->host_link_state = HLS_LINK_COOLDOWN; /* LCB access allowed */
10350 10335
10336 /* Disabling AOC transmitters */
10351 if (ppd->port_type == PORT_TYPE_QSFP && 10337 if (ppd->port_type == PORT_TYPE_QSFP &&
10352 ppd->qsfp_info.limiting_active && 10338 ppd->qsfp_info.limiting_active &&
10353 qsfp_mod_present(ppd)) { 10339 qsfp_mod_present(ppd)) {
@@ -10365,6 +10351,30 @@ static int goto_offline(struct hfi1_pportdata *ppd, u8 rem_reason)
10365 } 10351 }
10366 10352
10367 /* 10353 /*
10354 * Wait for the offline.Quiet transition if it hasn't happened yet. It
10355 * can take a while for the link to go down.
10356 */
10357 if (offline_state_ret != PLS_OFFLINE_QUIET) {
10358 ret = wait_physical_linkstate(ppd, PLS_OFFLINE, 30000);
10359 if (ret < 0)
10360 return ret;
10361 }
10362
10363 /*
10364 * Now in charge of LCB - must be after the physical state is
10365 * offline.quiet and before host_link_state is changed.
10366 */
10367 set_host_lcb_access(dd);
10368 write_csr(dd, DC_LCB_ERR_EN, ~0ull); /* watch LCB errors */
10369
10370 /* make sure the logical state is also down */
10371 ret = wait_logical_linkstate(ppd, IB_PORT_DOWN, 1000);
10372 if (ret)
10373 force_logical_link_state_down(ppd);
10374
10375 ppd->host_link_state = HLS_LINK_COOLDOWN; /* LCB access allowed */
10376
10377 /*
10368 * The LNI has a mandatory wait time after the physical state 10378 * The LNI has a mandatory wait time after the physical state
10369 * moves to Offline.Quiet. The wait time may be different 10379 * moves to Offline.Quiet. The wait time may be different
10370 * depending on how the link went down. The 8051 firmware 10380 * depending on how the link went down. The 8051 firmware
@@ -12804,6 +12814,39 @@ static int wait_physical_linkstate(struct hfi1_pportdata *ppd, u32 state,
12804 return 0; 12814 return 0;
12805} 12815}
12806 12816
12817/*
12818 * wait_phys_link_offline_quiet_substates - wait for any offline substate
12819 * @ppd: port device
12820 * @msecs: the number of milliseconds to wait
12821 *
12822 * Wait up to msecs milliseconds for any offline physical link
12823 * state change to occur.
12824 * Returns 0 if at least one state is reached, otherwise -ETIMEDOUT.
12825 */
12826static int wait_phys_link_offline_substates(struct hfi1_pportdata *ppd,
12827 int msecs)
12828{
12829 u32 read_state;
12830 unsigned long timeout;
12831
12832 timeout = jiffies + msecs_to_jiffies(msecs);
12833 while (1) {
12834 read_state = read_physical_state(ppd->dd);
12835 if ((read_state & 0xF0) == PLS_OFFLINE)
12836 break;
12837 if (time_after(jiffies, timeout)) {
12838 dd_dev_err(ppd->dd,
12839 "timeout waiting for phy link offline.quiet substates. Read state 0x%x, %dms\n",
12840 read_state, msecs);
12841 return -ETIMEDOUT;
12842 }
12843 usleep_range(1950, 2050); /* sleep 2ms-ish */
12844 }
12845
12846 log_state_transition(ppd, read_state);
12847 return read_state;
12848}
12849
12807#define CLEAR_STATIC_RATE_CONTROL_SMASK(r) \ 12850#define CLEAR_STATIC_RATE_CONTROL_SMASK(r) \
12808(r &= ~SEND_CTXT_CHECK_ENABLE_DISALLOW_PBC_STATIC_RATE_CONTROL_SMASK) 12851(r &= ~SEND_CTXT_CHECK_ENABLE_DISALLOW_PBC_STATIC_RATE_CONTROL_SMASK)
12809 12852
diff --git a/drivers/infiniband/hw/hfi1/chip.h b/drivers/infiniband/hw/hfi1/chip.h
index b8345a60a0fb..461f937fe110 100644
--- a/drivers/infiniband/hw/hfi1/chip.h
+++ b/drivers/infiniband/hw/hfi1/chip.h
@@ -204,6 +204,7 @@
204#define PLS_OFFLINE_READY_TO_QUIET_LT 0x92 204#define PLS_OFFLINE_READY_TO_QUIET_LT 0x92
205#define PLS_OFFLINE_REPORT_FAILURE 0x93 205#define PLS_OFFLINE_REPORT_FAILURE 0x93
206#define PLS_OFFLINE_READY_TO_QUIET_BCC 0x94 206#define PLS_OFFLINE_READY_TO_QUIET_BCC 0x94
207#define PLS_OFFLINE_QUIET_DURATION 0x95
207#define PLS_POLLING 0x20 208#define PLS_POLLING 0x20
208#define PLS_POLLING_QUIET 0x20 209#define PLS_POLLING_QUIET 0x20
209#define PLS_POLLING_ACTIVE 0x21 210#define PLS_POLLING_ACTIVE 0x21