[Skiboot] [RFC 09/12] npu2-opencapi: tweak to Oliver's RFC series

Frederic Barrat fbarrat at linux.ibm.com
Wed Jun 19 22:45:07 AEST 2019


This will obviously need to be adjusted once the foundation code is
upstream.

Signed-off-by: Frederic Barrat <fbarrat at linux.ibm.com>
---
 core/pci-opal.c | 73 +++++++++++++++++++++++++++++++------------------
 1 file changed, 46 insertions(+), 27 deletions(-)

diff --git a/core/pci-opal.c b/core/pci-opal.c
index 75b746fa..9b63f708 100644
--- a/core/pci-opal.c
+++ b/core/pci-opal.c
@@ -656,13 +656,41 @@ static int64_t opal_pci_get_power_state(uint64_t id, uint64_t data)
 }
 opal_call(OPAL_PCI_GET_POWER_STATE, opal_pci_get_power_state, 2);
 
+static void rescan_slot(struct pci_slot *slot)
+{
+	struct phb *phb = slot->phb;
+	struct pci_device *pd = slot->pd;
+
+	prerror("Rescanning slot...\n");
+	slot->ops.prepare_link_change(slot, true);
+	if (phb->phb_type != phb_type_npu_v2_opencapi) {
+		pci_scan_bus(phb, pd->secondary_bus,
+			pd->subordinate_bus, &pd->children, pd, true);
+		pci_add_device_nodes(phb, &pd->children, pd->dn,
+				&phb->lstate, 0);
+	} else {
+		pci_scan_bus(phb, 0, 0xff, &phb->devices, NULL, true);
+		pci_add_device_nodes(phb, &phb->devices,
+				phb->dt_node, &phb->lstate, 0);
+		phb->ops->phb_final_fixup(phb);
+	}
+}
+
+static u32 get_slot_phandle(struct pci_slot *slot)
+{
+	struct phb *phb = slot->phb;
+	struct pci_device *pd = slot->pd;
+
+	if (pd)
+		return pd->dn->phandle;
+	else
+		return phb->dt_node->phandle;
+}
+
 static void link_up_timer(struct timer *t __unused, void *data,
 			    uint64_t now __unused)
 {
 	struct pci_slot *slot = data;
-	struct phb *phb = slot->phb;
-	struct pci_device *pd = slot->pd;
-	struct dt_node *dn = pd->dn;
 	uint8_t link;
 	int64_t rc = OPAL_BUSY;
 
@@ -676,8 +704,9 @@ static void link_up_timer(struct timer *t __unused, void *data,
 	rc = slot->ops.run_sm(slot);
 	if (rc < 0) // error, abort
 		goto done;
-	if (rc > 0 && slot->retries-- <= 0) // timeout, abort
-		goto done;
+	// the slot->retries counter will interfere with our link training attempts. It says as much in comment above (?)
+	/* if (rc > 0 && slot->retries-- <= 0) // timeout, abort */
+	/* 	goto done; */
 	if (rc > 0) { // kick the can down the road
 		schedule_timer(t, msecs_to_tb(10));
 		return;
@@ -685,26 +714,19 @@ static void link_up_timer(struct timer *t __unused, void *data,
 
 	if (slot->ops.get_link_state(slot, &link) != OPAL_SUCCESS)
 		link = 0;
-	if (link) {
-		prerror("scanning slot...\n");
-		slot->ops.prepare_link_change(slot, true);
-
-		pci_scan_bus(phb, pd->secondary_bus,
-			     pd->subordinate_bus,
-			     &pd->children, pd, true);
-		pci_add_device_nodes(phb, &pd->children, dn,
-				     &phb->lstate, 0);
-	}
+	if (link)
+		rescan_slot(slot);
 
 done:
 	/*
 	 * We need to send a completion message back to the kernel, otherwise
 	 * it'll sit there forever.
 	 */
-	pci_slot_set_state(slot, PCI_SLOT_STATE_NORMAL);
 
+	// better left out to the state machine?
+	// pci_slot_set_state(slot, PCI_SLOT_STATE_NORMAL);
 	opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL,
-		       slot->async_token, dn->phandle,
+		       slot->async_token, get_slot_phandle(slot),
 		       slot->power_state, rc <= 0 ? rc : OPAL_BUSY);
 	prerror("sent competition state = %lld from %s\n", rc, __func__);
 }
@@ -714,7 +736,6 @@ static void set_power_timer(struct timer *t, void *data, uint64_t now)
 	struct pci_slot *slot = data;
 	//struct phb *phb = slot->phb;
 	struct pci_device *pd = slot->pd;
-	struct dt_node *dn = pd->dn;
 	//uint8_t link;
 	struct phb *phb = slot->phb;
 	int64_t rc = OPAL_BUSY;
@@ -758,8 +779,7 @@ static void set_power_timer(struct timer *t, void *data, uint64_t now)
 	 * In the power up case run through the FRESET handler. This is hella
 	 * dumb and we need to do something less stupid in future.
 	 */
-	pci_slot_set_state(slot, PCI_SLOT_STATE_LINK_START_POLL);
-
+	pci_slot_set_state(slot, PCI_SLOT_STATE_FRESET);
 	// switch to using the link poll timer
 	init_timer(&slot->timer, link_up_timer, slot);
 	link_up_timer(t, data, now);
@@ -773,7 +793,7 @@ done:
 	pci_slot_set_state(slot, PCI_SLOT_STATE_NORMAL);
 
 	opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL,
-		       slot->async_token, dn->phandle,
+		       slot->async_token, get_slot_phandle(slot),
 		       slot->power_state, rc <= 0 ? rc : OPAL_BUSY);
 	prerror("sent competition state = %lld from %s\n", rc, __func__);
 }
@@ -860,13 +880,12 @@ static int64_t opal_pci_set_power_state(uint64_t async_token,
 
 	/* Otherwise scan the slot so we have the new device in the DT */
 	if (*state == OPAL_PCI_SLOT_POWER_ON) {
-		slot->ops.prepare_link_change(slot, true);
-		pci_scan_bus(phb, pd->secondary_bus,
-			pd->subordinate_bus, &pd->children, pd, true);
-		pci_add_device_nodes(phb, &pd->children, pd->dn,
-			&phb->lstate, 0);
+		rescan_slot(slot);
 	} else {
-		pci_remove_bus(phb, &pd->children);
+		if (phb->phb_type != phb_type_npu_v2_opencapi)
+			pci_remove_bus(phb, &pd->children);
+		else
+			pci_remove_bus(phb, &phb->devices);
 	}
 
 	phb_unlock(phb);
-- 
2.21.0



More information about the Skiboot mailing list