// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/* Copyright (c) 2018 Mellanox Technologies */

#include <linux/mlx5/vport.h>
#include "lib/devcom.h"

static LIST_HEAD(devcom_list);

#define devcom_for_each_component(priv, comp, iter) \
	for (iter = 0; \
	     comp = &(priv)->components[iter], iter < MLX5_DEVCOM_NUM_COMPONENTS; \
	     iter++)

struct mlx5_devcom_component {
	struct {
		void *data;
	} device[MLX5_DEVCOM_PORTS_SUPPORTED];

	mlx5_devcom_event_handler_t handler;
	struct rw_semaphore sem;
	bool paired;
};

struct mlx5_devcom_list {
	struct list_head list;

	struct mlx5_devcom_component components[MLX5_DEVCOM_NUM_COMPONENTS];
	struct mlx5_core_dev *devs[MLX5_DEVCOM_PORTS_SUPPORTED];
};

struct mlx5_devcom {
	struct mlx5_devcom_list *priv;
	int idx;
};

static struct mlx5_devcom_list *mlx5_devcom_list_alloc(void)
{
	struct mlx5_devcom_component *comp;
	struct mlx5_devcom_list *priv;
	int i;

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

	devcom_for_each_component(priv, comp, i)
		init_rwsem(&comp->sem);

	return priv;
}

static struct mlx5_devcom *mlx5_devcom_alloc(struct mlx5_devcom_list *priv,
					     u8 idx)
{
	struct mlx5_devcom *devcom;

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

	devcom->priv = priv;
	devcom->idx = idx;
	return devcom;
}

/* Must be called with intf_mutex held */
struct mlx5_devcom *mlx5_devcom_register_device(struct mlx5_core_dev *dev)
{
	struct mlx5_devcom_list *priv = NULL, *iter;
	struct mlx5_devcom *devcom = NULL;
	bool new_priv = false;
	u64 sguid0, sguid1;
	int idx, i;

	if (!mlx5_core_is_pf(dev))
		return NULL;
	if (MLX5_CAP_GEN(dev, num_lag_ports) != MLX5_DEVCOM_PORTS_SUPPORTED)
		return NULL;

	sguid0 = mlx5_query_nic_system_image_guid(dev);
	list_for_each_entry(iter, &devcom_list, list) {
		struct mlx5_core_dev *tmp_dev = NULL;

		idx = -1;
		for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++) {
			if (iter->devs[i])
				tmp_dev = iter->devs[i];
			else
				idx = i;
		}

		if (idx == -1)
			continue;

		sguid1 = mlx5_query_nic_system_image_guid(tmp_dev);
		if (sguid0 != sguid1)
			continue;

		priv = iter;
		break;
	}

	if (!priv) {
		priv = mlx5_devcom_list_alloc();
		if (!priv)
			return ERR_PTR(-ENOMEM);

		idx = 0;
		new_priv = true;
	}

	priv->devs[idx] = dev;
	devcom = mlx5_devcom_alloc(priv, idx);
	if (!devcom) {
		kfree(priv);
		return ERR_PTR(-ENOMEM);
	}

	if (new_priv)
		list_add(&priv->list, &devcom_list);

	return devcom;
}

/* Must be called with intf_mutex held */
void mlx5_devcom_unregister_device(struct mlx5_devcom *devcom)
{
	struct mlx5_devcom_list *priv;
	int i;

	if (IS_ERR_OR_NULL(devcom))
		return;

	priv = devcom->priv;
	priv->devs[devcom->idx] = NULL;

	kfree(devcom);

	for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++)
		if (priv->devs[i])
			break;

	if (i != MLX5_DEVCOM_PORTS_SUPPORTED)
		return;

	list_del(&priv->list);
	kfree(priv);
}

void mlx5_devcom_register_component(struct mlx5_devcom *devcom,
				    enum mlx5_devcom_components id,
				    mlx5_devcom_event_handler_t handler,
				    void *data)
{
	struct mlx5_devcom_component *comp;

	if (IS_ERR_OR_NULL(devcom))
		return;

	WARN_ON(!data);

	comp = &devcom->priv->components[id];
	down_write(&comp->sem);
	comp->handler = handler;
	comp->device[devcom->idx].data = data;
	up_write(&comp->sem);
}

void mlx5_devcom_unregister_component(struct mlx5_devcom *devcom,
				      enum mlx5_devcom_components id)
{
	struct mlx5_devcom_component *comp;

	if (IS_ERR_OR_NULL(devcom))
		return;

	comp = &devcom->priv->components[id];
	down_write(&comp->sem);
	comp->device[devcom->idx].data = NULL;
	up_write(&comp->sem);
}

int mlx5_devcom_send_event(struct mlx5_devcom *devcom,
			   enum mlx5_devcom_components id,
			   int event,
			   void *event_data)
{
	struct mlx5_devcom_component *comp;
	int err = -ENODEV, i;

	if (IS_ERR_OR_NULL(devcom))
		return err;

	comp = &devcom->priv->components[id];
	down_write(&comp->sem);
	for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++)
		if (i != devcom->idx && comp->device[i].data) {
			err = comp->handler(event, comp->device[i].data,
					    event_data);
			break;
		}

	up_write(&comp->sem);
	return err;
}

void mlx5_devcom_set_paired(struct mlx5_devcom *devcom,
			    enum mlx5_devcom_components id,
			    bool paired)
{
	struct mlx5_devcom_component *comp;

	comp = &devcom->priv->components[id];
	WARN_ON(!rwsem_is_locked(&comp->sem));

	comp->paired = paired;
}

bool mlx5_devcom_is_paired(struct mlx5_devcom *devcom,
			   enum mlx5_devcom_components id)
{
	if (IS_ERR_OR_NULL(devcom))
		return false;

	return devcom->priv->components[id].paired;
}

void *mlx5_devcom_get_peer_data(struct mlx5_devcom *devcom,
				enum mlx5_devcom_components id)
{
	struct mlx5_devcom_component *comp;
	int i;

	if (IS_ERR_OR_NULL(devcom))
		return NULL;

	comp = &devcom->priv->components[id];
	down_read(&comp->sem);
	if (!comp->paired) {
		up_read(&comp->sem);
		return NULL;
	}

	for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++)
		if (i != devcom->idx)
			break;

	return comp->device[i].data;
}

void mlx5_devcom_release_peer_data(struct mlx5_devcom *devcom,
				   enum mlx5_devcom_components id)
{
	struct mlx5_devcom_component *comp = &devcom->priv->components[id];

	up_read(&comp->sem);
}
