aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederic Barrat <fbarrat@linux.vnet.ibm.com>2018-05-23 19:25:45 +0200
committerStewart Smith <stewart@linux.ibm.com>2018-06-01 02:07:26 -0500
commit60cb2cd0595d2bc0253fa5ada3f07d4fb69823e3 (patch)
tree663df3f4b3705d61bf710c1979bb31edc303afc7
parentf27a6322ec1c7533a4628e1ae563c53553d6ad0a (diff)
downloadskiboot-60cb2cd0595d2bc0253fa5ada3f07d4fb69823e3.zip
skiboot-60cb2cd0595d2bc0253fa5ada3f07d4fb69823e3.tar.gz
skiboot-60cb2cd0595d2bc0253fa5ada3f07d4fb69823e3.tar.bz2
npu2-opencapi: Fix link state to report link down
The PHB callback 'get_link_state' is always reporting the link width, irrespective of the link status and even when the link is down. It is causing too much work (and failures) when the PHB is probed during pci init. The fix is to look at the link status first and report the link as down when appropriate. Signed-off-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com> Acked-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
-rw-r--r--hw/npu2-opencapi.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/hw/npu2-opencapi.c b/hw/npu2-opencapi.c
index 77122ed..3465d70 100644
--- a/hw/npu2-opencapi.c
+++ b/hw/npu2-opencapi.c
@@ -80,6 +80,7 @@
#define OCAPI_LINK_TRAINING_RETRIES 5
#define OCAPI_LINK_TRAINING_TIMEOUT 3000 /* ms */
+#define OCAPI_LINK_STATE_TRAINED 0x7
enum npu2_link_training_state {
NPU2_TRAIN_DEFAULT, /* fully train the link */
@@ -1032,10 +1033,17 @@ static int64_t npu2_opencapi_get_link_state(struct pci_slot *slot, uint8_t *val)
{
struct npu2_dev *dev = phb_to_npu2_dev_ocapi(slot->phb);
uint64_t reg;
- int64_t link_width, rc = OPAL_SUCCESS;
+ int64_t link_width, training_status, rc = OPAL_SUCCESS;
reg = get_odl_status(dev->npu->chip_id, dev->index);
link_width = GETFIELD(OB_ODL_STATUS_TRAINED_MODE, reg);
+ training_status = GETFIELD(OB_ODL_STATUS_TRAINING_STATE_MACHINE, reg);
+
+ if (training_status != OCAPI_LINK_STATE_TRAINED) {
+ *val = OPAL_SHPC_LINK_DOWN;
+ return OPAL_SUCCESS;
+ }
+
switch (link_width) {
case 0b0001:
*val = OPAL_SHPC_LINK_UP_x4;
@@ -1086,7 +1094,8 @@ static int64_t npu2_opencapi_poll_link(struct pci_slot *slot)
/* fall-through */
case OCAPI_SLOT_LINK_WAIT:
reg = get_odl_status(chip_id, dev->index);
- if (GETFIELD(OB_ODL_STATUS_TRAINING_STATE_MACHINE, reg) == 0x7) {
+ if (GETFIELD(OB_ODL_STATUS_TRAINING_STATE_MACHINE, reg) ==
+ OCAPI_LINK_STATE_TRAINED) {
OCAPIINF(dev, "link trained in %lld ms\n",
OCAPI_LINK_TRAINING_TIMEOUT - slot->retries);
pci_slot_set_state(slot, OCAPI_SLOT_LINK_TRAINED);