16be60aedSMatan Barak /*
26be60aedSMatan Barak  * Copyright (c) 2017, Mellanox Technologies inc.  All rights reserved.
36be60aedSMatan Barak  *
46be60aedSMatan Barak  * This software is available to you under a choice of one of two
56be60aedSMatan Barak  * licenses.  You may choose to be licensed under the terms of the GNU
66be60aedSMatan Barak  * General Public License (GPL) Version 2, available from the file
76be60aedSMatan Barak  * COPYING in the main directory of this source tree, or the
86be60aedSMatan Barak  * OpenIB.org BSD license below:
96be60aedSMatan Barak  *
106be60aedSMatan Barak  *     Redistribution and use in source and binary forms, with or
116be60aedSMatan Barak  *     without modification, are permitted provided that the following
126be60aedSMatan Barak  *     conditions are met:
136be60aedSMatan Barak  *
146be60aedSMatan Barak  *      - Redistributions of source code must retain the above
156be60aedSMatan Barak  *        copyright notice, this list of conditions and the following
166be60aedSMatan Barak  *        disclaimer.
176be60aedSMatan Barak  *
186be60aedSMatan Barak  *      - Redistributions in binary form must reproduce the above
196be60aedSMatan Barak  *        copyright notice, this list of conditions and the following
206be60aedSMatan Barak  *        disclaimer in the documentation and/or other materials
216be60aedSMatan Barak  *        provided with the distribution.
226be60aedSMatan Barak  *
236be60aedSMatan Barak  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
246be60aedSMatan Barak  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
256be60aedSMatan Barak  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
266be60aedSMatan Barak  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
276be60aedSMatan Barak  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
286be60aedSMatan Barak  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
296be60aedSMatan Barak  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
306be60aedSMatan Barak  * SOFTWARE.
316be60aedSMatan Barak  */
326be60aedSMatan Barak 
336be60aedSMatan Barak #ifndef _UVERBS_STD_TYPES__
346be60aedSMatan Barak #define _UVERBS_STD_TYPES__
356be60aedSMatan Barak 
366be60aedSMatan Barak #include <rdma/uverbs_types.h>
3752427112SMatan Barak #include <rdma/uverbs_ioctl.h>
3864b19e13SMatan Barak #include <rdma/ib_user_ioctl_verbs.h>
3909e3ebf8SMatan Barak 
401250c304SJason Gunthorpe /* Returns _id, or causes a compile error if _id is not a u32.
411250c304SJason Gunthorpe  *
421250c304SJason Gunthorpe  * The uobj APIs should only be used with the write based uAPI to access
431250c304SJason Gunthorpe  * object IDs. The write API must use a u32 for the object handle, which is
441250c304SJason Gunthorpe  * checked by this macro.
451250c304SJason Gunthorpe  */
461250c304SJason Gunthorpe #define _uobj_check_id(_id) ((_id) * typecheck(u32, _id))
47fd3c7904SMatan Barak 
488313c10fSJason Gunthorpe #define uobj_get_type(_attrs, _object)                                         \
498313c10fSJason Gunthorpe 	uapi_get_object((_attrs)->ufile->device->uapi, _object)
50fd3c7904SMatan Barak 
518313c10fSJason Gunthorpe #define uobj_get_read(_type, _id, _attrs)                                      \
5270f06b26SShamir Rabinovitch 	rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
5370f06b26SShamir Rabinovitch 				_uobj_check_id(_id), UVERBS_LOOKUP_READ,       \
5470f06b26SShamir Rabinovitch 				_attrs)
55fd3c7904SMatan Barak 
568313c10fSJason Gunthorpe #define ufd_get_read(_type, _fdnum, _attrs)                                    \
578313c10fSJason Gunthorpe 	rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
589867f5c6SJason Gunthorpe 				(_fdnum)*typecheck(s32, _fdnum),               \
5970f06b26SShamir Rabinovitch 				UVERBS_LOOKUP_READ, _attrs)
601250c304SJason Gunthorpe 
611250c304SJason Gunthorpe static inline void *_uobj_get_obj_read(struct ib_uobject *uobj)
622cc1e3b8SJason Gunthorpe {
632cc1e3b8SJason Gunthorpe 	if (IS_ERR(uobj))
642cc1e3b8SJason Gunthorpe 		return NULL;
652cc1e3b8SJason Gunthorpe 	return uobj->object;
662cc1e3b8SJason Gunthorpe }
678313c10fSJason Gunthorpe #define uobj_get_obj_read(_object, _type, _id, _attrs)                         \
681250c304SJason Gunthorpe 	((struct ib_##_object *)_uobj_get_obj_read(                            \
698313c10fSJason Gunthorpe 		uobj_get_read(_type, _id, _attrs)))
702cc1e3b8SJason Gunthorpe 
718313c10fSJason Gunthorpe #define uobj_get_write(_type, _id, _attrs)                                     \
7270f06b26SShamir Rabinovitch 	rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
7370f06b26SShamir Rabinovitch 				_uobj_check_id(_id), UVERBS_LOOKUP_WRITE,      \
7470f06b26SShamir Rabinovitch 				_attrs)
75fd3c7904SMatan Barak 
766b0d08f4SJason Gunthorpe int __uobj_perform_destroy(const struct uverbs_api_object *obj, u32 id,
7770f06b26SShamir Rabinovitch 			   struct uverbs_attr_bundle *attrs);
787106a976SJason Gunthorpe #define uobj_perform_destroy(_type, _id, _attrs)                               \
798313c10fSJason Gunthorpe 	__uobj_perform_destroy(uobj_get_type(_attrs, _type),                   \
807106a976SJason Gunthorpe 			       _uobj_check_id(_id), _attrs)
81c33e73afSJason Gunthorpe 
826b0d08f4SJason Gunthorpe struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj,
8370f06b26SShamir Rabinovitch 				      u32 id, struct uverbs_attr_bundle *attrs);
8432ed5c00SJason Gunthorpe 
858313c10fSJason Gunthorpe #define uobj_get_destroy(_type, _id, _attrs)                                   \
868313c10fSJason Gunthorpe 	__uobj_get_destroy(uobj_get_type(_attrs, _type), _uobj_check_id(_id),  \
878313c10fSJason Gunthorpe 			   _attrs)
8832ed5c00SJason Gunthorpe 
8932ed5c00SJason Gunthorpe static inline void uobj_put_destroy(struct ib_uobject *uobj)
9032ed5c00SJason Gunthorpe {
91c85f4abeSJason Gunthorpe 	rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_DESTROY);
9232ed5c00SJason Gunthorpe }
9332ed5c00SJason Gunthorpe 
94fd3c7904SMatan Barak static inline void uobj_put_read(struct ib_uobject *uobj)
95fd3c7904SMatan Barak {
969867f5c6SJason Gunthorpe 	rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_READ);
97fd3c7904SMatan Barak }
98fd3c7904SMatan Barak 
99fd3c7904SMatan Barak #define uobj_put_obj_read(_obj)					\
100fd3c7904SMatan Barak 	uobj_put_read((_obj)->uobject)
101fd3c7904SMatan Barak 
102fd3c7904SMatan Barak static inline void uobj_put_write(struct ib_uobject *uobj)
103fd3c7904SMatan Barak {
1049867f5c6SJason Gunthorpe 	rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_WRITE);
105fd3c7904SMatan Barak }
106fd3c7904SMatan Barak 
107a6a3797dSShamir Rabinovitch static inline void uobj_alloc_abort(struct ib_uobject *uobj,
108a6a3797dSShamir Rabinovitch 				    struct uverbs_attr_bundle *attrs)
109fd3c7904SMatan Barak {
110a6a3797dSShamir Rabinovitch 	rdma_alloc_abort_uobject(uobj, attrs);
111fd3c7904SMatan Barak }
112fd3c7904SMatan Barak 
1136b0d08f4SJason Gunthorpe static inline struct ib_uobject *
1148313c10fSJason Gunthorpe __uobj_alloc(const struct uverbs_api_object *obj,
1158313c10fSJason Gunthorpe 	     struct uverbs_attr_bundle *attrs, struct ib_device **ib_dev)
116fd3c7904SMatan Barak {
11739e83af8SJason Gunthorpe 	struct ib_uobject *uobj = rdma_alloc_begin_uobject(obj, attrs);
118bbd51e88SJason Gunthorpe 
11970f06b26SShamir Rabinovitch 	if (!IS_ERR(uobj))
120feec576aSJason Gunthorpe 		*ib_dev = attrs->context->device;
121bbd51e88SJason Gunthorpe 	return uobj;
122fd3c7904SMatan Barak }
123fd3c7904SMatan Barak 
1248313c10fSJason Gunthorpe #define uobj_alloc(_type, _attrs, _ib_dev)                                     \
1258313c10fSJason Gunthorpe 	__uobj_alloc(uobj_get_type(_attrs, _type), _attrs, _ib_dev)
126fd3c7904SMatan Barak 
127841eefc5SMark Bloch static inline void uverbs_flow_action_fill_action(struct ib_flow_action *action,
128841eefc5SMark Bloch 						  struct ib_uobject *uobj,
129841eefc5SMark Bloch 						  struct ib_device *ib_dev,
130841eefc5SMark Bloch 						  enum ib_flow_action_type type)
131841eefc5SMark Bloch {
132841eefc5SMark Bloch 	atomic_set(&action->usecnt, 0);
133841eefc5SMark Bloch 	action->device = ib_dev;
134841eefc5SMark Bloch 	action->type = type;
135841eefc5SMark Bloch 	action->uobject = uobj;
136841eefc5SMark Bloch 	uobj->object = action;
137841eefc5SMark Bloch }
138841eefc5SMark Bloch 
13986e1d464SMark Bloch struct ib_uflow_resources {
14086e1d464SMark Bloch 	size_t			max;
14186e1d464SMark Bloch 	size_t			num;
14286e1d464SMark Bloch 	size_t			collection_num;
14386e1d464SMark Bloch 	size_t			counters_num;
14486e1d464SMark Bloch 	struct ib_counters	**counters;
14586e1d464SMark Bloch 	struct ib_flow_action	**collection;
14686e1d464SMark Bloch };
14786e1d464SMark Bloch 
14886e1d464SMark Bloch struct ib_uflow_object {
14986e1d464SMark Bloch 	struct ib_uobject		uobject;
15086e1d464SMark Bloch 	struct ib_uflow_resources	*resources;
15186e1d464SMark Bloch };
15286e1d464SMark Bloch 
153fa76d24eSMark Bloch struct ib_uflow_resources *flow_resources_alloc(size_t num_specs);
154fa76d24eSMark Bloch void flow_resources_add(struct ib_uflow_resources *uflow_res,
155fa76d24eSMark Bloch 			enum ib_flow_spec_type type,
156fa76d24eSMark Bloch 			void *ibobj);
157fa76d24eSMark Bloch void ib_uverbs_flow_resources_free(struct ib_uflow_resources *uflow_res);
158fa76d24eSMark Bloch 
15986e1d464SMark Bloch static inline void ib_set_flow(struct ib_uobject *uobj, struct ib_flow *ibflow,
16086e1d464SMark Bloch 			       struct ib_qp *qp, struct ib_device *device,
16186e1d464SMark Bloch 			       struct ib_uflow_resources *uflow_res)
16286e1d464SMark Bloch {
16386e1d464SMark Bloch 	struct ib_uflow_object *uflow;
16486e1d464SMark Bloch 
16586e1d464SMark Bloch 	uobj->object = ibflow;
16686e1d464SMark Bloch 	ibflow->uobject = uobj;
16786e1d464SMark Bloch 
16886e1d464SMark Bloch 	if (qp) {
16986e1d464SMark Bloch 		atomic_inc(&qp->usecnt);
17086e1d464SMark Bloch 		ibflow->qp = qp;
17186e1d464SMark Bloch 	}
17286e1d464SMark Bloch 
17386e1d464SMark Bloch 	ibflow->device = device;
17486e1d464SMark Bloch 	uflow = container_of(uobj, typeof(*uflow), uobject);
17586e1d464SMark Bloch 	uflow->resources = uflow_res;
17686e1d464SMark Bloch }
17786e1d464SMark Bloch 
17804ca16ccSYishai Hadas struct uverbs_api_object {
17904ca16ccSYishai Hadas 	const struct uverbs_obj_type *type_attrs;
18004ca16ccSYishai Hadas 	const struct uverbs_obj_type_class *type_class;
18104ca16ccSYishai Hadas 	u8 disabled:1;
18204ca16ccSYishai Hadas 	u32 id;
18304ca16ccSYishai Hadas };
18404ca16ccSYishai Hadas 
18504ca16ccSYishai Hadas static inline u32 uobj_get_object_id(struct ib_uobject *uobj)
18604ca16ccSYishai Hadas {
18704ca16ccSYishai Hadas 	return uobj->uapi_object->id;
18804ca16ccSYishai Hadas }
18904ca16ccSYishai Hadas 
1906be60aedSMatan Barak #endif
1916be60aedSMatan Barak 
192