// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright Red Hat

#include <linux/cleanup.h>
#include <linux/mutex.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/xarray.h>
#include "ice_adapter.h"
#include "ice.h"

static DEFINE_XARRAY(ice_adapters);
static DEFINE_MUTEX(ice_adapters_mutex);

static unsigned long ice_adapter_index(u64 dsn)
{
#if BITS_PER_LONG == 64
	return dsn;
#else
	return (u32)dsn ^ (u32)(dsn >> 32);
#endif
}

static struct ice_adapter *ice_adapter_new(u64 dsn)
{
	struct ice_adapter *adapter;

	adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
	if (!adapter)
		return NULL;

	adapter->device_serial_number = dsn;
	spin_lock_init(&adapter->ptp_gltsyn_time_lock);
	spin_lock_init(&adapter->txq_ctx_lock);
	refcount_set(&adapter->refcount, 1);

	mutex_init(&adapter->ports.lock);
	INIT_LIST_HEAD(&adapter->ports.ports);

	return adapter;
}

static void ice_adapter_free(struct ice_adapter *adapter)
{
	WARN_ON(!list_empty(&adapter->ports.ports));
	mutex_destroy(&adapter->ports.lock);

	kfree(adapter);
}

/**
 * ice_adapter_get - Get a shared ice_adapter structure.
 * @pdev: Pointer to the pci_dev whose driver is getting the ice_adapter.
 *
 * Gets a pointer to a shared ice_adapter structure. Physical functions (PFs)
 * of the same multi-function PCI device share one ice_adapter structure.
 * The ice_adapter is reference-counted. The PF driver must use ice_adapter_put
 * to release its reference.
 *
 * Context: Process, may sleep.
 * Return:  Pointer to ice_adapter on success.
 *          ERR_PTR() on error. -ENOMEM is the only possible error.
 */
struct ice_adapter *ice_adapter_get(struct pci_dev *pdev)
{
	u64 dsn = pci_get_dsn(pdev);
	struct ice_adapter *adapter;
	unsigned long index;
	int err;

	index = ice_adapter_index(dsn);
	scoped_guard(mutex, &ice_adapters_mutex) {
		err = xa_insert(&ice_adapters, index, NULL, GFP_KERNEL);
		if (err == -EBUSY) {
			adapter = xa_load(&ice_adapters, index);
			refcount_inc(&adapter->refcount);
			WARN_ON_ONCE(adapter->device_serial_number != dsn);
			return adapter;
		}
		if (err)
			return ERR_PTR(err);

		adapter = ice_adapter_new(dsn);
		if (!adapter)
			return ERR_PTR(-ENOMEM);
		xa_store(&ice_adapters, index, adapter, GFP_KERNEL);
	}
	return adapter;
}

/**
 * ice_adapter_put - Release a reference to the shared ice_adapter structure.
 * @pdev: Pointer to the pci_dev whose driver is releasing the ice_adapter.
 *
 * Releases the reference to ice_adapter previously obtained with
 * ice_adapter_get.
 *
 * Context: Process, may sleep.
 */
void ice_adapter_put(struct pci_dev *pdev)
{
	u64 dsn = pci_get_dsn(pdev);
	struct ice_adapter *adapter;
	unsigned long index;

	index = ice_adapter_index(dsn);
	scoped_guard(mutex, &ice_adapters_mutex) {
		adapter = xa_load(&ice_adapters, index);
		if (WARN_ON(!adapter))
			return;
		if (!refcount_dec_and_test(&adapter->refcount))
			return;

		WARN_ON(xa_erase(&ice_adapters, index) != adapter);
	}
	ice_adapter_free(adapter);
}
