mirror of
https://github.com/torvalds/linux.git
synced 2024-11-19 02:21:47 +00:00
staging/rdma/hfi1: HFI reports wrong offline disabled reason when cable removed
Removing QSFP cable should report 'No Local Media' instead of 'Transient' as reported by 'opaportinfo'. Workaround is to change the state to OPA_LINKDOWN_REASON_LOCAL_MEDIA_NOT_INSTALLED in cable handler. With cable still removed, 'opaportinfo bounce' should not cause a state change to Polling, as reported by 'opaportinfo'. Resolution is to prevent physical state change from Offline->Polling. Use a macro to mask lower nibble of OPA_LINKDOWN_REASON* as needed for offline_disabled_reason. Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Reviewed-by: Easwar Hariharan <easwar.hariharan@intel.com> Reviewed-by: Dean Luick <dean.luick@intel.com> Reported-by: Todd Rimmer <todd.rimmer@intel.com> Signed-off-by: Bryan Morgan <bryan.c.morgan@intel.com> Signed-off-by: Jubin John <jubin.john@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
parent
9cd70e1bbf
commit
a9c05e350c
@ -5857,6 +5857,16 @@ static void handle_qsfp_int(struct hfi1_devdata *dd, u32 src_ctx, u64 reg)
|
||||
ASIC_QSFP2_INVERT :
|
||||
ASIC_QSFP1_INVERT,
|
||||
qsfp_int_mgmt);
|
||||
|
||||
if ((ppd->offline_disabled_reason >
|
||||
HFI1_ODR_MASK(
|
||||
OPA_LINKDOWN_REASONLOCAL_MEDIA_NOT_INSTALLED)) ||
|
||||
(ppd->offline_disabled_reason ==
|
||||
HFI1_ODR_MASK(OPA_LINKDOWN_REASON_NONE)))
|
||||
ppd->offline_disabled_reason =
|
||||
HFI1_ODR_MASK(
|
||||
OPA_LINKDOWN_REASONLOCAL_MEDIA_NOT_INSTALLED);
|
||||
|
||||
if (ppd->host_link_state == HLS_DN_POLL) {
|
||||
/*
|
||||
* The link is still in POLL. This means
|
||||
@ -9615,9 +9625,10 @@ static int goto_offline(struct hfi1_pportdata *ppd, u8 rem_reason)
|
||||
ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (ppd->offline_disabled_reason == OPA_LINKDOWN_REASON_NONE)
|
||||
if (ppd->offline_disabled_reason ==
|
||||
HFI1_ODR_MASK(OPA_LINKDOWN_REASON_NONE))
|
||||
ppd->offline_disabled_reason =
|
||||
OPA_LINKDOWN_REASON_TRANSIENT;
|
||||
HFI1_ODR_MASK(OPA_LINKDOWN_REASON_TRANSIENT);
|
||||
}
|
||||
|
||||
if (do_wait) {
|
||||
@ -9972,7 +9983,8 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state)
|
||||
ret = -EINVAL;
|
||||
}
|
||||
}
|
||||
ppd->offline_disabled_reason = OPA_LINKDOWN_REASON_NONE;
|
||||
ppd->offline_disabled_reason =
|
||||
HFI1_ODR_MASK(OPA_LINKDOWN_REASON_NONE);
|
||||
/*
|
||||
* If an error occurred above, go back to offline. The
|
||||
* caller may reschedule another attempt.
|
||||
|
@ -99,6 +99,8 @@ extern unsigned long hfi1_cap_mask;
|
||||
#define HFI1_CAP_IS_USET(cap) (!!HFI1_CAP_UGET(cap))
|
||||
#define HFI1_MISC_GET() ((hfi1_cap_mask >> HFI1_CAP_MISC_SHIFT) & \
|
||||
HFI1_CAP_MISC_MASK)
|
||||
/* Offline Disabled Reason is 4-bits */
|
||||
#define HFI1_ODR_MASK(rsn) ((rsn) & OPA_PI_MASK_OFFLINE_REASON)
|
||||
|
||||
/*
|
||||
* Control context is always 0 and handles the error packets.
|
||||
|
@ -152,7 +152,8 @@ void handle_linkup_change(struct hfi1_devdata *dd, u32 linkup)
|
||||
|
||||
/* physical link went up */
|
||||
ppd->linkup = 1;
|
||||
ppd->offline_disabled_reason = OPA_LINKDOWN_REASON_NONE;
|
||||
ppd->offline_disabled_reason =
|
||||
HFI1_ODR_MASK(OPA_LINKDOWN_REASON_NONE);
|
||||
|
||||
/* link widths are not available until the link is fully up */
|
||||
get_linkup_link_widths(ppd);
|
||||
|
@ -590,12 +590,11 @@ static int __subn_get_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data,
|
||||
pi->port_states.ledenable_offlinereason |=
|
||||
ppd->is_sm_config_started << 5;
|
||||
pi->port_states.ledenable_offlinereason |=
|
||||
ppd->offline_disabled_reason & OPA_PI_MASK_OFFLINE_REASON;
|
||||
ppd->offline_disabled_reason;
|
||||
#else
|
||||
pi->port_states.offline_reason = ppd->neighbor_normal << 4;
|
||||
pi->port_states.offline_reason |= ppd->is_sm_config_started << 5;
|
||||
pi->port_states.offline_reason |= ppd->offline_disabled_reason &
|
||||
OPA_PI_MASK_OFFLINE_REASON;
|
||||
pi->port_states.offline_reason |= ppd->offline_disabled_reason;
|
||||
#endif /* PI_LED_ENABLE_SUP */
|
||||
|
||||
pi->port_states.portphysstate_portstate =
|
||||
@ -929,6 +928,14 @@ static int port_states_transition_allowed(struct hfi1_pportdata *ppd,
|
||||
physical_allowed == HFI_TRANSITION_IGNORED)
|
||||
return HFI_TRANSITION_IGNORED;
|
||||
|
||||
/*
|
||||
* A change request of Physical Port State from
|
||||
* 'Offline' to 'Polling' should be ignored.
|
||||
*/
|
||||
if ((physical_old == OPA_PORTPHYSSTATE_OFFLINE) &&
|
||||
(physical_new == IB_PORTPHYSSTATE_POLLING))
|
||||
return HFI_TRANSITION_IGNORED;
|
||||
|
||||
/*
|
||||
* Either physical_allowed or logical_allowed is
|
||||
* HFI_TRANSITION_ALLOWED.
|
||||
@ -993,11 +1000,11 @@ static int set_port_states(struct hfi1_pportdata *ppd, struct opa_smp *smp,
|
||||
set_link_state(ppd, link_state);
|
||||
if (link_state == HLS_DN_DISABLE &&
|
||||
(ppd->offline_disabled_reason >
|
||||
OPA_LINKDOWN_REASON_SMA_DISABLED ||
|
||||
HFI1_ODR_MASK(OPA_LINKDOWN_REASON_SMA_DISABLED) ||
|
||||
ppd->offline_disabled_reason ==
|
||||
OPA_LINKDOWN_REASON_NONE))
|
||||
HFI1_ODR_MASK(OPA_LINKDOWN_REASON_NONE)))
|
||||
ppd->offline_disabled_reason =
|
||||
OPA_LINKDOWN_REASON_SMA_DISABLED;
|
||||
HFI1_ODR_MASK(OPA_LINKDOWN_REASON_SMA_DISABLED);
|
||||
/*
|
||||
* Don't send a reply if the response would be sent
|
||||
* through the disabled port.
|
||||
@ -1710,12 +1717,11 @@ static int __subn_get_opa_psi(struct opa_smp *smp, u32 am, u8 *data,
|
||||
psi->port_states.ledenable_offlinereason |=
|
||||
ppd->is_sm_config_started << 5;
|
||||
psi->port_states.ledenable_offlinereason |=
|
||||
ppd->offline_disabled_reason & OPA_PI_MASK_OFFLINE_REASON;
|
||||
ppd->offline_disabled_reason;
|
||||
#else
|
||||
psi->port_states.offline_reason = ppd->neighbor_normal << 4;
|
||||
psi->port_states.offline_reason |= ppd->is_sm_config_started << 5;
|
||||
psi->port_states.offline_reason |= ppd->offline_disabled_reason &
|
||||
OPA_PI_MASK_OFFLINE_REASON;
|
||||
psi->port_states.offline_reason |= ppd->offline_disabled_reason;
|
||||
#endif /* PI_LED_ENABLE_SUP */
|
||||
|
||||
psi->port_states.portphysstate_portstate =
|
||||
|
Loading…
Reference in New Issue
Block a user