// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2013 - 2018 Intel Corporation. */

#include <linux/list.h>
#include <linux/errno.h>

#include "i40evf.h"
#include "i40e_prototype.h"
#include "i40evf_client.h"

static
const char i40evf_client_interface_version_str[] = I40EVF_CLIENT_VERSION_STR;
static struct i40e_client *vf_registered_client;
static LIST_HEAD(i40evf_devices);
static DEFINE_MUTEX(i40evf_device_mutex);

static u32 i40evf_client_virtchnl_send(struct i40e_info *ldev,
				       struct i40e_client *client,
				       u8 *msg, u16 len);

static int i40evf_client_setup_qvlist(struct i40e_info *ldev,
				      struct i40e_client *client,
				      struct i40e_qvlist_info *qvlist_info);

static struct i40e_ops i40evf_lan_ops = {
	.virtchnl_send = i40evf_client_virtchnl_send,
	.setup_qvlist = i40evf_client_setup_qvlist,
};

/**
 * i40evf_client_get_params - retrieve relevant client parameters
 * @vsi: VSI with parameters
 * @params: client param struct
 **/
static
void i40evf_client_get_params(struct i40e_vsi *vsi, struct i40e_params *params)
{
	int i;

	memset(params, 0, sizeof(struct i40e_params));
	params->mtu = vsi->netdev->mtu;
	params->link_up = vsi->back->link_up;

	for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
		params->qos.prio_qos[i].tc = 0;
		params->qos.prio_qos[i].qs_handle = vsi->qs_handle;
	}
}

/**
 * i40evf_notify_client_message - call the client message receive callback
 * @vsi: the VSI associated with this client
 * @msg: message buffer
 * @len: length of message
 *
 * If there is a client to this VSI, call the client
 **/
void i40evf_notify_client_message(struct i40e_vsi *vsi, u8 *msg, u16 len)
{
	struct i40e_client_instance *cinst;

	if (!vsi)
		return;

	cinst = vsi->back->cinst;
	if (!cinst || !cinst->client || !cinst->client->ops ||
	    !cinst->client->ops->virtchnl_receive) {
		dev_dbg(&vsi->back->pdev->dev,
			"Cannot locate client instance virtchnl_receive function\n");
		return;
	}
	cinst->client->ops->virtchnl_receive(&cinst->lan_info,  cinst->client,
					     msg, len);
}

/**
 * i40evf_notify_client_l2_params - call the client notify callback
 * @vsi: the VSI with l2 param changes
 *
 * If there is a client to this VSI, call the client
 **/
void i40evf_notify_client_l2_params(struct i40e_vsi *vsi)
{
	struct i40e_client_instance *cinst;
	struct i40e_params params;

	if (!vsi)
		return;

	cinst = vsi->back->cinst;

	if (!cinst || !cinst->client || !cinst->client->ops ||
	    !cinst->client->ops->l2_param_change) {
		dev_dbg(&vsi->back->pdev->dev,
			"Cannot locate client instance l2_param_change function\n");
		return;
	}
	i40evf_client_get_params(vsi, &params);
	cinst->lan_info.params = params;
	cinst->client->ops->l2_param_change(&cinst->lan_info, cinst->client,
					    &params);
}

/**
 * i40evf_notify_client_open - call the client open callback
 * @vsi: the VSI with netdev opened
 *
 * If there is a client to this netdev, call the client with open
 **/
void i40evf_notify_client_open(struct i40e_vsi *vsi)
{
	struct i40evf_adapter *adapter = vsi->back;
	struct i40e_client_instance *cinst = adapter->cinst;
	int ret;

	if (!cinst || !cinst->client || !cinst->client->ops ||
	    !cinst->client->ops->open) {
		dev_dbg(&vsi->back->pdev->dev,
			"Cannot locate client instance open function\n");
		return;
	}
	if (!(test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cinst->state))) {
		ret = cinst->client->ops->open(&cinst->lan_info, cinst->client);
		if (!ret)
			set_bit(__I40E_CLIENT_INSTANCE_OPENED, &cinst->state);
	}
}

/**
 * i40evf_client_release_qvlist - send a message to the PF to release iwarp qv map
 * @ldev: pointer to L2 context.
 *
 * Return 0 on success or < 0 on error
 **/
static int i40evf_client_release_qvlist(struct i40e_info *ldev)
{
	struct i40evf_adapter *adapter = ldev->vf;
	i40e_status err;

	if (adapter->aq_required)
		return -EAGAIN;

	err = i40e_aq_send_msg_to_pf(&adapter->hw,
			VIRTCHNL_OP_RELEASE_IWARP_IRQ_MAP,
			I40E_SUCCESS, NULL, 0, NULL);

	if (err)
		dev_err(&adapter->pdev->dev,
			"Unable to send iWarp vector release message to PF, error %d, aq status %d\n",
			err, adapter->hw.aq.asq_last_status);

	return err;
}

/**
 * i40evf_notify_client_close - call the client close callback
 * @vsi: the VSI with netdev closed
 * @reset: true when close called due to reset pending
 *
 * If there is a client to this netdev, call the client with close
 **/
void i40evf_notify_client_close(struct i40e_vsi *vsi, bool reset)
{
	struct i40evf_adapter *adapter = vsi->back;
	struct i40e_client_instance *cinst = adapter->cinst;

	if (!cinst || !cinst->client || !cinst->client->ops ||
	    !cinst->client->ops->close) {
		dev_dbg(&vsi->back->pdev->dev,
			"Cannot locate client instance close function\n");
		return;
	}
	cinst->client->ops->close(&cinst->lan_info, cinst->client, reset);
	i40evf_client_release_qvlist(&cinst->lan_info);
	clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cinst->state);
}

/**
 * i40evf_client_add_instance - add a client instance to the instance list
 * @adapter: pointer to the board struct
 *
 * Returns cinst ptr on success, NULL on failure
 **/
static struct i40e_client_instance *
i40evf_client_add_instance(struct i40evf_adapter *adapter)
{
	struct i40e_client_instance *cinst = NULL;
	struct i40e_vsi *vsi = &adapter->vsi;
	struct netdev_hw_addr *mac = NULL;
	struct i40e_params params;

	if (!vf_registered_client)
		goto out;

	if (adapter->cinst) {
		cinst = adapter->cinst;
		goto out;
	}

	cinst = kzalloc(sizeof(*cinst), GFP_KERNEL);
	if (!cinst)
		goto out;

	cinst->lan_info.vf = (void *)adapter;
	cinst->lan_info.netdev = vsi->netdev;
	cinst->lan_info.pcidev = adapter->pdev;
	cinst->lan_info.fid = 0;
	cinst->lan_info.ftype = I40E_CLIENT_FTYPE_VF;
	cinst->lan_info.hw_addr = adapter->hw.hw_addr;
	cinst->lan_info.ops = &i40evf_lan_ops;
	cinst->lan_info.version.major = I40EVF_CLIENT_VERSION_MAJOR;
	cinst->lan_info.version.minor = I40EVF_CLIENT_VERSION_MINOR;
	cinst->lan_info.version.build = I40EVF_CLIENT_VERSION_BUILD;
	i40evf_client_get_params(vsi, &params);
	cinst->lan_info.params = params;
	set_bit(__I40E_CLIENT_INSTANCE_NONE, &cinst->state);

	cinst->lan_info.msix_count = adapter->num_iwarp_msix;
	cinst->lan_info.msix_entries =
			&adapter->msix_entries[adapter->iwarp_base_vector];

	mac = list_first_entry(&cinst->lan_info.netdev->dev_addrs.list,
			       struct netdev_hw_addr, list);
	if (mac)
		ether_addr_copy(cinst->lan_info.lanmac, mac->addr);
	else
		dev_err(&adapter->pdev->dev, "MAC address list is empty!\n");

	cinst->client = vf_registered_client;
	adapter->cinst = cinst;
out:
	return cinst;
}

/**
 * i40evf_client_del_instance - removes a client instance from the list
 * @adapter: pointer to the board struct
 *
 **/
static
void i40evf_client_del_instance(struct i40evf_adapter *adapter)
{
	kfree(adapter->cinst);
	adapter->cinst = NULL;
}

/**
 * i40evf_client_subtask - client maintenance work
 * @adapter: board private structure
 **/
void i40evf_client_subtask(struct i40evf_adapter *adapter)
{
	struct i40e_client *client = vf_registered_client;
	struct i40e_client_instance *cinst;
	int ret = 0;

	if (adapter->state < __I40EVF_DOWN)
		return;

	/* first check client is registered */
	if (!client)
		return;

	/* Add the client instance to the instance list */
	cinst = i40evf_client_add_instance(adapter);
	if (!cinst)
		return;

	dev_info(&adapter->pdev->dev, "Added instance of Client %s\n",
		 client->name);

	if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cinst->state)) {
		/* Send an Open request to the client */

		if (client->ops && client->ops->open)
			ret = client->ops->open(&cinst->lan_info, client);
		if (!ret)
			set_bit(__I40E_CLIENT_INSTANCE_OPENED,
				&cinst->state);
		else
			/* remove client instance */
			i40evf_client_del_instance(adapter);
	}
}

/**
 * i40evf_lan_add_device - add a lan device struct to the list of lan devices
 * @adapter: pointer to the board struct
 *
 * Returns 0 on success or none 0 on error
 **/
int i40evf_lan_add_device(struct i40evf_adapter *adapter)
{
	struct i40e_device *ldev;
	int ret = 0;

	mutex_lock(&i40evf_device_mutex);
	list_for_each_entry(ldev, &i40evf_devices, list) {
		if (ldev->vf == adapter) {
			ret = -EEXIST;
			goto out;
		}
	}
	ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
	if (!ldev) {
		ret = -ENOMEM;
		goto out;
	}
	ldev->vf = adapter;
	INIT_LIST_HEAD(&ldev->list);
	list_add(&ldev->list, &i40evf_devices);
	dev_info(&adapter->pdev->dev, "Added LAN device bus=0x%02x dev=0x%02x func=0x%02x\n",
		 adapter->hw.bus.bus_id, adapter->hw.bus.device,
		 adapter->hw.bus.func);

	/* Since in some cases register may have happened before a device gets
	 * added, we can schedule a subtask to go initiate the clients.
	 */
	adapter->flags |= I40EVF_FLAG_SERVICE_CLIENT_REQUESTED;

out:
	mutex_unlock(&i40evf_device_mutex);
	return ret;
}

/**
 * i40evf_lan_del_device - removes a lan device from the device list
 * @adapter: pointer to the board struct
 *
 * Returns 0 on success or non-0 on error
 **/
int i40evf_lan_del_device(struct i40evf_adapter *adapter)
{
	struct i40e_device *ldev, *tmp;
	int ret = -ENODEV;

	mutex_lock(&i40evf_device_mutex);
	list_for_each_entry_safe(ldev, tmp, &i40evf_devices, list) {
		if (ldev->vf == adapter) {
			dev_info(&adapter->pdev->dev,
				 "Deleted LAN device bus=0x%02x dev=0x%02x func=0x%02x\n",
				 adapter->hw.bus.bus_id, adapter->hw.bus.device,
				 adapter->hw.bus.func);
			list_del(&ldev->list);
			kfree(ldev);
			ret = 0;
			break;
		}
	}

	mutex_unlock(&i40evf_device_mutex);
	return ret;
}

/**
 * i40evf_client_release - release client specific resources
 * @client: pointer to the registered client
 *
 **/
static void i40evf_client_release(struct i40e_client *client)
{
	struct i40e_client_instance *cinst;
	struct i40e_device *ldev;
	struct i40evf_adapter *adapter;

	mutex_lock(&i40evf_device_mutex);
	list_for_each_entry(ldev, &i40evf_devices, list) {
		adapter = ldev->vf;
		cinst = adapter->cinst;
		if (!cinst)
			continue;
		if (test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cinst->state)) {
			if (client->ops && client->ops->close)
				client->ops->close(&cinst->lan_info, client,
						   false);
			i40evf_client_release_qvlist(&cinst->lan_info);
			clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cinst->state);

			dev_warn(&adapter->pdev->dev,
				 "Client %s instance closed\n", client->name);
		}
		/* delete the client instance */
		i40evf_client_del_instance(adapter);
		dev_info(&adapter->pdev->dev, "Deleted client instance of Client %s\n",
			 client->name);
	}
	mutex_unlock(&i40evf_device_mutex);
}

/**
 * i40evf_client_prepare - prepare client specific resources
 * @client: pointer to the registered client
 *
 **/
static void i40evf_client_prepare(struct i40e_client *client)
{
	struct i40e_device *ldev;
	struct i40evf_adapter *adapter;

	mutex_lock(&i40evf_device_mutex);
	list_for_each_entry(ldev, &i40evf_devices, list) {
		adapter = ldev->vf;
		/* Signal the watchdog to service the client */
		adapter->flags |= I40EVF_FLAG_SERVICE_CLIENT_REQUESTED;
	}
	mutex_unlock(&i40evf_device_mutex);
}

/**
 * i40evf_client_virtchnl_send - send a message to the PF instance
 * @ldev: pointer to L2 context.
 * @client: Client pointer.
 * @msg: pointer to message buffer
 * @len: message length
 *
 * Return 0 on success or < 0 on error
 **/
static u32 i40evf_client_virtchnl_send(struct i40e_info *ldev,
				       struct i40e_client *client,
				       u8 *msg, u16 len)
{
	struct i40evf_adapter *adapter = ldev->vf;
	i40e_status err;

	if (adapter->aq_required)
		return -EAGAIN;

	err = i40e_aq_send_msg_to_pf(&adapter->hw, VIRTCHNL_OP_IWARP,
				     I40E_SUCCESS, msg, len, NULL);
	if (err)
		dev_err(&adapter->pdev->dev, "Unable to send iWarp message to PF, error %d, aq status %d\n",
			err, adapter->hw.aq.asq_last_status);

	return err;
}

/**
 * i40evf_client_setup_qvlist - send a message to the PF to setup iwarp qv map
 * @ldev: pointer to L2 context.
 * @client: Client pointer.
 * @qvlist_info: queue and vector list
 *
 * Return 0 on success or < 0 on error
 **/
static int i40evf_client_setup_qvlist(struct i40e_info *ldev,
				      struct i40e_client *client,
				      struct i40e_qvlist_info *qvlist_info)
{
	struct virtchnl_iwarp_qvlist_info *v_qvlist_info;
	struct i40evf_adapter *adapter = ldev->vf;
	struct i40e_qv_info *qv_info;
	i40e_status err;
	u32 v_idx, i;
	u32 msg_size;

	if (adapter->aq_required)
		return -EAGAIN;

	/* A quick check on whether the vectors belong to the client */
	for (i = 0; i < qvlist_info->num_vectors; i++) {
		qv_info = &qvlist_info->qv_info[i];
		if (!qv_info)
			continue;
		v_idx = qv_info->v_idx;
		if ((v_idx >=
		    (adapter->iwarp_base_vector + adapter->num_iwarp_msix)) ||
		    (v_idx < adapter->iwarp_base_vector))
			return -EINVAL;
	}

	v_qvlist_info = (struct virtchnl_iwarp_qvlist_info *)qvlist_info;
	msg_size = sizeof(struct virtchnl_iwarp_qvlist_info) +
			(sizeof(struct virtchnl_iwarp_qv_info) *
			(v_qvlist_info->num_vectors - 1));

	adapter->client_pending |= BIT(VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP);
	err = i40e_aq_send_msg_to_pf(&adapter->hw,
			VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP,
			I40E_SUCCESS, (u8 *)v_qvlist_info, msg_size, NULL);

	if (err) {
		dev_err(&adapter->pdev->dev,
			"Unable to send iWarp vector config message to PF, error %d, aq status %d\n",
			err, adapter->hw.aq.asq_last_status);
		goto out;
	}

	err = -EBUSY;
	for (i = 0; i < 5; i++) {
		msleep(100);
		if (!(adapter->client_pending &
		      BIT(VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP))) {
			err = 0;
			break;
		}
	}
out:
	return err;
}

/**
 * i40evf_register_client - Register a i40e client driver with the L2 driver
 * @client: pointer to the i40e_client struct
 *
 * Returns 0 on success or non-0 on error
 **/
int i40evf_register_client(struct i40e_client *client)
{
	int ret = 0;

	if (!client) {
		ret = -EIO;
		goto out;
	}

	if (strlen(client->name) == 0) {
		pr_info("i40evf: Failed to register client with no name\n");
		ret = -EIO;
		goto out;
	}

	if (vf_registered_client) {
		pr_info("i40evf: Client %s has already been registered!\n",
			client->name);
		ret = -EEXIST;
		goto out;
	}

	if ((client->version.major != I40EVF_CLIENT_VERSION_MAJOR) ||
	    (client->version.minor != I40EVF_CLIENT_VERSION_MINOR)) {
		pr_info("i40evf: Failed to register client %s due to mismatched client interface version\n",
			client->name);
		pr_info("Client is using version: %02d.%02d.%02d while LAN driver supports %s\n",
			client->version.major, client->version.minor,
			client->version.build,
			i40evf_client_interface_version_str);
		ret = -EIO;
		goto out;
	}

	vf_registered_client = client;

	i40evf_client_prepare(client);

	pr_info("i40evf: Registered client %s with return code %d\n",
		client->name, ret);
out:
	return ret;
}
EXPORT_SYMBOL(i40evf_register_client);

/**
 * i40evf_unregister_client - Unregister a i40e client driver with the L2 driver
 * @client: pointer to the i40e_client struct
 *
 * Returns 0 on success or non-0 on error
 **/
int i40evf_unregister_client(struct i40e_client *client)
{
	int ret = 0;

	/* When a unregister request comes through we would have to send
	 * a close for each of the client instances that were opened.
	 * client_release function is called to handle this.
	 */
	i40evf_client_release(client);

	if (vf_registered_client != client) {
		pr_info("i40evf: Client %s has not been registered\n",
			client->name);
		ret = -ENODEV;
		goto out;
	}
	vf_registered_client = NULL;
	pr_info("i40evf: Unregistered client %s\n", client->name);
out:
	return ret;
}
EXPORT_SYMBOL(i40evf_unregister_client);
