1219820Sjeff/*
2219820Sjeff * Copyright (c) 2005 Voltaire Inc.  All rights reserved.
3219820Sjeff * Copyright (c) 2005-2007 Intel Corporation.  All rights reserved.
4219820Sjeff *
5219820Sjeff * This software is available to you under a choice of one of two
6219820Sjeff * licenses.  You may choose to be licensed under the terms of the GNU
7219820Sjeff * General Public License (GPL) Version 2, available from the file
8219820Sjeff * COPYING in the main directory of this source tree, or the
9219820Sjeff * OpenIB.org BSD license below:
10219820Sjeff *
11219820Sjeff *     Redistribution and use in source and binary forms, with or
12219820Sjeff *     without modification, are permitted provided that the following
13219820Sjeff *     conditions are met:
14219820Sjeff *
15219820Sjeff *      - Redistributions of source code must retain the above
16219820Sjeff *        copyright notice, this list of conditions and the following
17219820Sjeff *        disclaimer.
18219820Sjeff *
19219820Sjeff *      - Redistributions in binary form must reproduce the above
20219820Sjeff *        copyright notice, this list of conditions and the following
21219820Sjeff *        disclaimer in the documentation and/or other materials
22219820Sjeff *        provided with the distribution.
23219820Sjeff *
24219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31219820Sjeff * SOFTWARE.
32219820Sjeff */
33219820Sjeff
34219820Sjeff#if !defined(RDMA_CMA_H)
35219820Sjeff#define RDMA_CMA_H
36219820Sjeff
37219820Sjeff#include <netinet/in.h>
38219820Sjeff#include <sys/socket.h>
39219820Sjeff#include <infiniband/verbs.h>
40219820Sjeff#include <infiniband/sa.h>
41219820Sjeff
42219820Sjeff#ifdef __cplusplus
43219820Sjeffextern "C" {
44219820Sjeff#endif
45219820Sjeff
46219820Sjeff/*
47219820Sjeff * Upon receiving a device removal event, users must destroy the associated
48219820Sjeff * RDMA identifier and release all resources allocated with the device.
49219820Sjeff */
50219820Sjeffenum rdma_cm_event_type {
51219820Sjeff	RDMA_CM_EVENT_ADDR_RESOLVED,
52219820Sjeff	RDMA_CM_EVENT_ADDR_ERROR,
53219820Sjeff	RDMA_CM_EVENT_ROUTE_RESOLVED,
54219820Sjeff	RDMA_CM_EVENT_ROUTE_ERROR,
55219820Sjeff	RDMA_CM_EVENT_CONNECT_REQUEST,
56219820Sjeff	RDMA_CM_EVENT_CONNECT_RESPONSE,
57219820Sjeff	RDMA_CM_EVENT_CONNECT_ERROR,
58219820Sjeff	RDMA_CM_EVENT_UNREACHABLE,
59219820Sjeff	RDMA_CM_EVENT_REJECTED,
60219820Sjeff	RDMA_CM_EVENT_ESTABLISHED,
61219820Sjeff	RDMA_CM_EVENT_DISCONNECTED,
62219820Sjeff	RDMA_CM_EVENT_DEVICE_REMOVAL,
63219820Sjeff	RDMA_CM_EVENT_MULTICAST_JOIN,
64219820Sjeff	RDMA_CM_EVENT_MULTICAST_ERROR,
65219820Sjeff	RDMA_CM_EVENT_ADDR_CHANGE,
66219820Sjeff	RDMA_CM_EVENT_TIMEWAIT_EXIT
67219820Sjeff};
68219820Sjeff
69219820Sjeffenum rdma_port_space {
70219820Sjeff	RDMA_PS_IPOIB= 0x0002,
71219820Sjeff	RDMA_PS_TCP  = 0x0106,
72219820Sjeff	RDMA_PS_UDP  = 0x0111,
73219820Sjeff};
74219820Sjeff
75219820Sjeff/*
76219820Sjeff * Global qkey value for UDP QPs and multicast groups created via the
77219820Sjeff * RDMA CM.
78219820Sjeff */
79219820Sjeff#define RDMA_UDP_QKEY 0x01234567
80219820Sjeff
81219820Sjeffstruct ib_addr {
82219820Sjeff	union ibv_gid	sgid;
83219820Sjeff	union ibv_gid	dgid;
84219820Sjeff	uint16_t	pkey;
85219820Sjeff};
86219820Sjeff
87219820Sjeffstruct rdma_addr {
88219820Sjeff	struct sockaddr		src_addr;
89219820Sjeff	uint8_t			src_pad[sizeof(struct sockaddr_storage) -
90219820Sjeff					sizeof(struct sockaddr)];
91219820Sjeff	struct sockaddr		dst_addr;
92219820Sjeff	uint8_t			dst_pad[sizeof(struct sockaddr_storage) -
93219820Sjeff					sizeof(struct sockaddr)];
94219820Sjeff	union {
95219820Sjeff		struct ib_addr	ibaddr;
96219820Sjeff	} addr;
97219820Sjeff};
98219820Sjeff
99219820Sjeffstruct rdma_route {
100219820Sjeff	struct rdma_addr	 addr;
101219820Sjeff	struct ibv_sa_path_rec	*path_rec;
102219820Sjeff	int			 num_paths;
103219820Sjeff};
104219820Sjeff
105219820Sjeffstruct rdma_event_channel {
106219820Sjeff	int			fd;
107219820Sjeff};
108219820Sjeff
109219820Sjeffstruct rdma_cm_id {
110219820Sjeff	struct ibv_context	*verbs;
111219820Sjeff	struct rdma_event_channel *channel;
112219820Sjeff	void			*context;
113219820Sjeff	struct ibv_qp		*qp;
114219820Sjeff	struct rdma_route	 route;
115219820Sjeff	enum rdma_port_space	 ps;
116219820Sjeff	uint8_t			 port_num;
117219820Sjeff};
118219820Sjeff
119219820Sjeffstruct rdma_conn_param {
120219820Sjeff	const void *private_data;
121219820Sjeff	uint8_t private_data_len;
122219820Sjeff	uint8_t responder_resources;
123219820Sjeff	uint8_t initiator_depth;
124219820Sjeff	uint8_t flow_control;
125219820Sjeff	uint8_t retry_count;		/* ignored when accepting */
126219820Sjeff	uint8_t rnr_retry_count;
127219820Sjeff	/* Fields below ignored if a QP is created on the rdma_cm_id. */
128219820Sjeff	uint8_t srq;
129219820Sjeff	uint32_t qp_num;
130219820Sjeff};
131219820Sjeff
132219820Sjeffstruct rdma_ud_param {
133219820Sjeff	const void *private_data;
134219820Sjeff	uint8_t private_data_len;
135219820Sjeff	struct ibv_ah_attr ah_attr;
136219820Sjeff	uint32_t qp_num;
137219820Sjeff	uint32_t qkey;
138219820Sjeff};
139219820Sjeff
140219820Sjeffstruct rdma_cm_event {
141219820Sjeff	struct rdma_cm_id	*id;
142219820Sjeff	struct rdma_cm_id	*listen_id;
143219820Sjeff	enum rdma_cm_event_type	 event;
144219820Sjeff	int			 status;
145219820Sjeff	union {
146219820Sjeff		struct rdma_conn_param conn;
147219820Sjeff		struct rdma_ud_param   ud;
148219820Sjeff	} param;
149219820Sjeff};
150219820Sjeff
151219820Sjeff/**
152219820Sjeff * rdma_create_event_channel - Open a channel used to report communication events.
153219820Sjeff * Description:
154219820Sjeff *   Asynchronous events are reported to users through event channels.  Each
155219820Sjeff *   event channel maps to a file descriptor.
156219820Sjeff * Notes:
157219820Sjeff *   All created event channels must be destroyed by calling
158219820Sjeff *   rdma_destroy_event_channel.  Users should call rdma_get_cm_event to
159219820Sjeff *   retrieve events on an event channel.
160219820Sjeff * See also:
161219820Sjeff *   rdma_get_cm_event, rdma_destroy_event_channel
162219820Sjeff */
163219820Sjeffstruct rdma_event_channel *rdma_create_event_channel(void);
164219820Sjeff
165219820Sjeff/**
166219820Sjeff * rdma_destroy_event_channel - Close an event communication channel.
167219820Sjeff * @channel: The communication channel to destroy.
168219820Sjeff * Description:
169219820Sjeff *   Release all resources associated with an event channel and closes the
170219820Sjeff *   associated file descriptor.
171219820Sjeff * Notes:
172219820Sjeff *   All rdma_cm_id's associated with the event channel must be destroyed,
173219820Sjeff *   and all returned events must be acked before calling this function.
174219820Sjeff * See also:
175219820Sjeff *  rdma_create_event_channel, rdma_get_cm_event, rdma_ack_cm_event
176219820Sjeff */
177219820Sjeffvoid rdma_destroy_event_channel(struct rdma_event_channel *channel);
178219820Sjeff
179219820Sjeff/**
180219820Sjeff * rdma_create_id - Allocate a communication identifier.
181219820Sjeff * @channel: The communication channel that events associated with the
182219820Sjeff *   allocated rdma_cm_id will be reported on.
183219820Sjeff * @id: A reference where the allocated communication identifier will be
184219820Sjeff *   returned.
185219820Sjeff * @context: User specified context associated with the rdma_cm_id.
186219820Sjeff * @ps: RDMA port space.
187219820Sjeff * Description:
188219820Sjeff *   Creates an identifier that is used to track communication information.
189219820Sjeff * Notes:
190219820Sjeff *   Rdma_cm_id's are conceptually equivalent to a socket for RDMA
191219820Sjeff *   communication.  The difference is that RDMA communication requires
192219820Sjeff *   explicitly binding to a specified RDMA device before communication
193219820Sjeff *   can occur, and most operations are asynchronous in nature.  Communication
194219820Sjeff *   events on an rdma_cm_id are reported through the associated event
195219820Sjeff *   channel.  Users must release the rdma_cm_id by calling rdma_destroy_id.
196219820Sjeff * See also:
197219820Sjeff *   rdma_create_event_channel, rdma_destroy_id, rdma_get_devices,
198219820Sjeff *   rdma_bind_addr, rdma_resolve_addr, rdma_connect, rdma_listen,
199219820Sjeff */
200219820Sjeffint rdma_create_id(struct rdma_event_channel *channel,
201219820Sjeff		   struct rdma_cm_id **id, void *context,
202219820Sjeff		   enum rdma_port_space ps);
203219820Sjeff
204219820Sjeff/**
205219820Sjeff * rdma_destroy_id - Release a communication identifier.
206219820Sjeff * @id: The communication identifier to destroy.
207219820Sjeff * Description:
208219820Sjeff *   Destroys the specified rdma_cm_id and cancels any outstanding
209219820Sjeff *   asynchronous operation.
210219820Sjeff * Notes:
211219820Sjeff *   Users must free any associated QP with the rdma_cm_id before
212219820Sjeff *   calling this routine and ack an related events.
213219820Sjeff * See also:
214219820Sjeff *   rdma_create_id, rdma_destroy_qp, rdma_ack_cm_event
215219820Sjeff */
216219820Sjeffint rdma_destroy_id(struct rdma_cm_id *id);
217219820Sjeff
218219820Sjeff/**
219219820Sjeff * rdma_bind_addr - Bind an RDMA identifier to a source address.
220219820Sjeff * @id: RDMA identifier.
221219820Sjeff * @addr: Local address information.  Wildcard values are permitted.
222219820Sjeff * Description:
223219820Sjeff *   Associates a source address with an rdma_cm_id.  The address may be
224219820Sjeff *   wildcarded.  If binding to a specific local address, the rdma_cm_id
225219820Sjeff *   will also be bound to a local RDMA device.
226219820Sjeff * Notes:
227219820Sjeff *   Typically, this routine is called before calling rdma_listen to bind
228219820Sjeff *   to a specific port number, but it may also be called on the active side
229219820Sjeff *   of a connection before calling rdma_resolve_addr to bind to a specific
230219820Sjeff *   address.
231219820Sjeff * See also:
232219820Sjeff *   rdma_create_id, rdma_listen, rdma_resolve_addr, rdma_create_qp
233219820Sjeff */
234219820Sjeffint rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr);
235219820Sjeff
236219820Sjeff/**
237219820Sjeff * rdma_resolve_addr - Resolve destination and optional source addresses.
238219820Sjeff * @id: RDMA identifier.
239219820Sjeff * @src_addr: Source address information.  This parameter may be NULL.
240219820Sjeff * @dst_addr: Destination address information.
241219820Sjeff * @timeout_ms: Time to wait for resolution to complete.
242219820Sjeff * Description:
243219820Sjeff *   Resolve destination and optional source addresses from IP addresses
244219820Sjeff *   to an RDMA address.  If successful, the specified rdma_cm_id will
245219820Sjeff *   be bound to a local device.
246219820Sjeff * Notes:
247219820Sjeff *   This call is used to map a given destination IP address to a usable RDMA
248219820Sjeff *   address.  If a source address is given, the rdma_cm_id is bound to that
249219820Sjeff *   address, the same as if rdma_bind_addr were called.  If no source
250219820Sjeff *   address is given, and the rdma_cm_id has not yet been bound to a device,
251219820Sjeff *   then the rdma_cm_id will be bound to a source address based on the
252219820Sjeff *   local routing tables.  After this call, the rdma_cm_id will be bound to
253219820Sjeff *   an RDMA device.  This call is typically made from the active side of a
254219820Sjeff *   connection before calling rdma_resolve_route and rdma_connect.
255219820Sjeff * See also:
256219820Sjeff *   rdma_create_id, rdma_resolve_route, rdma_connect, rdma_create_qp,
257219820Sjeff *   rdma_get_cm_event, rdma_bind_addr
258219820Sjeff */
259219820Sjeffint rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
260219820Sjeff		      struct sockaddr *dst_addr, int timeout_ms);
261219820Sjeff
262219820Sjeff/**
263219820Sjeff * rdma_resolve_route - Resolve the route information needed to establish a connection.
264219820Sjeff * @id: RDMA identifier.
265219820Sjeff * @timeout_ms: Time to wait for resolution to complete.
266219820Sjeff * Description:
267219820Sjeff *   Resolves an RDMA route to the destination address in order to establish
268219820Sjeff *   a connection.  The destination address must have already been resolved
269219820Sjeff *   by calling rdma_resolve_addr.
270219820Sjeff * Notes:
271219820Sjeff *   This is called on the client side of a connection after calling
272219820Sjeff *   rdma_resolve_addr, but before calling rdma_connect.
273219820Sjeff * See also:
274219820Sjeff *   rdma_resolve_addr, rdma_connect, rdma_get_cm_event
275219820Sjeff */
276219820Sjeffint rdma_resolve_route(struct rdma_cm_id *id, int timeout_ms);
277219820Sjeff
278219820Sjeff/**
279219820Sjeff * rdma_create_qp - Allocate a QP.
280219820Sjeff * @id: RDMA identifier.
281219820Sjeff * @pd: protection domain for the QP.
282219820Sjeff * @qp_init_attr: initial QP attributes.
283219820Sjeff * Description:
284219820Sjeff *  Allocate a QP associated with the specified rdma_cm_id and transition it
285219820Sjeff *  for sending and receiving.
286219820Sjeff * Notes:
287219820Sjeff *   The rdma_cm_id must be bound to a local RDMA device before calling this
288219820Sjeff *   function, and the protection domain must be for that same device.
289219820Sjeff *   QPs allocated to an rdma_cm_id are automatically transitioned by the
290219820Sjeff *   librdmacm through their states.  After being allocated, the QP will be
291219820Sjeff *   ready to handle posting of receives.  If the QP is unconnected, it will
292219820Sjeff *   be ready to post sends.
293219820Sjeff * See also:
294219820Sjeff *   rdma_bind_addr, rdma_resolve_addr, rdma_destroy_qp, ibv_create_qp,
295219820Sjeff *   ibv_modify_qp
296219820Sjeff */
297219820Sjeffint rdma_create_qp(struct rdma_cm_id *id, struct ibv_pd *pd,
298219820Sjeff		   struct ibv_qp_init_attr *qp_init_attr);
299219820Sjeff
300219820Sjeff/**
301219820Sjeff * rdma_destroy_qp - Deallocate a QP.
302219820Sjeff * @id: RDMA identifier.
303219820Sjeff * Description:
304219820Sjeff *   Destroy a QP allocated on the rdma_cm_id.
305219820Sjeff * Notes:
306219820Sjeff *   Users must destroy any QP associated with an rdma_cm_id before
307219820Sjeff *   destroying the ID.
308219820Sjeff * See also:
309219820Sjeff *   rdma_create_qp, rdma_destroy_id, ibv_destroy_qp
310219820Sjeff */
311219820Sjeffvoid rdma_destroy_qp(struct rdma_cm_id *id);
312219820Sjeff
313219820Sjeff/**
314219820Sjeff * rdma_connect - Initiate an active connection request.
315219820Sjeff * @id: RDMA identifier.
316219820Sjeff * @conn_param: connection parameters.
317219820Sjeff * Description:
318219820Sjeff *   For a connected rdma_cm_id, this call initiates a connection request
319219820Sjeff *   to a remote destination.  For an unconnected rdma_cm_id, it initiates
320219820Sjeff *   a lookup of the remote QP providing the datagram service.
321219820Sjeff * Notes:
322219820Sjeff *   Users must have resolved a route to the destination address
323219820Sjeff *   by having called rdma_resolve_route before calling this routine.
324219820Sjeff * See also:
325219820Sjeff *   rdma_resolve_route, rdma_disconnect, rdma_listen, rdma_get_cm_event
326219820Sjeff */
327219820Sjeffint rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param);
328219820Sjeff
329219820Sjeff/**
330219820Sjeff * rdma_listen - Listen for incoming connection requests.
331219820Sjeff * @id: RDMA identifier.
332219820Sjeff * @backlog: backlog of incoming connection requests.
333219820Sjeff * Description:
334219820Sjeff *   Initiates a listen for incoming connection requests or datagram service
335219820Sjeff *   lookup.  The listen will be restricted to the locally bound source
336219820Sjeff *   address.
337219820Sjeff * Notes:
338219820Sjeff *   Users must have bound the rdma_cm_id to a local address by calling
339219820Sjeff *   rdma_bind_addr before calling this routine.  If the rdma_cm_id is
340219820Sjeff *   bound to a specific IP address, the listen will be restricted to that
341219820Sjeff *   address and the associated RDMA device.  If the rdma_cm_id is bound
342219820Sjeff *   to an RDMA port number only, the listen will occur across all RDMA
343219820Sjeff *   devices.
344219820Sjeff * See also:
345219820Sjeff *   rdma_bind_addr, rdma_connect, rdma_accept, rdma_reject, rdma_get_cm_event
346219820Sjeff */
347219820Sjeffint rdma_listen(struct rdma_cm_id *id, int backlog);
348219820Sjeff
349219820Sjeff/**
350219820Sjeff * rdma_accept - Called to accept a connection request.
351219820Sjeff * @id: Connection identifier associated with the request.
352219820Sjeff * @conn_param: Information needed to establish the connection.
353219820Sjeff * Description:
354219820Sjeff *   Called from the listening side to accept a connection or datagram
355219820Sjeff *   service lookup request.
356219820Sjeff * Notes:
357219820Sjeff *   Unlike the socket accept routine, rdma_accept is not called on a
358219820Sjeff *   listening rdma_cm_id.  Instead, after calling rdma_listen, the user
359219820Sjeff *   waits for a connection request event to occur.  Connection request
360219820Sjeff *   events give the user a newly created rdma_cm_id, similar to a new
361219820Sjeff *   socket, but the rdma_cm_id is bound to a specific RDMA device.
362219820Sjeff *   rdma_accept is called on the new rdma_cm_id.
363219820Sjeff * See also:
364219820Sjeff *   rdma_listen, rdma_reject, rdma_get_cm_event
365219820Sjeff */
366219820Sjeffint rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param);
367219820Sjeff
368219820Sjeff/**
369219820Sjeff * rdma_reject - Called to reject a connection request.
370219820Sjeff * @id: Connection identifier associated with the request.
371219820Sjeff * @private_data: Optional private data to send with the reject message.
372219820Sjeff * @private_data_len: Size of the private_data to send, in bytes.
373219820Sjeff * Description:
374219820Sjeff *   Called from the listening side to reject a connection or datagram
375219820Sjeff *   service lookup request.
376219820Sjeff * Notes:
377219820Sjeff *   After receiving a connection request event, a user may call rdma_reject
378219820Sjeff *   to reject the request.  If the underlying RDMA transport supports
379219820Sjeff *   private data in the reject message, the specified data will be passed to
380219820Sjeff *   the remote side.
381219820Sjeff * See also:
382219820Sjeff *   rdma_listen, rdma_accept, rdma_get_cm_event
383219820Sjeff */
384219820Sjeffint rdma_reject(struct rdma_cm_id *id, const void *private_data,
385219820Sjeff		uint8_t private_data_len);
386219820Sjeff
387219820Sjeff/**
388219820Sjeff * rdma_notify - Notifies the librdmacm of an asynchronous event.
389219820Sjeff * @id: RDMA identifier.
390219820Sjeff * @event: Asynchronous event.
391219820Sjeff * Description:
392219820Sjeff *   Used to notify the librdmacm of asynchronous events that have occurred
393219820Sjeff *   on a QP associated with the rdma_cm_id.
394219820Sjeff * Notes:
395219820Sjeff *   Asynchronous events that occur on a QP are reported through the user's
396219820Sjeff *   device event handler.  This routine is used to notify the librdmacm of
397219820Sjeff *   communication events.  In most cases, use of this routine is not
398219820Sjeff *   necessary, however if connection establishment is done out of band
399219820Sjeff *   (such as done through Infiniband), it's possible to receive data on a
400219820Sjeff *   QP that is not yet considered connected.  This routine forces the
401219820Sjeff *   connection into an established state in this case in order to handle
402219820Sjeff *   the rare situation where the connection never forms on its own.
403219820Sjeff *   Events that should be reported to the CM are: IB_EVENT_COMM_EST.
404219820Sjeff * See also:
405219820Sjeff *   rdma_connect, rdma_accept, rdma_listen
406219820Sjeff */
407219820Sjeffint rdma_notify(struct rdma_cm_id *id, enum ibv_event_type event);
408219820Sjeff
409219820Sjeff/**
410219820Sjeff * rdma_disconnect - This function disconnects a connection.
411219820Sjeff * @id: RDMA identifier.
412219820Sjeff * Description:
413219820Sjeff *   Disconnects a connection and transitions any associated QP to the
414219820Sjeff *   error state.
415219820Sjeff * See also:
416219820Sjeff *   rdma_connect, rdma_listen, rdma_accept
417219820Sjeff */
418219820Sjeffint rdma_disconnect(struct rdma_cm_id *id);
419219820Sjeff
420219820Sjeff/**
421219820Sjeff * rdma_join_multicast - Joins a multicast group.
422219820Sjeff * @id: Communication identifier associated with the request.
423219820Sjeff * @addr: Multicast address identifying the group to join.
424219820Sjeff * @context: User-defined context associated with the join request.
425219820Sjeff * Description:
426219820Sjeff *   Joins a multicast group and attaches an associated QP to the group.
427219820Sjeff * Notes:
428219820Sjeff *   Before joining a multicast group, the rdma_cm_id must be bound to
429219820Sjeff *   an RDMA device by calling rdma_bind_addr or rdma_resolve_addr.  Use of
430219820Sjeff *   rdma_resolve_addr requires the local routing tables to resolve the
431219820Sjeff *   multicast address to an RDMA device.  The user must call
432219820Sjeff *   rdma_leave_multicast to leave the multicast group and release any
433219820Sjeff *   multicast resources.  The context is returned to the user through
434219820Sjeff *   the private_data field in the rdma_cm_event.
435219820Sjeff * See also:
436219820Sjeff *   rdma_leave_multicast, rdma_bind_addr, rdma_resolve_addr, rdma_create_qp
437219820Sjeff */
438219820Sjeffint rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,
439219820Sjeff			void *context);
440219820Sjeff
441219820Sjeff/**
442219820Sjeff * rdma_leave_multicast - Leaves a multicast group.
443219820Sjeff * @id: Communication identifier associated with the request.
444219820Sjeff * @addr: Multicast address identifying the group to leave.
445219820Sjeff * Description:
446219820Sjeff *   Leaves a multicast group and detaches an associated QP from the group.
447219820Sjeff * Notes:
448219820Sjeff *   Calling this function before a group has been fully joined results in
449219820Sjeff *   canceling the join operation.  Users should be aware that messages
450219820Sjeff *   received from the multicast group may stilled be queued for
451219820Sjeff *   completion processing immediately after leaving a multicast group.
452219820Sjeff *   Destroying an rdma_cm_id will automatically leave all multicast groups.
453219820Sjeff * See also:
454219820Sjeff *   rdma_join_multicast, rdma_destroy_qp
455219820Sjeff */
456219820Sjeffint rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr);
457219820Sjeff
458219820Sjeff/**
459219820Sjeff * rdma_get_cm_event - Retrieves the next pending communication event.
460219820Sjeff * @channel: Event channel to check for events.
461219820Sjeff * @event: Allocated information about the next communication event.
462219820Sjeff * Description:
463219820Sjeff *   Retrieves a communication event.  If no events are pending, by default,
464219820Sjeff *   the call will block until an event is received.
465219820Sjeff * Notes:
466219820Sjeff *   The default synchronous behavior of this routine can be changed by
467219820Sjeff *   modifying the file descriptor associated with the given channel.  All
468219820Sjeff *   events that are reported must be acknowledged by calling rdma_ack_cm_event.
469219820Sjeff *   Destruction of an rdma_cm_id will block until related events have been
470219820Sjeff *   acknowledged.
471219820Sjeff * See also:
472219820Sjeff *   rdma_ack_cm_event, rdma_create_event_channel, rdma_event_str
473219820Sjeff */
474219820Sjeffint rdma_get_cm_event(struct rdma_event_channel *channel,
475219820Sjeff		      struct rdma_cm_event **event);
476219820Sjeff
477219820Sjeff/**
478219820Sjeff * rdma_ack_cm_event - Free a communication event.
479219820Sjeff * @event: Event to be released.
480219820Sjeff * Description:
481219820Sjeff *   All events which are allocated by rdma_get_cm_event must be released,
482219820Sjeff *   there should be a one-to-one correspondence between successful gets
483219820Sjeff *   and acks.
484219820Sjeff * See also:
485219820Sjeff *   rdma_get_cm_event, rdma_destroy_id
486219820Sjeff */
487219820Sjeffint rdma_ack_cm_event(struct rdma_cm_event *event);
488219820Sjeff
489219820Sjeffstatic inline uint16_t rdma_get_src_port(struct rdma_cm_id *id)
490219820Sjeff{
491219820Sjeff	return	id->route.addr.src_addr.sa_family == PF_INET6 ?
492219820Sjeff		((struct sockaddr_in6 *) &id->route.addr.src_addr)->sin6_port :
493219820Sjeff		((struct sockaddr_in *) &id->route.addr.src_addr)->sin_port;
494219820Sjeff}
495219820Sjeff
496219820Sjeffstatic inline uint16_t rdma_get_dst_port(struct rdma_cm_id *id)
497219820Sjeff{
498219820Sjeff	return	id->route.addr.dst_addr.sa_family == PF_INET6 ?
499219820Sjeff		((struct sockaddr_in6 *) &id->route.addr.dst_addr)->sin6_port :
500219820Sjeff		((struct sockaddr_in *) &id->route.addr.dst_addr)->sin_port;
501219820Sjeff}
502219820Sjeff
503219820Sjeffstatic inline struct sockaddr *rdma_get_local_addr(struct rdma_cm_id *id)
504219820Sjeff{
505219820Sjeff	return &id->route.addr.src_addr;
506219820Sjeff}
507219820Sjeff
508219820Sjeffstatic inline struct sockaddr *rdma_get_peer_addr(struct rdma_cm_id *id)
509219820Sjeff{
510219820Sjeff	return &id->route.addr.dst_addr;
511219820Sjeff}
512219820Sjeff
513219820Sjeff/**
514219820Sjeff * rdma_get_devices - Get list of RDMA devices currently available.
515219820Sjeff * @num_devices: If non-NULL, set to the number of devices returned.
516219820Sjeff * Description:
517219820Sjeff *   Return a NULL-terminated array of opened RDMA devices.  Callers can use
518219820Sjeff *   this routine to allocate resources on specific RDMA devices that will be
519219820Sjeff *   shared across multiple rdma_cm_id's.
520219820Sjeff * Notes:
521219820Sjeff *   The returned array must be released by calling rdma_free_devices.  Devices
522219820Sjeff *   remain opened while the librdmacm is loaded.
523219820Sjeff * See also:
524219820Sjeff *   rdma_free_devices
525219820Sjeff */
526219820Sjeffstruct ibv_context **rdma_get_devices(int *num_devices);
527219820Sjeff
528219820Sjeff/**
529219820Sjeff * rdma_free_devices - Frees the list of devices returned by rdma_get_devices.
530219820Sjeff * @list: List of devices returned from rdma_get_devices.
531219820Sjeff * Description:
532219820Sjeff *   Frees the device array returned by rdma_get_devices.
533219820Sjeff * See also:
534219820Sjeff *   rdma_get_devices
535219820Sjeff */
536219820Sjeffvoid rdma_free_devices(struct ibv_context **list);
537219820Sjeff
538219820Sjeff/**
539219820Sjeff * rdma_event_str - Returns a string representation of an rdma cm event.
540219820Sjeff * @event: Asynchronous event.
541219820Sjeff * Description:
542219820Sjeff *   Returns a string representation of an asynchronous event.
543219820Sjeff * See also:
544219820Sjeff *   rdma_get_cm_event
545219820Sjeff */
546219820Sjeffconst char *rdma_event_str(enum rdma_cm_event_type event);
547219820Sjeff
548219820Sjeff/* Option levels */
549219820Sjeffenum {
550219820Sjeff	RDMA_OPTION_ID		= 0
551219820Sjeff};
552219820Sjeff
553219820Sjeff/* Option details */
554219820Sjeffenum {
555219820Sjeff	RDMA_OPTION_ID_TOS	= 0	/* uint8_t: RFC 2474 */
556219820Sjeff};
557219820Sjeff
558219820Sjeff/**
559219820Sjeff * rdma_set_option - Set options for an rdma_cm_id.
560219820Sjeff * @id: Communication identifier to set option for.
561219820Sjeff * @level: Protocol level of the option to set.
562219820Sjeff * @optname: Name of the option to set.
563219820Sjeff * @optval: Reference to the option data.
564219820Sjeff * @optlen: The size of the %optval buffer.
565219820Sjeff */
566219820Sjeffint rdma_set_option(struct rdma_cm_id *id, int level, int optname,
567219820Sjeff		    void *optval, size_t optlen);
568219820Sjeff
569219820Sjeff/**
570219820Sjeff * rdma_migrate_id - Move an rdma_cm_id to a new event channel.
571219820Sjeff * @id: Communication identifier to migrate.
572219820Sjeff * @channel: New event channel for rdma_cm_id events.
573219820Sjeff */
574219820Sjeffint rdma_migrate_id(struct rdma_cm_id *id, struct rdma_event_channel *channel);
575219820Sjeff
576219820Sjeff#ifdef __cplusplus
577219820Sjeff}
578219820Sjeff#endif
579219820Sjeff
580219820Sjeff#endif /* RDMA_CMA_H */
581