1/*
2 * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5 *
6 * This software is available to you under a choice of one of two
7 * licenses.  You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
11 *
12 *     Redistribution and use in source and binary forms, with or
13 *     without modification, are permitted provided that the following
14 *     conditions are met:
15 *
16 *      - Redistributions of source code must retain the above
17 *        copyright notice, this list of conditions and the following
18 *        disclaimer.
19 *
20 *      - Redistributions in binary form must reproduce the above
21 *        copyright notice, this list of conditions and the following
22 *        disclaimer in the documentation and/or other materials
23 *        provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 *
34 */
35
36#ifndef _OSMV_TXN_H_
37#define _OSMV_TXN_H_
38
39#include <sys/types.h>
40#include <unistd.h>
41
42#include <complib/cl_qmap.h>
43#include <opensm/osm_madw.h>
44#include <complib/cl_event_wheel.h>
45
46#include <vendor/osm_vendor_mlx_rmpp_ctx.h>
47
48#ifdef __cplusplus
49#  define BEGIN_C_DECLS extern "C" {
50#  define END_C_DECLS   }
51#else				/* !__cplusplus */
52#  define BEGIN_C_DECLS
53#  define END_C_DECLS
54#endif				/* __cplusplus */
55
56BEGIN_C_DECLS
57
58typedef enum _osmv_txn_rmpp_state {
59
60	OSMV_TXN_RMPP_NONE = 0,	/* Not part of RMPP transaction */
61
62	OSMV_TXN_RMPP_SENDER,
63	OSMV_TXN_RMPP_RECEIVER
64} osmv_txn_rmpp_state_t;
65
66typedef struct _osmv_rmpp_txfr {
67
68	osmv_txn_rmpp_state_t rmpp_state;
69	boolean_t is_rmpp_init_by_peer;
70	osmv_rmpp_send_ctx_t *p_rmpp_send_ctx;
71	osmv_rmpp_recv_ctx_t *p_rmpp_recv_ctx;
72
73} osmv_rmpp_txfr_t;
74
75typedef struct _osmv_txn_ctx {
76
77	/* The original Transaction ID */
78	uint64_t tid;
79	/* The key by which the Transaction is stored */
80	uint64_t key;
81
82	/* RMPP Send/Receive contexts, if applicable */
83	osmv_rmpp_txfr_t rmpp_txfr;
84
85	/* A MAD that was sent during the transaction (request or response) */
86	osm_madw_t *p_madw;
87
88	/* Reference to a log to enable tracing */
89	osm_log_t *p_log;
90
91} osmv_txn_ctx_t;
92
93typedef struct _osmv_txn_mgr {
94
95	/* Container of all the transactions */
96	cl_qmap_t *p_txn_map;
97
98	/* The timeouts DB */
99	cl_event_wheel_t *p_event_wheel;
100
101	/* Reference to a log to enable tracing */
102	osm_log_t *p_log;
103
104} osmv_txn_mgr_t;
105
106/* *    *   *   *   *   *   osmv_txn_ctx_t functions  *    *   *   *   *   *   *   *   */
107
108/*
109 * NAME
110 *   osmv_txn_init
111 *
112 * DESCRIPTION
113 *   allocs & inits the osmv_txn_ctx obj and insert it into the db
114 * SEE ALSO
115 *
116 */
117ib_api_status_t
118osmv_txn_init(IN osm_bind_handle_t h_bind,
119	      IN uint64_t tid, IN uint64_t key, OUT osmv_txn_ctx_t ** pp_txn);
120
121/*
122 * NAME
123 *   osmv_rmpp_txfr_init_sender
124 *
125 * DESCRIPTION
126 *   init the rmpp send ctx in the transaction
127 *
128 * SEE ALSO
129 *
130 */
131ib_api_status_t
132osmv_txn_init_rmpp_sender(IN osm_bind_handle_t h_bind,
133			  IN osmv_txn_ctx_t * p_txn, IN osm_madw_t * p_madw);
134
135/*
136 * NAME
137 *   osmv_rmpp_txfr_init_receiver
138 *
139 * DESCRIPTION
140 *   init the rmpp recv ctx in the transaction
141 *
142 * SEE ALSO
143 *
144 */
145ib_api_status_t
146osmv_txn_init_rmpp_receiver(IN osm_bind_handle_t h_bind,
147			    IN osmv_txn_ctx_t * p_txn,
148			    IN boolean_t is_init_by_peer);
149
150/*
151 * NAME
152 *   osmv_txn_done
153 *
154 * DESCRIPTION
155 *   destroys txn object and removes it from the db
156 *
157 * SEE ALSO
158 *
159 */
160void
161osmv_txn_done(IN osm_bind_handle_t h_bind,
162	      IN uint64_t key, IN boolean_t is_in_cb);
163/*
164 * NAME
165 *   osmv_txn_get_tid
166 *
167 * DESCRIPTION
168 *   returns tid of the transaction
169 * SEE ALSO
170 *
171 */
172static inline uint64_t osmv_txn_get_tid(IN osmv_txn_ctx_t * p_txn)
173{
174	CL_ASSERT(NULL != p_txn);
175	return p_txn->tid;
176}
177
178/*
179 * NAME
180 *   osmv_txn_get_key
181 *
182 * DESCRIPTION
183 *   returns key of the transaction
184 * SEE ALSO
185 *
186 */
187
188static inline uint64_t osmv_txn_get_key(IN osmv_txn_ctx_t * p_txn)
189{
190	CL_ASSERT(NULL != p_txn);
191	return p_txn->key;
192}
193
194/*
195 * NAME
196 *   osmv_txn_is_rmpp_init_by_peer
197 *
198 * DESCRIPTION
199 *   returns whether the rmpp txfr was init by the peer
200 *
201 * SEE ALSO
202 *
203 */
204static inline boolean_t osmv_txn_is_rmpp_init_by_peer(IN osmv_txn_ctx_t * p_txn)
205{
206	CL_ASSERT(NULL != p_txn);
207	return p_txn->rmpp_txfr.is_rmpp_init_by_peer;
208}
209
210/*
211 * NAME
212 *   osmv_txn_get_rmpp_send_ctx
213 *
214 * DESCRIPTION
215 *   returns osmv_rmpp_send_ctx obj
216 * SEE ALSO
217 *
218 */
219static inline osmv_rmpp_send_ctx_t *osmv_txn_get_rmpp_send_ctx(IN osmv_txn_ctx_t
220							       * p_txn)
221{
222	CL_ASSERT(NULL != p_txn);
223	return p_txn->rmpp_txfr.p_rmpp_send_ctx;
224}
225
226/*
227 * NAME
228 *   osmv_txn_get_rmpp_recv_ctx
229 *
230 * DESCRIPTION
231 *   returns osmv_rmpp_recv_ctx obj
232 * SEE ALSO
233 *
234 */
235static inline osmv_rmpp_recv_ctx_t *osmv_txn_get_rmpp_recv_ctx(IN osmv_txn_ctx_t
236							       * p_txn)
237{
238	CL_ASSERT(NULL != p_txn);
239	return p_txn->rmpp_txfr.p_rmpp_recv_ctx;
240}
241
242/*
243 * NAME
244 *   osmv_txn_get_rmpp_state
245 *
246 * DESCRIPTION
247 *   returns the rmpp role of the transactino ( send/ recv)
248 * SEE ALSO
249 *
250 */
251static inline osmv_txn_rmpp_state_t
252osmv_txn_get_rmpp_state(IN osmv_txn_ctx_t * p_txn)
253{
254	CL_ASSERT(NULL != p_txn);
255	return p_txn->rmpp_txfr.rmpp_state;
256}
257
258/*
259 * NAME
260 *   osmv_txn_set_rmpp_state
261 *
262 * DESCRIPTION
263 *   sets the rmpp role of the transaction (send/ recv)
264 * SEE ALSO
265 *
266 */
267static inline void
268osmv_txn_set_rmpp_state(IN osmv_txn_ctx_t * p_txn,
269			IN osmv_txn_rmpp_state_t state)
270{
271	CL_ASSERT(NULL != p_txn);
272	p_txn->rmpp_txfr.rmpp_state = state;
273}
274
275/*
276 * NAME
277 *   osmv_txn_get_madw
278 *
279 * DESCRIPTION
280 *   returns the requester madw
281 * SEE ALSO
282 *
283 */
284static inline osm_madw_t *osmv_txn_get_madw(IN osmv_txn_ctx_t * p_txn)
285{
286	CL_ASSERT(NULL != p_txn);
287	return p_txn->p_madw;
288}
289
290/*
291 * NAME
292 *   osmv_txn_set_madw
293 *
294 * DESCRIPTION
295 *   sets the requester madw
296 * SEE ALSO
297 *
298 */
299static inline void
300osmv_txn_set_madw(IN osmv_txn_ctx_t * p_txn, IN osm_madw_t * p_madw)
301{
302	CL_ASSERT(NULL != p_txn);
303	p_txn->p_madw = p_madw;
304}
305
306/*
307 * NAME
308 *  osmv_txn_set_timeout_ev
309 *
310 * DESCRIPTION
311 *
312 * SEE ALSO
313 *
314 */
315ib_api_status_t
316osmv_txn_set_timeout_ev(IN osm_bind_handle_t h_bind,
317			IN uint64_t key, IN uint64_t msec);
318/*
319 * NAME
320 *  osmv_txn_remove_timeout_ev
321 *
322 * DESCRIPTION
323
324 * SEE ALSO
325 *
326 */
327void osmv_txn_remove_timeout_ev(IN osm_bind_handle_t h_bind, IN uint64_t key);
328/*
329 * NAME
330 *  osmv_txn_lookup
331 *
332 * DESCRIPTION
333 *   get a transaction by its key
334 *
335 * SEE ALSO
336 *
337 */
338ib_api_status_t
339osmv_txn_lookup(IN osm_bind_handle_t h_bind,
340		IN uint64_t key, OUT osmv_txn_ctx_t ** pp_txn);
341
342void osmv_txn_abort_rmpp_txns(IN osm_bind_handle_t h_bind);
343
344/*      *       *       *       *       *       *       *       *       *       *       *       */
345/*
346 * NAME
347 *  osmv_txnmgr_init
348 *
349 * DESCRIPTION
350 *  c'tor for txn mgr obj
351 * SEE ALSO
352 *
353 */
354ib_api_status_t
355osmv_txnmgr_init(IN osmv_txn_mgr_t * p_tx_mgr,
356		 IN osm_log_t * p_log, IN cl_spinlock_t * p_lock);
357
358/*
359 * NAME
360 *  osmv_txnmgr_done
361 *
362 * DESCRIPTION
363 *  c'tor for txn mgr obj
364 * SEE ALSO
365 *
366 */
367void osmv_txnmgr_done(IN osm_bind_handle_t h_bind);
368
369void osmv_txn_lock(IN osm_bind_handle_t h_bind);
370void osmv_txn_unlock(IN osm_bind_handle_t h_bind);
371
372inline static uint64_t osmv_txn_uniq_key(IN uint64_t tid)
373{
374	uint64_t pid = getpid();
375
376	return ((pid << 32) | (tid & 0xFFFFFFFF));
377}
378
379END_C_DECLS
380#endif				/* _OSMV_TXN_H_ */
381