1321936Shselasky/*
2321936Shselasky * Copyright (c) 2010 Intel Corporation.  All rights reserved.
3321936Shselasky *
4321936Shselasky * This software is available to you under the OpenIB.org BSD license
5321936Shselasky * below:
6321936Shselasky *
7321936Shselasky *     Redistribution and use in source and binary forms, with or
8321936Shselasky *     without modification, are permitted provided that the following
9321936Shselasky *     conditions are met:
10321936Shselasky *
11321936Shselasky *      - Redistributions of source code must retain the above
12321936Shselasky *        copyright notice, this list of conditions and the following
13321936Shselasky *        disclaimer.
14321936Shselasky *
15321936Shselasky *      - Redistributions in binary form must reproduce the above
16321936Shselasky *        copyright notice, this list of conditions and the following
17321936Shselasky *        disclaimer in the documentation and/or other materials
18321936Shselasky *        provided with the distribution.
19321936Shselasky *
20321936Shselasky * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21321936Shselasky * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22321936Shselasky * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV
23321936Shselasky * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
24321936Shselasky * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25321936Shselasky * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26321936Shselasky * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27321936Shselasky * SOFTWARE.
28321936Shselasky */
29321936Shselasky
30321936Shselasky#include <stdio.h>
31321936Shselasky#include <stdlib.h>
32321936Shselasky#include <string.h>
33321936Shselasky#include <netdb.h>
34321936Shselasky#include <errno.h>
35321936Shselasky#include <getopt.h>
36321936Shselasky#include <rdma/rdma_cma.h>
37321936Shselasky#include <rdma/rdma_verbs.h>
38321936Shselasky
39321936Shselaskystatic const char *server = "127.0.0.1";
40321936Shselaskystatic const char *port = "7471";
41321936Shselasky
42321936Shselaskystatic struct rdma_cm_id *id;
43321936Shselaskystatic struct ibv_mr *mr, *send_mr;
44321936Shselaskystatic int send_flags;
45321936Shselaskystatic uint8_t send_msg[16];
46321936Shselaskystatic uint8_t recv_msg[16];
47321936Shselasky
48321936Shselaskystatic int run(void)
49321936Shselasky{
50321936Shselasky	struct rdma_addrinfo hints, *res;
51321936Shselasky	struct ibv_qp_init_attr attr;
52321936Shselasky	struct ibv_wc wc;
53321936Shselasky	int ret;
54321936Shselasky
55321936Shselasky	memset(&hints, 0, sizeof hints);
56321936Shselasky	hints.ai_port_space = RDMA_PS_TCP;
57321936Shselasky	ret = rdma_getaddrinfo(server, port, &hints, &res);
58321936Shselasky	if (ret) {
59321936Shselasky		printf("rdma_getaddrinfo: %s\n", gai_strerror(ret));
60321936Shselasky		goto out;
61321936Shselasky	}
62321936Shselasky
63321936Shselasky	memset(&attr, 0, sizeof attr);
64321936Shselasky	attr.cap.max_send_wr = attr.cap.max_recv_wr = 1;
65321936Shselasky	attr.cap.max_send_sge = attr.cap.max_recv_sge = 1;
66321936Shselasky	attr.cap.max_inline_data = 16;
67321936Shselasky	attr.qp_context = id;
68321936Shselasky	attr.sq_sig_all = 1;
69321936Shselasky	ret = rdma_create_ep(&id, res, NULL, &attr);
70321936Shselasky	// Check to see if we got inline data allowed or not
71321936Shselasky	if (attr.cap.max_inline_data >= 16)
72321936Shselasky		send_flags = IBV_SEND_INLINE;
73321936Shselasky	else
74321936Shselasky		printf("rdma_client: device doesn't support IBV_SEND_INLINE, "
75321936Shselasky		       "using sge sends\n");
76321936Shselasky
77321936Shselasky	if (ret) {
78321936Shselasky		perror("rdma_create_ep");
79321936Shselasky		goto out_free_addrinfo;
80321936Shselasky	}
81321936Shselasky
82321936Shselasky	mr = rdma_reg_msgs(id, recv_msg, 16);
83321936Shselasky	if (!mr) {
84321936Shselasky		perror("rdma_reg_msgs for recv_msg");
85321936Shselasky		ret = -1;
86321936Shselasky		goto out_destroy_ep;
87321936Shselasky	}
88321936Shselasky	if ((send_flags & IBV_SEND_INLINE) == 0) {
89321936Shselasky		send_mr = rdma_reg_msgs(id, send_msg, 16);
90321936Shselasky		if (!send_mr) {
91321936Shselasky			perror("rdma_reg_msgs for send_msg");
92321936Shselasky			ret = -1;
93321936Shselasky			goto out_dereg_recv;
94321936Shselasky		}
95321936Shselasky	}
96321936Shselasky
97321936Shselasky	ret = rdma_post_recv(id, NULL, recv_msg, 16, mr);
98321936Shselasky	if (ret) {
99321936Shselasky		perror("rdma_post_recv");
100321936Shselasky		goto out_dereg_send;
101321936Shselasky	}
102321936Shselasky
103321936Shselasky	ret = rdma_connect(id, NULL);
104321936Shselasky	if (ret) {
105321936Shselasky		perror("rdma_connect");
106321936Shselasky		goto out_dereg_send;
107321936Shselasky	}
108321936Shselasky
109321936Shselasky	ret = rdma_post_send(id, NULL, send_msg, 16, send_mr, send_flags);
110321936Shselasky	if (ret) {
111321936Shselasky		perror("rdma_post_send");
112321936Shselasky		goto out_disconnect;
113321936Shselasky	}
114321936Shselasky
115321936Shselasky	while ((ret = rdma_get_send_comp(id, &wc)) == 0);
116321936Shselasky	if (ret < 0) {
117321936Shselasky		perror("rdma_get_send_comp");
118321936Shselasky		goto out_disconnect;
119321936Shselasky	}
120321936Shselasky
121321936Shselasky	while ((ret = rdma_get_recv_comp(id, &wc)) == 0);
122321936Shselasky	if (ret < 0)
123321936Shselasky		perror("rdma_get_recv_comp");
124321936Shselasky	else
125321936Shselasky		ret = 0;
126321936Shselasky
127321936Shselaskyout_disconnect:
128321936Shselasky	rdma_disconnect(id);
129321936Shselaskyout_dereg_send:
130321936Shselasky	if ((send_flags & IBV_SEND_INLINE) == 0)
131321936Shselasky		rdma_dereg_mr(send_mr);
132321936Shselaskyout_dereg_recv:
133321936Shselasky	rdma_dereg_mr(mr);
134321936Shselaskyout_destroy_ep:
135321936Shselasky	rdma_destroy_ep(id);
136321936Shselaskyout_free_addrinfo:
137321936Shselasky	rdma_freeaddrinfo(res);
138321936Shselaskyout:
139321936Shselasky	return ret;
140321936Shselasky}
141321936Shselasky
142321936Shselaskyint main(int argc, char **argv)
143321936Shselasky{
144321936Shselasky	int op, ret;
145321936Shselasky
146321936Shselasky	while ((op = getopt(argc, argv, "s:p:")) != -1) {
147321936Shselasky		switch (op) {
148321936Shselasky		case 's':
149321936Shselasky			server = optarg;
150321936Shselasky			break;
151321936Shselasky		case 'p':
152321936Shselasky			port = optarg;
153321936Shselasky			break;
154321936Shselasky		default:
155321936Shselasky			printf("usage: %s\n", argv[0]);
156321936Shselasky			printf("\t[-s server_address]\n");
157321936Shselasky			printf("\t[-p port_number]\n");
158321936Shselasky			exit(1);
159321936Shselasky		}
160321936Shselasky	}
161321936Shselasky
162321936Shselasky	printf("rdma_client: start\n");
163321936Shselasky	ret = run();
164321936Shselasky	printf("rdma_client: end %d\n", ret);
165321936Shselasky	return ret;
166321936Shselasky}
167