16bf9d8f6SLeon Romanovsky /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
26be60aedSMatan Barak /*
36be60aedSMatan Barak  * Copyright (c) 2017, Mellanox Technologies inc.  All rights reserved.
46be60aedSMatan Barak  */
56be60aedSMatan Barak 
66be60aedSMatan Barak #ifndef _UVERBS_STD_TYPES__
76be60aedSMatan Barak #define _UVERBS_STD_TYPES__
86be60aedSMatan Barak 
96be60aedSMatan Barak #include <rdma/uverbs_types.h>
1052427112SMatan Barak #include <rdma/uverbs_ioctl.h>
1164b19e13SMatan Barak #include <rdma/ib_user_ioctl_verbs.h>
1209e3ebf8SMatan Barak 
131250c304SJason Gunthorpe /* Returns _id, or causes a compile error if _id is not a u32.
141250c304SJason Gunthorpe  *
151250c304SJason Gunthorpe  * The uobj APIs should only be used with the write based uAPI to access
161250c304SJason Gunthorpe  * object IDs. The write API must use a u32 for the object handle, which is
171250c304SJason Gunthorpe  * checked by this macro.
181250c304SJason Gunthorpe  */
191250c304SJason Gunthorpe #define _uobj_check_id(_id) ((_id) * typecheck(u32, _id))
20fd3c7904SMatan Barak 
218313c10fSJason Gunthorpe #define uobj_get_type(_attrs, _object)                                         \
228313c10fSJason Gunthorpe 	uapi_get_object((_attrs)->ufile->device->uapi, _object)
23fd3c7904SMatan Barak 
248313c10fSJason Gunthorpe #define uobj_get_read(_type, _id, _attrs)                                      \
2570f06b26SShamir Rabinovitch 	rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
2670f06b26SShamir Rabinovitch 				_uobj_check_id(_id), UVERBS_LOOKUP_READ,       \
2770f06b26SShamir Rabinovitch 				_attrs)
28fd3c7904SMatan Barak 
298313c10fSJason Gunthorpe #define ufd_get_read(_type, _fdnum, _attrs)                                    \
308313c10fSJason Gunthorpe 	rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
319867f5c6SJason Gunthorpe 				(_fdnum)*typecheck(s32, _fdnum),               \
3270f06b26SShamir Rabinovitch 				UVERBS_LOOKUP_READ, _attrs)
331250c304SJason Gunthorpe 
_uobj_get_obj_read(struct ib_uobject * uobj)341250c304SJason Gunthorpe static inline void *_uobj_get_obj_read(struct ib_uobject *uobj)
352cc1e3b8SJason Gunthorpe {
362cc1e3b8SJason Gunthorpe 	if (IS_ERR(uobj))
372cc1e3b8SJason Gunthorpe 		return NULL;
382cc1e3b8SJason Gunthorpe 	return uobj->object;
392cc1e3b8SJason Gunthorpe }
408313c10fSJason Gunthorpe #define uobj_get_obj_read(_object, _type, _id, _attrs)                         \
411250c304SJason Gunthorpe 	((struct ib_##_object *)_uobj_get_obj_read(                            \
428313c10fSJason Gunthorpe 		uobj_get_read(_type, _id, _attrs)))
432cc1e3b8SJason Gunthorpe 
448313c10fSJason Gunthorpe #define uobj_get_write(_type, _id, _attrs)                                     \
4570f06b26SShamir Rabinovitch 	rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
4670f06b26SShamir Rabinovitch 				_uobj_check_id(_id), UVERBS_LOOKUP_WRITE,      \
4770f06b26SShamir Rabinovitch 				_attrs)
48fd3c7904SMatan Barak 
496b0d08f4SJason Gunthorpe int __uobj_perform_destroy(const struct uverbs_api_object *obj, u32 id,
5070f06b26SShamir Rabinovitch 			   struct uverbs_attr_bundle *attrs);
517106a976SJason Gunthorpe #define uobj_perform_destroy(_type, _id, _attrs)                               \
528313c10fSJason Gunthorpe 	__uobj_perform_destroy(uobj_get_type(_attrs, _type),                   \
537106a976SJason Gunthorpe 			       _uobj_check_id(_id), _attrs)
54c33e73afSJason Gunthorpe 
556b0d08f4SJason Gunthorpe struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj,
5670f06b26SShamir Rabinovitch 				      u32 id, struct uverbs_attr_bundle *attrs);
5732ed5c00SJason Gunthorpe 
588313c10fSJason Gunthorpe #define uobj_get_destroy(_type, _id, _attrs)                                   \
598313c10fSJason Gunthorpe 	__uobj_get_destroy(uobj_get_type(_attrs, _type), _uobj_check_id(_id),  \
608313c10fSJason Gunthorpe 			   _attrs)
6132ed5c00SJason Gunthorpe 
uobj_put_destroy(struct ib_uobject * uobj)6232ed5c00SJason Gunthorpe static inline void uobj_put_destroy(struct ib_uobject *uobj)
6332ed5c00SJason Gunthorpe {
64c85f4abeSJason Gunthorpe 	rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_DESTROY);
6532ed5c00SJason Gunthorpe }
6632ed5c00SJason Gunthorpe 
uobj_put_read(struct ib_uobject * uobj)67fd3c7904SMatan Barak static inline void uobj_put_read(struct ib_uobject *uobj)
68fd3c7904SMatan Barak {
699867f5c6SJason Gunthorpe 	rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_READ);
70fd3c7904SMatan Barak }
71fd3c7904SMatan Barak 
72fd3c7904SMatan Barak #define uobj_put_obj_read(_obj)					\
73fd3c7904SMatan Barak 	uobj_put_read((_obj)->uobject)
74fd3c7904SMatan Barak 
uobj_put_write(struct ib_uobject * uobj)75fd3c7904SMatan Barak static inline void uobj_put_write(struct ib_uobject *uobj)
76fd3c7904SMatan Barak {
779867f5c6SJason Gunthorpe 	rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_WRITE);
78fd3c7904SMatan Barak }
79fd3c7904SMatan Barak 
uobj_alloc_abort(struct ib_uobject * uobj,struct uverbs_attr_bundle * attrs)80a6a3797dSShamir Rabinovitch static inline void uobj_alloc_abort(struct ib_uobject *uobj,
81a6a3797dSShamir Rabinovitch 				    struct uverbs_attr_bundle *attrs)
82fd3c7904SMatan Barak {
830ac8903cSJason Gunthorpe 	rdma_alloc_abort_uobject(uobj, attrs, false);
84fd3c7904SMatan Barak }
85fd3c7904SMatan Barak 
uobj_finalize_uobj_create(struct ib_uobject * uobj,struct uverbs_attr_bundle * attrs)860f63ef1dSLeon Romanovsky static inline void uobj_finalize_uobj_create(struct ib_uobject *uobj,
870f63ef1dSLeon Romanovsky 					     struct uverbs_attr_bundle *attrs)
880f63ef1dSLeon Romanovsky {
890f63ef1dSLeon Romanovsky 	/*
900f63ef1dSLeon Romanovsky 	 * Tell the core code that the write() handler has completed
910f63ef1dSLeon Romanovsky 	 * initializing the object and that the core should commit or
920f63ef1dSLeon Romanovsky 	 * abort this object based upon the return code from the write()
930f63ef1dSLeon Romanovsky 	 * method. Similar to what uverbs_finalize_uobj_create() does for
940f63ef1dSLeon Romanovsky 	 * ioctl()
950f63ef1dSLeon Romanovsky 	 */
960f63ef1dSLeon Romanovsky 	WARN_ON(attrs->uobject);
970f63ef1dSLeon Romanovsky 	attrs->uobject = uobj;
980f63ef1dSLeon Romanovsky }
990f63ef1dSLeon Romanovsky 
1006b0d08f4SJason Gunthorpe static inline struct ib_uobject *
__uobj_alloc(const struct uverbs_api_object * obj,struct uverbs_attr_bundle * attrs,struct ib_device ** ib_dev)1018313c10fSJason Gunthorpe __uobj_alloc(const struct uverbs_api_object *obj,
1028313c10fSJason Gunthorpe 	     struct uverbs_attr_bundle *attrs, struct ib_device **ib_dev)
103fd3c7904SMatan Barak {
10439e83af8SJason Gunthorpe 	struct ib_uobject *uobj = rdma_alloc_begin_uobject(obj, attrs);
105bbd51e88SJason Gunthorpe 
10670f06b26SShamir Rabinovitch 	if (!IS_ERR(uobj))
107feec576aSJason Gunthorpe 		*ib_dev = attrs->context->device;
108bbd51e88SJason Gunthorpe 	return uobj;
109fd3c7904SMatan Barak }
110fd3c7904SMatan Barak 
1118313c10fSJason Gunthorpe #define uobj_alloc(_type, _attrs, _ib_dev)                                     \
1128313c10fSJason Gunthorpe 	__uobj_alloc(uobj_get_type(_attrs, _type), _attrs, _ib_dev)
113fd3c7904SMatan Barak 
uverbs_flow_action_fill_action(struct ib_flow_action * action,struct ib_uobject * uobj,struct ib_device * ib_dev,enum ib_flow_action_type type)114841eefc5SMark Bloch static inline void uverbs_flow_action_fill_action(struct ib_flow_action *action,
115841eefc5SMark Bloch 						  struct ib_uobject *uobj,
116841eefc5SMark Bloch 						  struct ib_device *ib_dev,
117841eefc5SMark Bloch 						  enum ib_flow_action_type type)
118841eefc5SMark Bloch {
119841eefc5SMark Bloch 	atomic_set(&action->usecnt, 0);
120841eefc5SMark Bloch 	action->device = ib_dev;
121841eefc5SMark Bloch 	action->type = type;
122841eefc5SMark Bloch 	action->uobject = uobj;
123841eefc5SMark Bloch 	uobj->object = action;
124841eefc5SMark Bloch }
125841eefc5SMark Bloch 
12686e1d464SMark Bloch struct ib_uflow_resources {
12786e1d464SMark Bloch 	size_t			max;
12886e1d464SMark Bloch 	size_t			num;
12986e1d464SMark Bloch 	size_t			collection_num;
13086e1d464SMark Bloch 	size_t			counters_num;
13186e1d464SMark Bloch 	struct ib_counters	**counters;
13286e1d464SMark Bloch 	struct ib_flow_action	**collection;
13386e1d464SMark Bloch };
13486e1d464SMark Bloch 
13586e1d464SMark Bloch struct ib_uflow_object {
13686e1d464SMark Bloch 	struct ib_uobject		uobject;
13786e1d464SMark Bloch 	struct ib_uflow_resources	*resources;
13886e1d464SMark Bloch };
13986e1d464SMark Bloch 
140fa76d24eSMark Bloch struct ib_uflow_resources *flow_resources_alloc(size_t num_specs);
141fa76d24eSMark Bloch void flow_resources_add(struct ib_uflow_resources *uflow_res,
142fa76d24eSMark Bloch 			enum ib_flow_spec_type type,
143fa76d24eSMark Bloch 			void *ibobj);
144fa76d24eSMark Bloch void ib_uverbs_flow_resources_free(struct ib_uflow_resources *uflow_res);
145fa76d24eSMark Bloch 
ib_set_flow(struct ib_uobject * uobj,struct ib_flow * ibflow,struct ib_qp * qp,struct ib_device * device,struct ib_uflow_resources * uflow_res)14686e1d464SMark Bloch static inline void ib_set_flow(struct ib_uobject *uobj, struct ib_flow *ibflow,
14786e1d464SMark Bloch 			       struct ib_qp *qp, struct ib_device *device,
14886e1d464SMark Bloch 			       struct ib_uflow_resources *uflow_res)
14986e1d464SMark Bloch {
15086e1d464SMark Bloch 	struct ib_uflow_object *uflow;
15186e1d464SMark Bloch 
15286e1d464SMark Bloch 	uobj->object = ibflow;
15386e1d464SMark Bloch 	ibflow->uobject = uobj;
15486e1d464SMark Bloch 
15586e1d464SMark Bloch 	if (qp) {
15686e1d464SMark Bloch 		atomic_inc(&qp->usecnt);
15786e1d464SMark Bloch 		ibflow->qp = qp;
15886e1d464SMark Bloch 	}
15986e1d464SMark Bloch 
16086e1d464SMark Bloch 	ibflow->device = device;
16186e1d464SMark Bloch 	uflow = container_of(uobj, typeof(*uflow), uobject);
16286e1d464SMark Bloch 	uflow->resources = uflow_res;
16386e1d464SMark Bloch }
16486e1d464SMark Bloch 
16504ca16ccSYishai Hadas struct uverbs_api_object {
16604ca16ccSYishai Hadas 	const struct uverbs_obj_type *type_attrs;
16704ca16ccSYishai Hadas 	const struct uverbs_obj_type_class *type_class;
16804ca16ccSYishai Hadas 	u8 disabled:1;
16904ca16ccSYishai Hadas 	u32 id;
17004ca16ccSYishai Hadas };
17104ca16ccSYishai Hadas 
uobj_get_object_id(struct ib_uobject * uobj)17204ca16ccSYishai Hadas static inline u32 uobj_get_object_id(struct ib_uobject *uobj)
17304ca16ccSYishai Hadas {
17404ca16ccSYishai Hadas 	return uobj->uapi_object->id;
17504ca16ccSYishai Hadas }
17604ca16ccSYishai Hadas 
1776be60aedSMatan Barak #endif
1786be60aedSMatan Barak 
179