// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2020 The Linux Foundation. All rights reserved.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/workqueue.h>

#include "pdr_internal.h"

struct pdr_service {
	char service_name[SERVREG_NAME_LENGTH + 1];
	char service_path[SERVREG_NAME_LENGTH + 1];

	struct sockaddr_qrtr addr;

	unsigned int instance;
	unsigned int service;
	u8 service_data_valid;
	u32 service_data;
	int state;

	bool need_notifier_register;
	bool need_notifier_remove;
	bool need_locator_lookup;
	bool service_connected;

	struct list_head node;
};

struct pdr_handle {
	struct qmi_handle locator_hdl;
	struct qmi_handle notifier_hdl;

	struct sockaddr_qrtr locator_addr;

	struct list_head lookups;
	struct list_head indack_list;

	/* control access to pdr lookup/indack lists */
	struct mutex list_lock;

	/* serialize pd status invocation */
	struct mutex status_lock;

	/* control access to the locator state */
	struct mutex lock;

	bool locator_init_complete;

	struct work_struct locator_work;
	struct work_struct notifier_work;
	struct work_struct indack_work;

	struct workqueue_struct *notifier_wq;
	struct workqueue_struct *indack_wq;

	void (*status)(int state, char *service_path, void *priv);
	void *priv;
};

struct pdr_list_node {
	enum servreg_service_state curr_state;
	u16 transaction_id;
	struct pdr_service *pds;
	struct list_head node;
};

static int pdr_locator_new_server(struct qmi_handle *qmi,
				  struct qmi_service *svc)
{
	struct pdr_handle *pdr = container_of(qmi, struct pdr_handle,
					      locator_hdl);
	struct pdr_service *pds;

	/* Create a local client port for QMI communication */
	pdr->locator_addr.sq_family = AF_QIPCRTR;
	pdr->locator_addr.sq_node = svc->node;
	pdr->locator_addr.sq_port = svc->port;

	mutex_lock(&pdr->lock);
	pdr->locator_init_complete = true;
	mutex_unlock(&pdr->lock);

	/* Service pending lookup requests */
	mutex_lock(&pdr->list_lock);
	list_for_each_entry(pds, &pdr->lookups, node) {
		if (pds->need_locator_lookup)
			schedule_work(&pdr->locator_work);
	}
	mutex_unlock(&pdr->list_lock);

	return 0;
}

static void pdr_locator_del_server(struct qmi_handle *qmi,
				   struct qmi_service *svc)
{
	struct pdr_handle *pdr = container_of(qmi, struct pdr_handle,
					      locator_hdl);

	mutex_lock(&pdr->lock);
	pdr->locator_init_complete = false;
	mutex_unlock(&pdr->lock);

	pdr->locator_addr.sq_node = 0;
	pdr->locator_addr.sq_port = 0;
}

static struct qmi_ops pdr_locator_ops = {
	.new_server = pdr_locator_new_server,
	.del_server = pdr_locator_del_server,
};

static int pdr_register_listener(struct pdr_handle *pdr,
				 struct pdr_service *pds,
				 bool enable)
{
	struct servreg_register_listener_resp resp;
	struct servreg_register_listener_req req;
	struct qmi_txn txn;
	int ret;

	ret = qmi_txn_init(&pdr->notifier_hdl, &txn,
			   servreg_register_listener_resp_ei,
			   &resp);
	if (ret < 0)
		return ret;

	req.enable = enable;
	strcpy(req.service_path, pds->service_path);

	ret = qmi_send_request(&pdr->notifier_hdl, &pds->addr,
			       &txn, SERVREG_REGISTER_LISTENER_REQ,
			       SERVREG_REGISTER_LISTENER_REQ_LEN,
			       servreg_register_listener_req_ei,
			       &req);
	if (ret < 0) {
		qmi_txn_cancel(&txn);
		return ret;
	}

	ret = qmi_txn_wait(&txn, 5 * HZ);
	if (ret < 0) {
		pr_err("PDR: %s register listener txn wait failed: %d\n",
		       pds->service_path, ret);
		return ret;
	}

	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
		pr_err("PDR: %s register listener failed: 0x%x\n",
		       pds->service_path, resp.resp.error);
		return ret;
	}

	pds->state = resp.curr_state;

	return 0;
}

static void pdr_notifier_work(struct work_struct *work)
{
	struct pdr_handle *pdr = container_of(work, struct pdr_handle,
					      notifier_work);
	struct pdr_service *pds;
	int ret;

	mutex_lock(&pdr->list_lock);
	list_for_each_entry(pds, &pdr->lookups, node) {
		if (pds->service_connected) {
			if (!pds->need_notifier_register)
				continue;

			pds->need_notifier_register = false;
			ret = pdr_register_listener(pdr, pds, true);
			if (ret < 0)
				pds->state = SERVREG_SERVICE_STATE_DOWN;
		} else {
			if (!pds->need_notifier_remove)
				continue;

			pds->need_notifier_remove = false;
			pds->state = SERVREG_SERVICE_STATE_DOWN;
		}

		mutex_lock(&pdr->status_lock);
		pdr->status(pds->state, pds->service_path, pdr->priv);
		mutex_unlock(&pdr->status_lock);
	}
	mutex_unlock(&pdr->list_lock);
}

static int pdr_notifier_new_server(struct qmi_handle *qmi,
				   struct qmi_service *svc)
{
	struct pdr_handle *pdr = container_of(qmi, struct pdr_handle,
					      notifier_hdl);
	struct pdr_service *pds;

	mutex_lock(&pdr->list_lock);
	list_for_each_entry(pds, &pdr->lookups, node) {
		if (pds->service == svc->service &&
		    pds->instance == svc->instance) {
			pds->service_connected = true;
			pds->need_notifier_register = true;
			pds->addr.sq_family = AF_QIPCRTR;
			pds->addr.sq_node = svc->node;
			pds->addr.sq_port = svc->port;
			queue_work(pdr->notifier_wq, &pdr->notifier_work);
		}
	}
	mutex_unlock(&pdr->list_lock);

	return 0;
}

static void pdr_notifier_del_server(struct qmi_handle *qmi,
				    struct qmi_service *svc)
{
	struct pdr_handle *pdr = container_of(qmi, struct pdr_handle,
					      notifier_hdl);
	struct pdr_service *pds;

	mutex_lock(&pdr->list_lock);
	list_for_each_entry(pds, &pdr->lookups, node) {
		if (pds->service == svc->service &&
		    pds->instance == svc->instance) {
			pds->service_connected = false;
			pds->need_notifier_remove = true;
			pds->addr.sq_node = 0;
			pds->addr.sq_port = 0;
			queue_work(pdr->notifier_wq, &pdr->notifier_work);
		}
	}
	mutex_unlock(&pdr->list_lock);
}

static struct qmi_ops pdr_notifier_ops = {
	.new_server = pdr_notifier_new_server,
	.del_server = pdr_notifier_del_server,
};

static int pdr_send_indack_msg(struct pdr_handle *pdr, struct pdr_service *pds,
			       u16 tid)
{
	struct servreg_set_ack_resp resp;
	struct servreg_set_ack_req req;
	struct qmi_txn txn;
	int ret;

	ret = qmi_txn_init(&pdr->notifier_hdl, &txn, servreg_set_ack_resp_ei,
			   &resp);
	if (ret < 0)
		return ret;

	req.transaction_id = tid;
	strcpy(req.service_path, pds->service_path);

	ret = qmi_send_request(&pdr->notifier_hdl, &pds->addr,
			       &txn, SERVREG_SET_ACK_REQ,
			       SERVREG_SET_ACK_REQ_LEN,
			       servreg_set_ack_req_ei,
			       &req);

	/* Skip waiting for response */
	qmi_txn_cancel(&txn);
	return ret;
}

static void pdr_indack_work(struct work_struct *work)
{
	struct pdr_handle *pdr = container_of(work, struct pdr_handle,
					      indack_work);
	struct pdr_list_node *ind, *tmp;
	struct pdr_service *pds;

	list_for_each_entry_safe(ind, tmp, &pdr->indack_list, node) {
		pds = ind->pds;
		pdr_send_indack_msg(pdr, pds, ind->transaction_id);

		mutex_lock(&pdr->status_lock);
		pds->state = ind->curr_state;
		pdr->status(pds->state, pds->service_path, pdr->priv);
		mutex_unlock(&pdr->status_lock);

		mutex_lock(&pdr->list_lock);
		list_del(&ind->node);
		mutex_unlock(&pdr->list_lock);

		kfree(ind);
	}
}

static void pdr_indication_cb(struct qmi_handle *qmi,
			      struct sockaddr_qrtr *sq,
			      struct qmi_txn *txn, const void *data)
{
	struct pdr_handle *pdr = container_of(qmi, struct pdr_handle,
					      notifier_hdl);
	const struct servreg_state_updated_ind *ind_msg = data;
	struct pdr_list_node *ind;
	struct pdr_service *pds;
	bool found = false;

	if (!ind_msg || !ind_msg->service_path[0] ||
	    strlen(ind_msg->service_path) > SERVREG_NAME_LENGTH)
		return;

	mutex_lock(&pdr->list_lock);
	list_for_each_entry(pds, &pdr->lookups, node) {
		if (strcmp(pds->service_path, ind_msg->service_path))
			continue;

		found = true;
		break;
	}
	mutex_unlock(&pdr->list_lock);

	if (!found)
		return;

	pr_info("PDR: Indication received from %s, state: 0x%x, trans-id: %d\n",
		ind_msg->service_path, ind_msg->curr_state,
		ind_msg->transaction_id);

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

	ind->transaction_id = ind_msg->transaction_id;
	ind->curr_state = ind_msg->curr_state;
	ind->pds = pds;

	mutex_lock(&pdr->list_lock);
	list_add_tail(&ind->node, &pdr->indack_list);
	mutex_unlock(&pdr->list_lock);

	queue_work(pdr->indack_wq, &pdr->indack_work);
}

static struct qmi_msg_handler qmi_indication_handler[] = {
	{
		.type = QMI_INDICATION,
		.msg_id = SERVREG_STATE_UPDATED_IND_ID,
		.ei = servreg_state_updated_ind_ei,
		.decoded_size = sizeof(struct servreg_state_updated_ind),
		.fn = pdr_indication_cb,
	},
	{}
};

static int pdr_get_domain_list(struct servreg_get_domain_list_req *req,
			       struct servreg_get_domain_list_resp *resp,
			       struct pdr_handle *pdr)
{
	struct qmi_txn txn;
	int ret;

	ret = qmi_txn_init(&pdr->locator_hdl, &txn,
			   servreg_get_domain_list_resp_ei, resp);
	if (ret < 0)
		return ret;

	ret = qmi_send_request(&pdr->locator_hdl,
			       &pdr->locator_addr,
			       &txn, SERVREG_GET_DOMAIN_LIST_REQ,
			       SERVREG_GET_DOMAIN_LIST_REQ_MAX_LEN,
			       servreg_get_domain_list_req_ei,
			       req);
	if (ret < 0) {
		qmi_txn_cancel(&txn);
		return ret;
	}

	ret = qmi_txn_wait(&txn, 5 * HZ);
	if (ret < 0) {
		pr_err("PDR: %s get domain list txn wait failed: %d\n",
		       req->service_name, ret);
		return ret;
	}

	if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
		pr_err("PDR: %s get domain list failed: 0x%x\n",
		       req->service_name, resp->resp.error);
		return -EREMOTEIO;
	}

	return 0;
}

static int pdr_locate_service(struct pdr_handle *pdr, struct pdr_service *pds)
{
	struct servreg_get_domain_list_resp *resp;
	struct servreg_get_domain_list_req req;
	struct servreg_location_entry *entry;
	int domains_read = 0;
	int ret, i;

	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
	if (!resp)
		return -ENOMEM;

	/* Prepare req message */
	strcpy(req.service_name, pds->service_name);
	req.domain_offset_valid = true;
	req.domain_offset = 0;

	do {
		req.domain_offset = domains_read;
		ret = pdr_get_domain_list(&req, resp, pdr);
		if (ret < 0)
			goto out;

		for (i = domains_read; i < resp->domain_list_len; i++) {
			entry = &resp->domain_list[i];

			if (strnlen(entry->name, sizeof(entry->name)) == sizeof(entry->name))
				continue;

			if (!strcmp(entry->name, pds->service_path)) {
				pds->service_data_valid = entry->service_data_valid;
				pds->service_data = entry->service_data;
				pds->instance = entry->instance;
				goto out;
			}
		}

		/* Update ret to indicate that the service is not yet found */
		ret = -ENXIO;

		/* Always read total_domains from the response msg */
		if (resp->domain_list_len > resp->total_domains)
			resp->domain_list_len = resp->total_domains;

		domains_read += resp->domain_list_len;
	} while (domains_read < resp->total_domains);
out:
	kfree(resp);
	return ret;
}

static void pdr_notify_lookup_failure(struct pdr_handle *pdr,
				      struct pdr_service *pds,
				      int err)
{
	pr_err("PDR: service lookup for %s failed: %d\n",
	       pds->service_name, err);

	if (err == -ENXIO)
		return;

	list_del(&pds->node);
	pds->state = SERVREG_LOCATOR_ERR;
	mutex_lock(&pdr->status_lock);
	pdr->status(pds->state, pds->service_path, pdr->priv);
	mutex_unlock(&pdr->status_lock);
	kfree(pds);
}

static void pdr_locator_work(struct work_struct *work)
{
	struct pdr_handle *pdr = container_of(work, struct pdr_handle,
					      locator_work);
	struct pdr_service *pds, *tmp;
	int ret = 0;

	/* Bail out early if the SERVREG LOCATOR QMI service is not up */
	mutex_lock(&pdr->lock);
	if (!pdr->locator_init_complete) {
		mutex_unlock(&pdr->lock);
		pr_debug("PDR: SERVICE LOCATOR service not available\n");
		return;
	}
	mutex_unlock(&pdr->lock);

	mutex_lock(&pdr->list_lock);
	list_for_each_entry_safe(pds, tmp, &pdr->lookups, node) {
		if (!pds->need_locator_lookup)
			continue;

		ret = pdr_locate_service(pdr, pds);
		if (ret < 0) {
			pdr_notify_lookup_failure(pdr, pds, ret);
			continue;
		}

		ret = qmi_add_lookup(&pdr->notifier_hdl, pds->service, 1,
				     pds->instance);
		if (ret < 0) {
			pdr_notify_lookup_failure(pdr, pds, ret);
			continue;
		}

		pds->need_locator_lookup = false;
	}
	mutex_unlock(&pdr->list_lock);
}

/**
 * pdr_add_lookup() - register a tracking request for a PD
 * @pdr:		PDR client handle
 * @service_name:	service name of the tracking request
 * @service_path:	service path of the tracking request
 *
 * Registering a pdr lookup allows for tracking the life cycle of the PD.
 *
 * Return: pdr_service object on success, ERR_PTR on failure. -EALREADY is
 * returned if a lookup is already in progress for the given service path.
 */
struct pdr_service *pdr_add_lookup(struct pdr_handle *pdr,
				   const char *service_name,
				   const char *service_path)
{
	struct pdr_service *pds, *tmp;
	int ret;

	if (IS_ERR_OR_NULL(pdr))
		return ERR_PTR(-EINVAL);

	if (!service_name || strlen(service_name) > SERVREG_NAME_LENGTH ||
	    !service_path || strlen(service_path) > SERVREG_NAME_LENGTH)
		return ERR_PTR(-EINVAL);

	pds = kzalloc(sizeof(*pds), GFP_KERNEL);
	if (!pds)
		return ERR_PTR(-ENOMEM);

	pds->service = SERVREG_NOTIFIER_SERVICE;
	strcpy(pds->service_name, service_name);
	strcpy(pds->service_path, service_path);
	pds->need_locator_lookup = true;

	mutex_lock(&pdr->list_lock);
	list_for_each_entry(tmp, &pdr->lookups, node) {
		if (strcmp(tmp->service_path, service_path))
			continue;

		mutex_unlock(&pdr->list_lock);
		ret = -EALREADY;
		goto err;
	}

	list_add(&pds->node, &pdr->lookups);
	mutex_unlock(&pdr->list_lock);

	schedule_work(&pdr->locator_work);

	return pds;
err:
	kfree(pds);
	return ERR_PTR(ret);
}
EXPORT_SYMBOL(pdr_add_lookup);

/**
 * pdr_restart_pd() - restart PD
 * @pdr:	PDR client handle
 * @pds:	PD service handle
 *
 * Restarts the PD tracked by the PDR client handle for a given service path.
 *
 * Return: 0 on success, negative errno on failure.
 */
int pdr_restart_pd(struct pdr_handle *pdr, struct pdr_service *pds)
{
	struct servreg_restart_pd_resp resp;
	struct servreg_restart_pd_req req;
	struct sockaddr_qrtr addr;
	struct pdr_service *tmp;
	struct qmi_txn txn;
	int ret;

	if (IS_ERR_OR_NULL(pdr) || IS_ERR_OR_NULL(pds))
		return -EINVAL;

	mutex_lock(&pdr->list_lock);
	list_for_each_entry(tmp, &pdr->lookups, node) {
		if (tmp != pds)
			continue;

		if (!pds->service_connected)
			break;

		/* Prepare req message */
		strcpy(req.service_path, pds->service_path);
		addr = pds->addr;
		break;
	}
	mutex_unlock(&pdr->list_lock);

	if (!req.service_path[0])
		return -EINVAL;

	ret = qmi_txn_init(&pdr->notifier_hdl, &txn,
			   servreg_restart_pd_resp_ei,
			   &resp);
	if (ret < 0)
		return ret;

	ret = qmi_send_request(&pdr->notifier_hdl, &addr,
			       &txn, SERVREG_RESTART_PD_REQ,
			       SERVREG_RESTART_PD_REQ_MAX_LEN,
			       servreg_restart_pd_req_ei, &req);
	if (ret < 0) {
		qmi_txn_cancel(&txn);
		return ret;
	}

	ret = qmi_txn_wait(&txn, 5 * HZ);
	if (ret < 0) {
		pr_err("PDR: %s PD restart txn wait failed: %d\n",
		       req.service_path, ret);
		return ret;
	}

	/* Check response if PDR is disabled */
	if (resp.resp.result == QMI_RESULT_FAILURE_V01 &&
	    resp.resp.error == QMI_ERR_DISABLED_V01) {
		pr_err("PDR: %s PD restart is disabled: 0x%x\n",
		       req.service_path, resp.resp.error);
		return -EOPNOTSUPP;
	}

	/* Check the response for other error case*/
	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
		pr_err("PDR: %s request for PD restart failed: 0x%x\n",
		       req.service_path, resp.resp.error);
		return -EREMOTEIO;
	}

	return 0;
}
EXPORT_SYMBOL(pdr_restart_pd);

/**
 * pdr_handle_alloc() - initialize the PDR client handle
 * @status:	function to be called on PD state change
 * @priv:	handle for client's use
 *
 * Initializes the PDR client handle to allow for tracking/restart of PDs.
 *
 * Return: pdr_handle object on success, ERR_PTR on failure.
 */
struct pdr_handle *pdr_handle_alloc(void (*status)(int state,
						   char *service_path,
						   void *priv), void *priv)
{
	struct pdr_handle *pdr;
	int ret;

	if (!status)
		return ERR_PTR(-EINVAL);

	pdr = kzalloc(sizeof(*pdr), GFP_KERNEL);
	if (!pdr)
		return ERR_PTR(-ENOMEM);

	pdr->status = status;
	pdr->priv = priv;

	mutex_init(&pdr->status_lock);
	mutex_init(&pdr->list_lock);
	mutex_init(&pdr->lock);

	INIT_LIST_HEAD(&pdr->lookups);
	INIT_LIST_HEAD(&pdr->indack_list);

	INIT_WORK(&pdr->locator_work, pdr_locator_work);
	INIT_WORK(&pdr->notifier_work, pdr_notifier_work);
	INIT_WORK(&pdr->indack_work, pdr_indack_work);

	pdr->notifier_wq = create_singlethread_workqueue("pdr_notifier_wq");
	if (!pdr->notifier_wq) {
		ret = -ENOMEM;
		goto free_pdr_handle;
	}

	pdr->indack_wq = alloc_ordered_workqueue("pdr_indack_wq", WQ_HIGHPRI);
	if (!pdr->indack_wq) {
		ret = -ENOMEM;
		goto destroy_notifier;
	}

	ret = qmi_handle_init(&pdr->locator_hdl,
			      SERVREG_GET_DOMAIN_LIST_RESP_MAX_LEN,
			      &pdr_locator_ops, NULL);
	if (ret < 0)
		goto destroy_indack;

	ret = qmi_add_lookup(&pdr->locator_hdl, SERVREG_LOCATOR_SERVICE, 1, 1);
	if (ret < 0)
		goto release_qmi_handle;

	ret = qmi_handle_init(&pdr->notifier_hdl,
			      SERVREG_STATE_UPDATED_IND_MAX_LEN,
			      &pdr_notifier_ops,
			      qmi_indication_handler);
	if (ret < 0)
		goto release_qmi_handle;

	return pdr;

release_qmi_handle:
	qmi_handle_release(&pdr->locator_hdl);
destroy_indack:
	destroy_workqueue(pdr->indack_wq);
destroy_notifier:
	destroy_workqueue(pdr->notifier_wq);
free_pdr_handle:
	kfree(pdr);

	return ERR_PTR(ret);
}
EXPORT_SYMBOL(pdr_handle_alloc);

/**
 * pdr_handle_release() - release the PDR client handle
 * @pdr:	PDR client handle
 *
 * Cleans up pending tracking requests and releases the underlying qmi handles.
 */
void pdr_handle_release(struct pdr_handle *pdr)
{
	struct pdr_service *pds, *tmp;

	if (IS_ERR_OR_NULL(pdr))
		return;

	mutex_lock(&pdr->list_lock);
	list_for_each_entry_safe(pds, tmp, &pdr->lookups, node) {
		list_del(&pds->node);
		kfree(pds);
	}
	mutex_unlock(&pdr->list_lock);

	cancel_work_sync(&pdr->locator_work);
	cancel_work_sync(&pdr->notifier_work);
	cancel_work_sync(&pdr->indack_work);

	destroy_workqueue(pdr->notifier_wq);
	destroy_workqueue(pdr->indack_wq);

	qmi_handle_release(&pdr->locator_hdl);
	qmi_handle_release(&pdr->notifier_hdl);

	kfree(pdr);
}
EXPORT_SYMBOL(pdr_handle_release);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Qualcomm Protection Domain Restart helpers");
