/* Copyright 2017 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>

#include <skiboot.h>
#include <device.h>

#include <pci.h>
#include <pci-cfg.h>
#include <pci-slot.h>
#include <ccan/list/list.h>

#undef pr_fmt
#define pr_fmt(fmt) "DT-SLOT: " fmt

#define PCIDBG(_p, _bdfn, fmt, a...) \
        prlog(PR_DEBUG, "PHB#%04x:%02x:%02x.%x " fmt,   \
              (_p)->opal_id,                            \
              ((_bdfn) >> 8) & 0xff,                    \
              ((_bdfn) >> 3) & 0x1f, (_bdfn) & 0x7, ## a)

struct dt_node *dt_slots;

static struct dt_node *map_phb_to_slot(struct phb *phb)
{
	uint32_t chip_id = dt_get_chip_id(phb->dt_node);
	uint32_t phb_idx = dt_prop_get_u32_def(phb->dt_node,
					       "ibm,phb-index", 0);
	struct dt_node *slot_node;

	if (!dt_slots)
		dt_slots = dt_find_by_path(dt_root, "/ibm,pcie-slots");

	if (!dt_slots)
		return NULL;

	dt_for_each_child(dt_slots, slot_node) {
		u32 reg[2];

		if (!dt_node_is_compatible(slot_node, "ibm,pcie-root-port"))
			continue;

		reg[0] = dt_prop_get_cell(slot_node, "reg", 0);
		reg[1] = dt_prop_get_cell(slot_node, "reg", 1);

		if (reg[0] == chip_id && reg[1] == phb_idx)
			return slot_node;
	}

	return NULL;
}

static struct dt_node *find_devfn(struct dt_node *bus, uint32_t bdfn)
{
	uint32_t port_dev_id = (bdfn >> 3) & 0x1f;
	struct dt_node *child;

	dt_for_each_child(bus, child)
		if (dt_prop_get_u32_def(child, "reg", ~0u) == port_dev_id)
			return child;

	return NULL;
}

/* Looks for a device device under this slot. */
static struct dt_node *find_dev_under_slot(struct dt_node *slot,
					   struct pci_device *pd)
{
	struct dt_node *child, *wildcard = NULL;

	/* find the device in the parent bus node */
	dt_for_each_child(slot, child) {
		u32 vdid;

		/* "pluggable" and "builtin" without unit addrs are wildcards */
		if (!dt_has_node_property(child, "reg", NULL)) {
			if (wildcard)
				prerror("Duplicate wildcard entry! Already have %s, found %s",
					wildcard->name, child->name);

			wildcard = child;
			continue;
		}

		/* NB: the pci_device vdid is did,vid rather than vid,did */
		vdid = dt_prop_get_cell(child, "reg", 1) << 16 |
			dt_prop_get_cell(child, "reg", 0);

		if (vdid == pd->vdid)
			return child;
	}

	if (!wildcard)
		PCIDBG(pd->phb, pd->bdfn,
			"Unable to find a slot for device %.4x:%.4x\n",
			(pd->vdid & 0xffff0000) >> 16, pd->vdid & 0xffff);

	return wildcard;
}

/*
 * If the `pd` is a bridge this returns a node with a compatible of
 * ibm,pcie-port to indicate it's a "slot node".
 */
static struct dt_node *find_node_for_dev(struct phb *phb,
					 struct pci_device *pd)
{
	struct dt_node *sw_slot, *sw_up;

	assert(pd);

	if (pd->slot && pd->slot->data)
		return pd->slot->data;

	/*
	 * Example DT:
	 *	 /root-complex@8,5/switch-up@10b5,8725/down-port@4
	 */
	switch (pd->dev_type) {
	case PCIE_TYPE_ROOT_PORT: // find the root-complex@<chip>,<phb> node
		return map_phb_to_slot(phb);

	case PCIE_TYPE_SWITCH_DNPORT: // grab the down-port@<devfn>
		/*
		 * Walk up the topology to find the slot that contains
		 * the switch upstream port is connected to. In the example
		 * this would be the root-complex@8,5 node.
		 */
		sw_slot = find_node_for_dev(phb, pd->parent->parent);
		if (!sw_slot)
			return NULL;

		/* find the per-device node for this switch */
		sw_up = find_dev_under_slot(sw_slot, pd->parent);
		if (!sw_up)
			return NULL;

		/* find this down port */
		return find_devfn(sw_up, pd->bdfn);

	default:
		PCIDBG(phb, pd->bdfn,
			"Trying to find a slot for non-pcie bridge type %d\n",
			pd->dev_type);
		assert(0);
	}

	return NULL;
}

struct dt_node *map_pci_dev_to_slot(struct phb *phb, struct pci_device *pd)
{
	struct dt_node *n;
	char *path;

	assert(pd);

	/*
	 * Having a slot only makes sense for root and switch downstream ports.
	 * We don't care about PCI-X.
	 */
	if (pd->dev_type != PCIE_TYPE_SWITCH_DNPORT &&
	    pd->dev_type != PCIE_TYPE_ROOT_PORT)
		return NULL;

	PCIDBG(phb, pd->bdfn, "Finding slot\n");

	n = find_node_for_dev(phb, pd);
	if (!n) {
		PCIDBG(phb, pd->bdfn, "No slot found!\n");
	} else {
		path = dt_get_path(n);
		PCIDBG(phb, pd->bdfn, "Slot found %s\n", path);
		free(path);
	}

	return n;
}

int __print_slot(struct phb *phb, struct pci_device *pd, void *userdata);
int __print_slot(struct phb *phb, struct pci_device *pd,
			void __unused *userdata)
{
	struct dt_node *node;
	struct dt_node *pnode;
	char *c = NULL;
	u32 phandle = 0;

	if (!pd)
		return 0;

	node = map_pci_dev_to_slot(phb, pd);

	/* at this point all node associations should be done */
	if (pd->dn && dt_has_node_property(pd->dn, "ibm,pcie-slot", NULL)) {
		phandle = dt_prop_get_u32(pd->dn, "ibm,pcie-slot");
		pnode = dt_find_by_phandle(dt_root, phandle);

		assert(node == pnode);
	}

	if (node)
		c = dt_get_path(node);

	PCIDBG(phb, pd->bdfn, "Mapped to slot %s (%x)\n",
		c ? c : "<null>", phandle);

	free(c);

	return 0;
}
