1321936Shselasky/*
2321936Shselasky * Copyright (c) 2010-2014 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 <endian.h>
31321936Shselasky#include <stdio.h>
32321936Shselasky#include <stdlib.h>
33321936Shselasky#include <string.h>
34321936Shselasky#include <netdb.h>
35321936Shselasky#include <errno.h>
36321936Shselasky#include <getopt.h>
37321936Shselasky#include <ctype.h>
38321936Shselasky#include <rdma/rdma_cma.h>
39321936Shselasky#include <rdma/rdma_verbs.h>
40321936Shselasky
41321936Shselaskystatic const char *server = "127.0.0.1";
42321936Shselaskystatic char port[6] = "7471";
43321936Shselasky
44321936Shselaskystatic struct rdma_cm_id *id;
45321936Shselaskystatic struct ibv_mr *mr;
46321936Shselaskystatic struct rdma_addrinfo hints;
47321936Shselasky
48321936Shselaskystatic uint8_t send_msg[16];
49321936Shselaskystatic uint32_t srqn;
50321936Shselasky
51321936Shselaskystatic int post_send(void)
52321936Shselasky{
53321936Shselasky	struct ibv_send_wr wr, *bad;
54321936Shselasky	struct ibv_sge sge;
55321936Shselasky	int ret;
56321936Shselasky
57321936Shselasky	sge.addr = (uint64_t) (uintptr_t) send_msg;
58321936Shselasky	sge.length = (uint32_t) sizeof send_msg;
59321936Shselasky	sge.lkey = 0;
60321936Shselasky	wr.wr_id = (uintptr_t) NULL;
61321936Shselasky	wr.next = NULL;
62321936Shselasky	wr.sg_list = &sge;
63321936Shselasky	wr.num_sge = 1;
64321936Shselasky	wr.opcode = IBV_WR_SEND;
65321936Shselasky	wr.send_flags = IBV_SEND_INLINE;
66321936Shselasky	if (hints.ai_qp_type == IBV_QPT_XRC_SEND)
67321936Shselasky		wr.qp_type.xrc.remote_srqn = srqn;
68321936Shselasky
69321936Shselasky	ret = ibv_post_send(id->qp, &wr, &bad);
70321936Shselasky	if (ret)
71321936Shselasky		perror("rdma_post_send");
72321936Shselasky
73321936Shselasky	return ret;
74321936Shselasky}
75321936Shselasky
76321936Shselaskystatic int test(void)
77321936Shselasky{
78321936Shselasky	struct rdma_addrinfo *res;
79321936Shselasky	struct ibv_qp_init_attr attr;
80321936Shselasky	struct ibv_wc wc;
81321936Shselasky	int ret;
82321936Shselasky
83321936Shselasky	ret = rdma_getaddrinfo(server, port, &hints, &res);
84321936Shselasky	if (ret) {
85321936Shselasky		printf("rdma_getaddrinfo: %s\n", gai_strerror(ret));
86321936Shselasky		return ret;
87321936Shselasky	}
88321936Shselasky
89321936Shselasky	memset(&attr, 0, sizeof attr);
90321936Shselasky	attr.cap.max_send_wr = attr.cap.max_recv_wr = 1;
91321936Shselasky	attr.cap.max_send_sge = attr.cap.max_recv_sge = 1;
92321936Shselasky	attr.sq_sig_all = 1;
93321936Shselasky	ret = rdma_create_ep(&id, res, NULL, &attr);
94321936Shselasky	rdma_freeaddrinfo(res);
95321936Shselasky	if (ret) {
96321936Shselasky		perror("rdma_create_ep");
97321936Shselasky		return ret;
98321936Shselasky	}
99321936Shselasky
100321936Shselasky	mr = rdma_reg_msgs(id, send_msg, sizeof send_msg);
101321936Shselasky	if (!mr) {
102321936Shselasky		perror("rdma_reg_msgs");
103321936Shselasky		return ret;
104321936Shselasky	}
105321936Shselasky
106321936Shselasky	ret = rdma_connect(id, NULL);
107321936Shselasky	if (ret) {
108321936Shselasky		perror("rdma_connect");
109321936Shselasky		return ret;
110321936Shselasky	}
111321936Shselasky
112321936Shselasky	if (hints.ai_qp_type == IBV_QPT_XRC_SEND)
113321936Shselasky		srqn = be32toh(*(__be32 *) id->event->param.conn.private_data);
114321936Shselasky
115321936Shselasky	ret = post_send();
116321936Shselasky	if (ret) {
117321936Shselasky		perror("post_send");
118321936Shselasky		return ret;
119321936Shselasky	}
120321936Shselasky
121321936Shselasky	ret = rdma_get_send_comp(id, &wc);
122321936Shselasky	if (ret <= 0) {
123321936Shselasky		perror("rdma_get_recv_comp");
124321936Shselasky		return ret;
125321936Shselasky	}
126321936Shselasky
127321936Shselasky	rdma_disconnect(id);
128321936Shselasky	rdma_dereg_mr(mr);
129321936Shselasky	rdma_destroy_ep(id);
130321936Shselasky	return 0;
131321936Shselasky}
132321936Shselasky
133321936Shselaskyint main(int argc, char **argv)
134321936Shselasky{
135321936Shselasky	int op, ret;
136321936Shselasky
137321936Shselasky	hints.ai_port_space = RDMA_PS_TCP;
138321936Shselasky	hints.ai_qp_type = IBV_QPT_RC;
139321936Shselasky
140321936Shselasky	while ((op = getopt(argc, argv, "s:p:c:")) != -1) {
141321936Shselasky		switch (op) {
142321936Shselasky		case 's':
143321936Shselasky			server = optarg;
144321936Shselasky			break;
145321936Shselasky		case 'p':
146321936Shselasky			strncpy(port, optarg, sizeof port - 1);
147321936Shselasky			break;
148321936Shselasky		case 'c':
149321936Shselasky			switch (tolower(optarg[0])) {
150321936Shselasky			case 'r':
151321936Shselasky				break;
152321936Shselasky			case 'x':
153321936Shselasky				hints.ai_port_space = RDMA_PS_IB;
154321936Shselasky				hints.ai_qp_type = IBV_QPT_XRC_SEND;
155321936Shselasky				break;
156321936Shselasky			default:
157321936Shselasky				goto err;
158321936Shselasky			}
159321936Shselasky			break;
160321936Shselasky		default:
161321936Shselasky			goto err;
162321936Shselasky		}
163321936Shselasky	}
164321936Shselasky
165321936Shselasky	printf("%s: start\n", argv[0]);
166321936Shselasky	ret = test();
167321936Shselasky	printf("%s: end %d\n", argv[0], ret);
168321936Shselasky	return ret;
169321936Shselasky
170321936Shselaskyerr:
171321936Shselasky	printf("usage: %s\n", argv[0]);
172321936Shselasky	printf("\t[-s server]\n");
173321936Shselasky	printf("\t[-p port_number]\n");
174321936Shselasky	printf("\t[-c communication type]\n");
175321936Shselasky	printf("\t    r - RC: reliable-connected (default)\n");
176321936Shselasky	printf("\t    x - XRC: extended-reliable-connected\n");
177321936Shselasky	exit(1);
178321936Shselasky}
179