// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/*
 * Copyright (c) 2020, Mellanox Technologies inc.  All rights reserved.
 */

#include <rdma/uverbs_std_types.h>
#include "rdma_core.h"
#include "uverbs.h"

static int uverbs_free_wq(struct ib_uobject *uobject,
			  enum rdma_remove_reason why,
			  struct uverbs_attr_bundle *attrs)
{
	struct ib_wq *wq = uobject->object;
	struct ib_uwq_object *uwq =
		container_of(uobject, struct ib_uwq_object, uevent.uobject);
	int ret;

	ret = ib_destroy_wq_user(wq, &attrs->driver_udata);
	if (ret)
		return ret;

	ib_uverbs_release_uevent(&uwq->uevent);
	return 0;
}

static int UVERBS_HANDLER(UVERBS_METHOD_WQ_CREATE)(
	struct uverbs_attr_bundle *attrs)
{
	struct ib_uwq_object *obj = container_of(
		uverbs_attr_get_uobject(attrs, UVERBS_ATTR_CREATE_WQ_HANDLE),
		typeof(*obj), uevent.uobject);
	struct ib_pd *pd =
		uverbs_attr_get_obj(attrs, UVERBS_ATTR_CREATE_WQ_PD_HANDLE);
	struct ib_cq *cq =
		uverbs_attr_get_obj(attrs, UVERBS_ATTR_CREATE_WQ_CQ_HANDLE);
	struct ib_wq_init_attr wq_init_attr = {};
	struct ib_wq *wq;
	u64 user_handle;
	int ret;

	ret = uverbs_get_flags32(&wq_init_attr.create_flags, attrs,
				 UVERBS_ATTR_CREATE_WQ_FLAGS,
				 IB_UVERBS_WQ_FLAGS_CVLAN_STRIPPING |
				 IB_UVERBS_WQ_FLAGS_SCATTER_FCS |
				 IB_UVERBS_WQ_FLAGS_DELAY_DROP |
				 IB_UVERBS_WQ_FLAGS_PCI_WRITE_END_PADDING);
	if (!ret)
		ret = uverbs_copy_from(&wq_init_attr.max_sge, attrs,
			       UVERBS_ATTR_CREATE_WQ_MAX_SGE);
	if (!ret)
		ret = uverbs_copy_from(&wq_init_attr.max_wr, attrs,
				       UVERBS_ATTR_CREATE_WQ_MAX_WR);
	if (!ret)
		ret = uverbs_copy_from(&user_handle, attrs,
				       UVERBS_ATTR_CREATE_WQ_USER_HANDLE);
	if (!ret)
		ret = uverbs_get_const(&wq_init_attr.wq_type, attrs,
				       UVERBS_ATTR_CREATE_WQ_TYPE);
	if (ret)
		return ret;

	if (wq_init_attr.wq_type != IB_WQT_RQ)
		return -EINVAL;

	obj->uevent.event_file = ib_uverbs_get_async_event(attrs,
					UVERBS_ATTR_CREATE_WQ_EVENT_FD);
	obj->uevent.uobject.user_handle = user_handle;
	INIT_LIST_HEAD(&obj->uevent.event_list);
	wq_init_attr.event_handler = ib_uverbs_wq_event_handler;
	wq_init_attr.wq_context = attrs->ufile;
	wq_init_attr.cq = cq;

	wq = pd->device->ops.create_wq(pd, &wq_init_attr, &attrs->driver_udata);
	if (IS_ERR(wq)) {
		ret = PTR_ERR(wq);
		goto err;
	}

	obj->uevent.uobject.object = wq;
	wq->wq_type = wq_init_attr.wq_type;
	wq->cq = cq;
	wq->pd = pd;
	wq->device = pd->device;
	wq->wq_context = wq_init_attr.wq_context;
	atomic_set(&wq->usecnt, 0);
	atomic_inc(&pd->usecnt);
	atomic_inc(&cq->usecnt);
	wq->uobject = obj;
	uverbs_finalize_uobj_create(attrs, UVERBS_ATTR_CREATE_WQ_HANDLE);

	ret = uverbs_copy_to(attrs, UVERBS_ATTR_CREATE_WQ_RESP_MAX_WR,
			     &wq_init_attr.max_wr,
			     sizeof(wq_init_attr.max_wr));
	if (ret)
		return ret;

	ret = uverbs_copy_to(attrs, UVERBS_ATTR_CREATE_WQ_RESP_MAX_SGE,
			     &wq_init_attr.max_sge,
			     sizeof(wq_init_attr.max_sge));
	if (ret)
		return ret;

	ret = uverbs_copy_to(attrs, UVERBS_ATTR_CREATE_WQ_RESP_WQ_NUM,
			     &wq->wq_num,
			     sizeof(wq->wq_num));
	return ret;

err:
	if (obj->uevent.event_file)
		uverbs_uobject_put(&obj->uevent.event_file->uobj);
	return ret;
};

DECLARE_UVERBS_NAMED_METHOD(
	UVERBS_METHOD_WQ_CREATE,
	UVERBS_ATTR_IDR(UVERBS_ATTR_CREATE_WQ_HANDLE,
			UVERBS_OBJECT_WQ,
			UVERBS_ACCESS_NEW,
			UA_MANDATORY),
	UVERBS_ATTR_IDR(UVERBS_ATTR_CREATE_WQ_PD_HANDLE,
			UVERBS_OBJECT_PD,
			UVERBS_ACCESS_READ,
			UA_MANDATORY),
	UVERBS_ATTR_CONST_IN(UVERBS_ATTR_CREATE_WQ_TYPE,
			     enum ib_wq_type,
			     UA_MANDATORY),
	UVERBS_ATTR_PTR_IN(UVERBS_ATTR_CREATE_WQ_USER_HANDLE,
			   UVERBS_ATTR_TYPE(u64),
			   UA_MANDATORY),
	UVERBS_ATTR_PTR_IN(UVERBS_ATTR_CREATE_WQ_MAX_WR,
			   UVERBS_ATTR_TYPE(u32),
			   UA_MANDATORY),
	UVERBS_ATTR_PTR_IN(UVERBS_ATTR_CREATE_WQ_MAX_SGE,
			   UVERBS_ATTR_TYPE(u32),
			   UA_MANDATORY),
	UVERBS_ATTR_FLAGS_IN(UVERBS_ATTR_CREATE_WQ_FLAGS,
			     enum ib_uverbs_wq_flags,
			     UA_MANDATORY),
	UVERBS_ATTR_IDR(UVERBS_ATTR_CREATE_WQ_CQ_HANDLE,
			UVERBS_OBJECT_CQ,
			UVERBS_ACCESS_READ,
			UA_OPTIONAL),
	UVERBS_ATTR_FD(UVERBS_ATTR_CREATE_WQ_EVENT_FD,
		       UVERBS_OBJECT_ASYNC_EVENT,
		       UVERBS_ACCESS_READ,
		       UA_OPTIONAL),
	UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_CREATE_WQ_RESP_MAX_WR,
			    UVERBS_ATTR_TYPE(u32),
			    UA_MANDATORY),
	UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_CREATE_WQ_RESP_MAX_SGE,
			    UVERBS_ATTR_TYPE(u32),
			    UA_MANDATORY),
	UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_CREATE_WQ_RESP_WQ_NUM,
			   UVERBS_ATTR_TYPE(u32),
			   UA_OPTIONAL),
	UVERBS_ATTR_UHW());

static int UVERBS_HANDLER(UVERBS_METHOD_WQ_DESTROY)(
	struct uverbs_attr_bundle *attrs)
{
	struct ib_uobject *uobj =
		uverbs_attr_get_uobject(attrs, UVERBS_ATTR_DESTROY_WQ_HANDLE);
	struct ib_uwq_object *obj =
		container_of(uobj, struct ib_uwq_object, uevent.uobject);

	return uverbs_copy_to(attrs, UVERBS_ATTR_DESTROY_WQ_RESP,
			      &obj->uevent.events_reported,
			      sizeof(obj->uevent.events_reported));
}

DECLARE_UVERBS_NAMED_METHOD(
	UVERBS_METHOD_WQ_DESTROY,
	UVERBS_ATTR_IDR(UVERBS_ATTR_DESTROY_WQ_HANDLE,
			UVERBS_OBJECT_WQ,
			UVERBS_ACCESS_DESTROY,
			UA_MANDATORY),
	UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_DESTROY_WQ_RESP,
			    UVERBS_ATTR_TYPE(u32),
			    UA_MANDATORY));


DECLARE_UVERBS_NAMED_OBJECT(
	UVERBS_OBJECT_WQ,
	UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_uwq_object), uverbs_free_wq),
	&UVERBS_METHOD(UVERBS_METHOD_WQ_CREATE),
	&UVERBS_METHOD(UVERBS_METHOD_WQ_DESTROY)
);

const struct uapi_definition uverbs_def_obj_wq[] = {
	UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_WQ,
				      UAPI_DEF_OBJ_NEEDS_FN(destroy_wq)),
	{}
};
