xref: /freebsd/contrib/ofed/libcxgb4/verbs.c (revision a687910f)
1d6b92ffaSHans Petter Selasky /*
2d6b92ffaSHans Petter Selasky  * Copyright (c) 2006-2016 Chelsio, Inc. All rights reserved.
3d6b92ffaSHans Petter Selasky  *
4d6b92ffaSHans Petter Selasky  * This software is available to you under a choice of one of two
5d6b92ffaSHans Petter Selasky  * licenses.  You may choose to be licensed under the terms of the GNU
6d6b92ffaSHans Petter Selasky  * General Public License (GPL) Version 2, available from the file
7d6b92ffaSHans Petter Selasky  * COPYING in the main directory of this source tree, or the
8d6b92ffaSHans Petter Selasky  * OpenIB.org BSD license below:
9d6b92ffaSHans Petter Selasky  *
10d6b92ffaSHans Petter Selasky  *     Redistribution and use in source and binary forms, with or
11d6b92ffaSHans Petter Selasky  *     without modification, are permitted provided that the following
12d6b92ffaSHans Petter Selasky  *     conditions are met:
13d6b92ffaSHans Petter Selasky  *
14d6b92ffaSHans Petter Selasky  *      - Redistributions of source code must retain the above
15d6b92ffaSHans Petter Selasky  *        copyright notice, this list of conditions and the following
16d6b92ffaSHans Petter Selasky  *        disclaimer.
17d6b92ffaSHans Petter Selasky  *
18d6b92ffaSHans Petter Selasky  *      - Redistributions in binary form must reproduce the above
19d6b92ffaSHans Petter Selasky  *        copyright notice, this list of conditions and the following
20d6b92ffaSHans Petter Selasky  *        disclaimer in the documentation and/or other materials
21d6b92ffaSHans Petter Selasky  *        provided with the distribution.
22d6b92ffaSHans Petter Selasky  *
23d6b92ffaSHans Petter Selasky  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24d6b92ffaSHans Petter Selasky  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25d6b92ffaSHans Petter Selasky  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26d6b92ffaSHans Petter Selasky  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27d6b92ffaSHans Petter Selasky  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28d6b92ffaSHans Petter Selasky  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29d6b92ffaSHans Petter Selasky  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30d6b92ffaSHans Petter Selasky  * SOFTWARE.
31d6b92ffaSHans Petter Selasky  */
32d6b92ffaSHans Petter Selasky #include <config.h>
33d6b92ffaSHans Petter Selasky 
34d6b92ffaSHans Petter Selasky #include <stdlib.h>
35d6b92ffaSHans Petter Selasky #include <stdio.h>
36d6b92ffaSHans Petter Selasky #include <string.h>
37d6b92ffaSHans Petter Selasky #include <errno.h>
38d6b92ffaSHans Petter Selasky #include <pthread.h>
39d6b92ffaSHans Petter Selasky #include <sys/mman.h>
40d6b92ffaSHans Petter Selasky #include <inttypes.h>
41d6b92ffaSHans Petter Selasky #include <assert.h>
42d6b92ffaSHans Petter Selasky 
43d6b92ffaSHans Petter Selasky #include "libcxgb4.h"
44d6b92ffaSHans Petter Selasky #include "cxgb4-abi.h"
45d6b92ffaSHans Petter Selasky 
46d6b92ffaSHans Petter Selasky #define MASKED(x) (void *)((unsigned long)(x) & c4iw_page_mask)
47d6b92ffaSHans Petter Selasky 
c4iw_query_device(struct ibv_context * context,struct ibv_device_attr * attr)48d6b92ffaSHans Petter Selasky int c4iw_query_device(struct ibv_context *context, struct ibv_device_attr *attr)
49d6b92ffaSHans Petter Selasky {
50d6b92ffaSHans Petter Selasky 	struct ibv_query_device cmd;
51d6b92ffaSHans Petter Selasky 	uint64_t raw_fw_ver;
52d6b92ffaSHans Petter Selasky 	u8 major, minor, sub_minor, build;
53d6b92ffaSHans Petter Selasky 	int ret;
54d6b92ffaSHans Petter Selasky 
55d6b92ffaSHans Petter Selasky 	ret = ibv_cmd_query_device(context, attr, &raw_fw_ver, &cmd,
56d6b92ffaSHans Petter Selasky 				   sizeof cmd);
57d6b92ffaSHans Petter Selasky 	if (ret)
58d6b92ffaSHans Petter Selasky 		return ret;
59d6b92ffaSHans Petter Selasky 
60d6b92ffaSHans Petter Selasky 	major = (raw_fw_ver >> 24) & 0xff;
61d6b92ffaSHans Petter Selasky 	minor = (raw_fw_ver >> 16) & 0xff;
62d6b92ffaSHans Petter Selasky 	sub_minor = (raw_fw_ver >> 8) & 0xff;
63d6b92ffaSHans Petter Selasky 	build = raw_fw_ver & 0xff;
64d6b92ffaSHans Petter Selasky 
65d6b92ffaSHans Petter Selasky 	snprintf(attr->fw_ver, sizeof attr->fw_ver,
66d6b92ffaSHans Petter Selasky 		 "%d.%d.%d.%d", major, minor, sub_minor, build);
67d6b92ffaSHans Petter Selasky 
68d6b92ffaSHans Petter Selasky 	return 0;
69d6b92ffaSHans Petter Selasky }
70d6b92ffaSHans Petter Selasky 
c4iw_query_port(struct ibv_context * context,uint8_t port,struct ibv_port_attr * attr)71d6b92ffaSHans Petter Selasky int c4iw_query_port(struct ibv_context *context, uint8_t port,
72d6b92ffaSHans Petter Selasky 		    struct ibv_port_attr *attr)
73d6b92ffaSHans Petter Selasky {
74d6b92ffaSHans Petter Selasky 	struct ibv_query_port cmd;
75d6b92ffaSHans Petter Selasky 
76d6b92ffaSHans Petter Selasky 	return ibv_cmd_query_port(context, port, attr, &cmd, sizeof cmd);
77d6b92ffaSHans Petter Selasky }
78d6b92ffaSHans Petter Selasky 
c4iw_alloc_pd(struct ibv_context * context)79d6b92ffaSHans Petter Selasky struct ibv_pd *c4iw_alloc_pd(struct ibv_context *context)
80d6b92ffaSHans Petter Selasky {
81d6b92ffaSHans Petter Selasky 	struct ibv_alloc_pd cmd;
82d6b92ffaSHans Petter Selasky 	struct c4iw_alloc_pd_resp resp;
83d6b92ffaSHans Petter Selasky 	struct c4iw_pd *pd;
84d6b92ffaSHans Petter Selasky 
85d6b92ffaSHans Petter Selasky 	pd = malloc(sizeof *pd);
86d6b92ffaSHans Petter Selasky 	if (!pd)
87d6b92ffaSHans Petter Selasky 		return NULL;
88d6b92ffaSHans Petter Selasky 
89d6b92ffaSHans Petter Selasky 	if (ibv_cmd_alloc_pd(context, &pd->ibv_pd, &cmd, sizeof cmd,
90d6b92ffaSHans Petter Selasky 			     &resp.ibv_resp, sizeof resp)) {
91d6b92ffaSHans Petter Selasky 		free(pd);
92d6b92ffaSHans Petter Selasky 		return NULL;
93d6b92ffaSHans Petter Selasky 	}
94d6b92ffaSHans Petter Selasky 
95d6b92ffaSHans Petter Selasky 	return &pd->ibv_pd;
96d6b92ffaSHans Petter Selasky }
97d6b92ffaSHans Petter Selasky 
c4iw_free_pd(struct ibv_pd * pd)98d6b92ffaSHans Petter Selasky int c4iw_free_pd(struct ibv_pd *pd)
99d6b92ffaSHans Petter Selasky {
100d6b92ffaSHans Petter Selasky 	int ret;
101d6b92ffaSHans Petter Selasky 
102d6b92ffaSHans Petter Selasky 	ret = ibv_cmd_dealloc_pd(pd);
103d6b92ffaSHans Petter Selasky 	if (ret)
104d6b92ffaSHans Petter Selasky 		return ret;
105d6b92ffaSHans Petter Selasky 
106d6b92ffaSHans Petter Selasky 	free(pd);
107d6b92ffaSHans Petter Selasky 	return 0;
108d6b92ffaSHans Petter Selasky }
109d6b92ffaSHans Petter Selasky 
__c4iw_reg_mr(struct ibv_pd * pd,void * addr,size_t length,uint64_t hca_va,int access)110d6b92ffaSHans Petter Selasky static struct ibv_mr *__c4iw_reg_mr(struct ibv_pd *pd, void *addr,
111d6b92ffaSHans Petter Selasky 				    size_t length, uint64_t hca_va,
112d6b92ffaSHans Petter Selasky 				    int access)
113d6b92ffaSHans Petter Selasky {
114d6b92ffaSHans Petter Selasky 	struct c4iw_mr *mhp;
115d6b92ffaSHans Petter Selasky 	struct ibv_reg_mr cmd;
116d6b92ffaSHans Petter Selasky 	struct ibv_reg_mr_resp resp;
117d6b92ffaSHans Petter Selasky 	struct c4iw_dev *dev = to_c4iw_dev(pd->context->device);
118d6b92ffaSHans Petter Selasky 
119d6b92ffaSHans Petter Selasky 	mhp = malloc(sizeof *mhp);
120d6b92ffaSHans Petter Selasky 	if (!mhp)
121d6b92ffaSHans Petter Selasky 		return NULL;
122d6b92ffaSHans Petter Selasky 
123d6b92ffaSHans Petter Selasky 	if (ibv_cmd_reg_mr(pd, addr, length, hca_va,
124d6b92ffaSHans Petter Selasky 			   access, &mhp->ibv_mr, &cmd, sizeof cmd,
125d6b92ffaSHans Petter Selasky 			   &resp, sizeof resp)) {
126d6b92ffaSHans Petter Selasky 		free(mhp);
127d6b92ffaSHans Petter Selasky 		return NULL;
128d6b92ffaSHans Petter Selasky 	}
129d6b92ffaSHans Petter Selasky 
130d6b92ffaSHans Petter Selasky 	mhp->va_fbo = hca_va;
131d6b92ffaSHans Petter Selasky 	mhp->len = length;
132d6b92ffaSHans Petter Selasky 
133d6b92ffaSHans Petter Selasky 	PDBG("%s stag 0x%x va_fbo 0x%" PRIx64 " len %d\n",
134d6b92ffaSHans Petter Selasky 	     __func__, mhp->ibv_mr.rkey, mhp->va_fbo, mhp->len);
135d6b92ffaSHans Petter Selasky 
136d6b92ffaSHans Petter Selasky 	pthread_spin_lock(&dev->lock);
137d6b92ffaSHans Petter Selasky 	dev->mmid2ptr[c4iw_mmid(mhp->ibv_mr.lkey)] = mhp;
138d6b92ffaSHans Petter Selasky 	pthread_spin_unlock(&dev->lock);
139d6b92ffaSHans Petter Selasky 	INC_STAT(mr);
140d6b92ffaSHans Petter Selasky 	return &mhp->ibv_mr;
141d6b92ffaSHans Petter Selasky }
142d6b92ffaSHans Petter Selasky 
c4iw_reg_mr(struct ibv_pd * pd,void * addr,size_t length,int access)143d6b92ffaSHans Petter Selasky struct ibv_mr *c4iw_reg_mr(struct ibv_pd *pd, void *addr,
144d6b92ffaSHans Petter Selasky 			   size_t length, int access)
145d6b92ffaSHans Petter Selasky {
146d6b92ffaSHans Petter Selasky 	PDBG("%s addr %p length %ld\n", __func__, addr, length);
147d6b92ffaSHans Petter Selasky 	return __c4iw_reg_mr(pd, addr, length, (uintptr_t) addr, access);
148d6b92ffaSHans Petter Selasky }
149d6b92ffaSHans Petter Selasky 
c4iw_dereg_mr(struct ibv_mr * mr)150d6b92ffaSHans Petter Selasky int c4iw_dereg_mr(struct ibv_mr *mr)
151d6b92ffaSHans Petter Selasky {
152d6b92ffaSHans Petter Selasky 	int ret;
153d6b92ffaSHans Petter Selasky 	struct c4iw_dev *dev = to_c4iw_dev(mr->pd->context->device);
154d6b92ffaSHans Petter Selasky 
155d6b92ffaSHans Petter Selasky 	ret = ibv_cmd_dereg_mr(mr);
156d6b92ffaSHans Petter Selasky 	if (ret)
157d6b92ffaSHans Petter Selasky 		return ret;
158d6b92ffaSHans Petter Selasky 
159d6b92ffaSHans Petter Selasky 	pthread_spin_lock(&dev->lock);
160d6b92ffaSHans Petter Selasky 	dev->mmid2ptr[c4iw_mmid(mr->lkey)] = NULL;
161d6b92ffaSHans Petter Selasky 	pthread_spin_unlock(&dev->lock);
162d6b92ffaSHans Petter Selasky 
163d6b92ffaSHans Petter Selasky 	free(to_c4iw_mr(mr));
164d6b92ffaSHans Petter Selasky 
165d6b92ffaSHans Petter Selasky 	return 0;
166d6b92ffaSHans Petter Selasky }
167d6b92ffaSHans Petter Selasky 
c4iw_create_cq(struct ibv_context * context,int cqe,struct ibv_comp_channel * channel,int comp_vector)168d6b92ffaSHans Petter Selasky struct ibv_cq *c4iw_create_cq(struct ibv_context *context, int cqe,
169d6b92ffaSHans Petter Selasky 			      struct ibv_comp_channel *channel, int comp_vector)
170d6b92ffaSHans Petter Selasky {
171d6b92ffaSHans Petter Selasky 	struct ibv_create_cq cmd;
172d6b92ffaSHans Petter Selasky 	struct c4iw_create_cq_resp resp;
173d6b92ffaSHans Petter Selasky 	struct c4iw_cq *chp;
174d6b92ffaSHans Petter Selasky 	struct c4iw_dev *dev = to_c4iw_dev(context->device);
175d6b92ffaSHans Petter Selasky 	int ret;
176d6b92ffaSHans Petter Selasky 
177d6b92ffaSHans Petter Selasky 	chp = calloc(1, sizeof *chp);
178d6b92ffaSHans Petter Selasky 	if (!chp) {
179d6b92ffaSHans Petter Selasky 		return NULL;
180d6b92ffaSHans Petter Selasky 	}
181d6b92ffaSHans Petter Selasky 
182d6b92ffaSHans Petter Selasky 	resp.reserved = 0;
183d6b92ffaSHans Petter Selasky 	ret = ibv_cmd_create_cq(context, cqe, channel, comp_vector,
184d6b92ffaSHans Petter Selasky 				&chp->ibv_cq, &cmd, sizeof cmd,
185d6b92ffaSHans Petter Selasky 				&resp.ibv_resp, sizeof resp);
186d6b92ffaSHans Petter Selasky 	if (ret)
187d6b92ffaSHans Petter Selasky 		goto err1;
188d6b92ffaSHans Petter Selasky 
189d6b92ffaSHans Petter Selasky 	if (resp.reserved)
190d6b92ffaSHans Petter Selasky 		PDBG("%s c4iw_create_cq_resp reserved field modified by kernel\n",
191d6b92ffaSHans Petter Selasky 		     __FUNCTION__);
192d6b92ffaSHans Petter Selasky 
193a687910fSSean Lim 	ret = pthread_spin_init(&chp->lock, PTHREAD_PROCESS_PRIVATE);
194a687910fSSean Lim 	if (ret)
195a687910fSSean Lim 		goto err2;
196d6b92ffaSHans Petter Selasky #ifdef STALL_DETECTION
197d6b92ffaSHans Petter Selasky 	gettimeofday(&chp->time, NULL);
198d6b92ffaSHans Petter Selasky #endif
199d6b92ffaSHans Petter Selasky 	chp->rhp = dev;
200d6b92ffaSHans Petter Selasky 	chp->cq.qid_mask = resp.qid_mask;
201d6b92ffaSHans Petter Selasky 	chp->cq.cqid = resp.cqid;
202d6b92ffaSHans Petter Selasky 	chp->cq.size = resp.size;
203d6b92ffaSHans Petter Selasky 	chp->cq.memsize = resp.memsize;
204d6b92ffaSHans Petter Selasky 	chp->cq.gen = 1;
205d6b92ffaSHans Petter Selasky 	chp->cq.queue = mmap(NULL, chp->cq.memsize, PROT_READ|PROT_WRITE,
206d6b92ffaSHans Petter Selasky 			     MAP_SHARED, context->cmd_fd, resp.key);
207d6b92ffaSHans Petter Selasky 	if (chp->cq.queue == MAP_FAILED)
208a687910fSSean Lim 		goto err3;
209d6b92ffaSHans Petter Selasky 
210d6b92ffaSHans Petter Selasky 	chp->cq.ugts = mmap(NULL, c4iw_page_size, PROT_WRITE, MAP_SHARED,
211d6b92ffaSHans Petter Selasky 			   context->cmd_fd, resp.gts_key);
212d6b92ffaSHans Petter Selasky 	if (chp->cq.ugts == MAP_FAILED)
213a687910fSSean Lim 		goto err4;
214d6b92ffaSHans Petter Selasky 
215d6b92ffaSHans Petter Selasky 	if (dev_is_t4(chp->rhp))
216d6b92ffaSHans Petter Selasky 		chp->cq.ugts += 1;
217d6b92ffaSHans Petter Selasky 	else
218d6b92ffaSHans Petter Selasky 		chp->cq.ugts += 5;
219d6b92ffaSHans Petter Selasky 	chp->cq.sw_queue = calloc(chp->cq.size, sizeof *chp->cq.queue);
220d6b92ffaSHans Petter Selasky 	if (!chp->cq.sw_queue)
221a687910fSSean Lim 		goto err5;
222d6b92ffaSHans Petter Selasky 
223d6b92ffaSHans Petter Selasky 	PDBG("%s cqid 0x%x key %" PRIx64 " va %p memsize %lu gts_key %"
224d6b92ffaSHans Petter Selasky 	       PRIx64 " va %p qid_mask 0x%x\n",
225d6b92ffaSHans Petter Selasky 	       __func__, chp->cq.cqid, resp.key, chp->cq.queue,
226d6b92ffaSHans Petter Selasky 	       chp->cq.memsize, resp.gts_key, chp->cq.ugts, chp->cq.qid_mask);
227d6b92ffaSHans Petter Selasky 
228d6b92ffaSHans Petter Selasky 	pthread_spin_lock(&dev->lock);
229d6b92ffaSHans Petter Selasky 	dev->cqid2ptr[chp->cq.cqid] = chp;
230d6b92ffaSHans Petter Selasky 	pthread_spin_unlock(&dev->lock);
231d6b92ffaSHans Petter Selasky 	INC_STAT(cq);
232d6b92ffaSHans Petter Selasky 	return &chp->ibv_cq;
233a687910fSSean Lim err5:
234d6b92ffaSHans Petter Selasky 	munmap(MASKED(chp->cq.ugts), c4iw_page_size);
235a687910fSSean Lim err4:
236d6b92ffaSHans Petter Selasky 	munmap(chp->cq.queue, chp->cq.memsize);
237a687910fSSean Lim err3:
238a687910fSSean Lim 	pthread_spin_destroy(&chp->lock);
239d6b92ffaSHans Petter Selasky err2:
240d6b92ffaSHans Petter Selasky 	(void)ibv_cmd_destroy_cq(&chp->ibv_cq);
241d6b92ffaSHans Petter Selasky err1:
242d6b92ffaSHans Petter Selasky 	free(chp);
243d6b92ffaSHans Petter Selasky 	return NULL;
244d6b92ffaSHans Petter Selasky }
245d6b92ffaSHans Petter Selasky 
c4iw_resize_cq(struct ibv_cq * ibcq,int cqe)246d6b92ffaSHans Petter Selasky int c4iw_resize_cq(struct ibv_cq *ibcq, int cqe)
247d6b92ffaSHans Petter Selasky {
248d6b92ffaSHans Petter Selasky #if 0
249d6b92ffaSHans Petter Selasky 	int ret;
250d6b92ffaSHans Petter Selasky 
251d6b92ffaSHans Petter Selasky 	struct ibv_resize_cq cmd;
252d6b92ffaSHans Petter Selasky 	struct ibv_resize_cq_resp resp;
253d6b92ffaSHans Petter Selasky 	ret = ibv_cmd_resize_cq(ibcq, cqe, &cmd, sizeof cmd, &resp, sizeof resp);
254d6b92ffaSHans Petter Selasky 	PDBG("%s ret %d\n", __func__, ret);
255d6b92ffaSHans Petter Selasky 	return ret;
256d6b92ffaSHans Petter Selasky #else
257d6b92ffaSHans Petter Selasky 	return -ENOSYS;
258d6b92ffaSHans Petter Selasky #endif
259d6b92ffaSHans Petter Selasky }
260d6b92ffaSHans Petter Selasky 
c4iw_destroy_cq(struct ibv_cq * ibcq)261d6b92ffaSHans Petter Selasky int c4iw_destroy_cq(struct ibv_cq *ibcq)
262d6b92ffaSHans Petter Selasky {
263d6b92ffaSHans Petter Selasky 	int ret;
264d6b92ffaSHans Petter Selasky 	struct c4iw_cq *chp = to_c4iw_cq(ibcq);
265d6b92ffaSHans Petter Selasky 	struct c4iw_dev *dev = to_c4iw_dev(ibcq->context->device);
266d6b92ffaSHans Petter Selasky 
267d6b92ffaSHans Petter Selasky 	chp->cq.error = 1;
268d6b92ffaSHans Petter Selasky 	ret = ibv_cmd_destroy_cq(ibcq);
269d6b92ffaSHans Petter Selasky 	if (ret) {
270d6b92ffaSHans Petter Selasky 		return ret;
271d6b92ffaSHans Petter Selasky 	}
272a687910fSSean Lim 	verbs_cleanup_cq(ibcq);
273d6b92ffaSHans Petter Selasky 	munmap(MASKED(chp->cq.ugts), c4iw_page_size);
274d6b92ffaSHans Petter Selasky 	munmap(chp->cq.queue, chp->cq.memsize);
275d6b92ffaSHans Petter Selasky 
276d6b92ffaSHans Petter Selasky 	pthread_spin_lock(&dev->lock);
277d6b92ffaSHans Petter Selasky 	dev->cqid2ptr[chp->cq.cqid] = NULL;
278d6b92ffaSHans Petter Selasky 	pthread_spin_unlock(&dev->lock);
279d6b92ffaSHans Petter Selasky 
280d6b92ffaSHans Petter Selasky 	free(chp->cq.sw_queue);
281a687910fSSean Lim 	pthread_spin_destroy(&chp->lock);
282d6b92ffaSHans Petter Selasky 	free(chp);
283d6b92ffaSHans Petter Selasky 	return 0;
284d6b92ffaSHans Petter Selasky }
285d6b92ffaSHans Petter Selasky 
c4iw_create_srq(struct ibv_pd * pd,struct ibv_srq_init_attr * attr)286d6b92ffaSHans Petter Selasky struct ibv_srq *c4iw_create_srq(struct ibv_pd *pd,
287d6b92ffaSHans Petter Selasky 				struct ibv_srq_init_attr *attr)
288d6b92ffaSHans Petter Selasky {
289d6b92ffaSHans Petter Selasky 	return NULL;
290d6b92ffaSHans Petter Selasky }
291d6b92ffaSHans Petter Selasky 
c4iw_modify_srq(struct ibv_srq * srq,struct ibv_srq_attr * attr,int attr_mask)292d6b92ffaSHans Petter Selasky int c4iw_modify_srq(struct ibv_srq *srq, struct ibv_srq_attr *attr,
293d6b92ffaSHans Petter Selasky 		    int attr_mask)
294d6b92ffaSHans Petter Selasky {
295d6b92ffaSHans Petter Selasky 	return ENOSYS;
296d6b92ffaSHans Petter Selasky }
297d6b92ffaSHans Petter Selasky 
c4iw_destroy_srq(struct ibv_srq * srq)298d6b92ffaSHans Petter Selasky int c4iw_destroy_srq(struct ibv_srq *srq)
299d6b92ffaSHans Petter Selasky {
300d6b92ffaSHans Petter Selasky 	return ENOSYS;
301d6b92ffaSHans Petter Selasky }
302d6b92ffaSHans Petter Selasky 
c4iw_post_srq_recv(struct ibv_srq * ibsrq,struct ibv_recv_wr * wr,struct ibv_recv_wr ** bad_wr)303d6b92ffaSHans Petter Selasky int c4iw_post_srq_recv(struct ibv_srq *ibsrq, struct ibv_recv_wr *wr,
304d6b92ffaSHans Petter Selasky 		       struct ibv_recv_wr **bad_wr)
305d6b92ffaSHans Petter Selasky {
306d6b92ffaSHans Petter Selasky 	return ENOSYS;
307d6b92ffaSHans Petter Selasky }
308d6b92ffaSHans Petter Selasky 
create_qp_v0(struct ibv_pd * pd,struct ibv_qp_init_attr * attr)309d6b92ffaSHans Petter Selasky static struct ibv_qp *create_qp_v0(struct ibv_pd *pd,
310d6b92ffaSHans Petter Selasky 				   struct ibv_qp_init_attr *attr)
311d6b92ffaSHans Petter Selasky {
312d6b92ffaSHans Petter Selasky 	struct ibv_create_qp cmd;
313d6b92ffaSHans Petter Selasky 	struct c4iw_create_qp_resp_v0 resp;
314d6b92ffaSHans Petter Selasky 	struct c4iw_qp *qhp;
315d6b92ffaSHans Petter Selasky 	struct c4iw_dev *dev = to_c4iw_dev(pd->context->device);
316d6b92ffaSHans Petter Selasky 	int ret;
317d6b92ffaSHans Petter Selasky 	void *dbva;
318d6b92ffaSHans Petter Selasky 
319d6b92ffaSHans Petter Selasky 	PDBG("%s enter qp\n", __func__);
320d6b92ffaSHans Petter Selasky 	qhp = calloc(1, sizeof *qhp);
321d6b92ffaSHans Petter Selasky 	if (!qhp)
322d6b92ffaSHans Petter Selasky 		goto err1;
323d6b92ffaSHans Petter Selasky 
324d6b92ffaSHans Petter Selasky 	ret = ibv_cmd_create_qp(pd, &qhp->ibv_qp, attr, &cmd,
325d6b92ffaSHans Petter Selasky 				sizeof cmd, &resp.ibv_resp, sizeof resp);
326d6b92ffaSHans Petter Selasky 	if (ret)
327d6b92ffaSHans Petter Selasky 		goto err2;
328d6b92ffaSHans Petter Selasky 
329d6b92ffaSHans Petter Selasky 	PDBG("%s sqid 0x%x sq key %" PRIx64 " sq db/gts key %" PRIx64
330d6b92ffaSHans Petter Selasky 	       " rqid 0x%x rq key %" PRIx64 " rq db/gts key %" PRIx64
331d6b92ffaSHans Petter Selasky 	       " qid_mask 0x%x\n",
332d6b92ffaSHans Petter Selasky 		__func__,
333d6b92ffaSHans Petter Selasky 		resp.sqid, resp.sq_key, resp.sq_db_gts_key,
334d6b92ffaSHans Petter Selasky 		resp.rqid, resp.rq_key, resp.rq_db_gts_key, resp.qid_mask);
335d6b92ffaSHans Petter Selasky 
336d6b92ffaSHans Petter Selasky 	qhp->wq.qid_mask = resp.qid_mask;
337d6b92ffaSHans Petter Selasky 	qhp->rhp = dev;
338d6b92ffaSHans Petter Selasky 	qhp->wq.sq.qid = resp.sqid;
339d6b92ffaSHans Petter Selasky 	qhp->wq.sq.size = resp.sq_size;
340d6b92ffaSHans Petter Selasky 	qhp->wq.sq.memsize = resp.sq_memsize;
341d6b92ffaSHans Petter Selasky 	qhp->wq.sq.flags = 0;
342d6b92ffaSHans Petter Selasky 	qhp->wq.rq.msn = 1;
343d6b92ffaSHans Petter Selasky 	qhp->wq.rq.qid = resp.rqid;
344d6b92ffaSHans Petter Selasky 	qhp->wq.rq.size = resp.rq_size;
345d6b92ffaSHans Petter Selasky 	qhp->wq.rq.memsize = resp.rq_memsize;
346a687910fSSean Lim 	ret = pthread_spin_init(&qhp->lock, PTHREAD_PROCESS_PRIVATE);
347a687910fSSean Lim 	if (ret)
348a687910fSSean Lim 		goto err3;
349d6b92ffaSHans Petter Selasky 
350d6b92ffaSHans Petter Selasky 	dbva = mmap(NULL, c4iw_page_size, PROT_WRITE, MAP_SHARED,
351d6b92ffaSHans Petter Selasky 		    pd->context->cmd_fd, resp.sq_db_gts_key);
352d6b92ffaSHans Petter Selasky 	if (dbva == MAP_FAILED)
353a687910fSSean Lim 		goto err4;
354d6b92ffaSHans Petter Selasky 
355d6b92ffaSHans Petter Selasky 	qhp->wq.sq.udb = dbva;
356d6b92ffaSHans Petter Selasky 	qhp->wq.sq.queue = mmap(NULL, qhp->wq.sq.memsize,
357d6b92ffaSHans Petter Selasky 			    PROT_WRITE, MAP_SHARED,
358d6b92ffaSHans Petter Selasky 			    pd->context->cmd_fd, resp.sq_key);
359d6b92ffaSHans Petter Selasky 	if (qhp->wq.sq.queue == MAP_FAILED)
360a687910fSSean Lim 		goto err5;
361d6b92ffaSHans Petter Selasky 
362d6b92ffaSHans Petter Selasky 	dbva = mmap(NULL, c4iw_page_size, PROT_WRITE, MAP_SHARED,
363d6b92ffaSHans Petter Selasky 		    pd->context->cmd_fd, resp.rq_db_gts_key);
364d6b92ffaSHans Petter Selasky 	if (dbva == MAP_FAILED)
365a687910fSSean Lim 		goto err6;
366d6b92ffaSHans Petter Selasky 	qhp->wq.rq.udb = dbva;
367d6b92ffaSHans Petter Selasky 	qhp->wq.rq.queue = mmap(NULL, qhp->wq.rq.memsize,
368d6b92ffaSHans Petter Selasky 			    PROT_WRITE, MAP_SHARED,
369d6b92ffaSHans Petter Selasky 			    pd->context->cmd_fd, resp.rq_key);
370d6b92ffaSHans Petter Selasky 	if (qhp->wq.rq.queue == MAP_FAILED)
371a687910fSSean Lim 		goto err7;
372d6b92ffaSHans Petter Selasky 
373d6b92ffaSHans Petter Selasky 	qhp->wq.sq.sw_sq = calloc(qhp->wq.sq.size, sizeof (struct t4_swsqe));
374d6b92ffaSHans Petter Selasky 	if (!qhp->wq.sq.sw_sq)
375a687910fSSean Lim 		goto err8;
376d6b92ffaSHans Petter Selasky 
377d6b92ffaSHans Petter Selasky 	qhp->wq.rq.sw_rq = calloc(qhp->wq.rq.size, sizeof (uint64_t));
378d6b92ffaSHans Petter Selasky 	if (!qhp->wq.rq.sw_rq)
379a687910fSSean Lim 		goto err9;
380d6b92ffaSHans Petter Selasky 
381d6b92ffaSHans Petter Selasky 	PDBG("%s sq dbva %p sq qva %p sq depth %u sq memsize %lu "
382d6b92ffaSHans Petter Selasky 	       " rq dbva %p rq qva %p rq depth %u rq memsize %lu\n",
383d6b92ffaSHans Petter Selasky 	     __func__,
384d6b92ffaSHans Petter Selasky 	     qhp->wq.sq.udb, qhp->wq.sq.queue,
385d6b92ffaSHans Petter Selasky 	     qhp->wq.sq.size, qhp->wq.sq.memsize,
386d6b92ffaSHans Petter Selasky 	     qhp->wq.rq.udb, qhp->wq.rq.queue,
387d6b92ffaSHans Petter Selasky 	     qhp->wq.rq.size, qhp->wq.rq.memsize);
388d6b92ffaSHans Petter Selasky 
389d6b92ffaSHans Petter Selasky 	qhp->sq_sig_all = attr->sq_sig_all;
390d6b92ffaSHans Petter Selasky 
391d6b92ffaSHans Petter Selasky 	pthread_spin_lock(&dev->lock);
392d6b92ffaSHans Petter Selasky 	dev->qpid2ptr[qhp->wq.sq.qid] = qhp;
393d6b92ffaSHans Petter Selasky 	pthread_spin_unlock(&dev->lock);
394d6b92ffaSHans Petter Selasky 	INC_STAT(qp);
395d6b92ffaSHans Petter Selasky 	return &qhp->ibv_qp;
396a687910fSSean Lim err9:
397d6b92ffaSHans Petter Selasky 	free(qhp->wq.sq.sw_sq);
398a687910fSSean Lim err8:
399d6b92ffaSHans Petter Selasky 	munmap((void *)qhp->wq.rq.queue, qhp->wq.rq.memsize);
400a687910fSSean Lim err7:
401d6b92ffaSHans Petter Selasky 	munmap(MASKED(qhp->wq.rq.udb), c4iw_page_size);
402a687910fSSean Lim err6:
403d6b92ffaSHans Petter Selasky 	munmap((void *)qhp->wq.sq.queue, qhp->wq.sq.memsize);
404a687910fSSean Lim err5:
405d6b92ffaSHans Petter Selasky 	munmap(MASKED(qhp->wq.sq.udb), c4iw_page_size);
406a687910fSSean Lim err4:
407a687910fSSean Lim 	pthread_spin_destroy(&qhp->lock);
408d6b92ffaSHans Petter Selasky err3:
409d6b92ffaSHans Petter Selasky 	(void)ibv_cmd_destroy_qp(&qhp->ibv_qp);
410d6b92ffaSHans Petter Selasky err2:
411d6b92ffaSHans Petter Selasky 	free(qhp);
412d6b92ffaSHans Petter Selasky err1:
413d6b92ffaSHans Petter Selasky 	return NULL;
414d6b92ffaSHans Petter Selasky }
415d6b92ffaSHans Petter Selasky 
create_qp(struct ibv_pd * pd,struct ibv_qp_init_attr * attr)416d6b92ffaSHans Petter Selasky static struct ibv_qp *create_qp(struct ibv_pd *pd,
417d6b92ffaSHans Petter Selasky 				struct ibv_qp_init_attr *attr)
418d6b92ffaSHans Petter Selasky {
419d6b92ffaSHans Petter Selasky 	struct ibv_create_qp cmd;
420d6b92ffaSHans Petter Selasky 	struct c4iw_create_qp_resp resp;
421d6b92ffaSHans Petter Selasky 	struct c4iw_qp *qhp;
422d6b92ffaSHans Petter Selasky 	struct c4iw_dev *dev = to_c4iw_dev(pd->context->device);
423d6b92ffaSHans Petter Selasky 	struct c4iw_context *ctx = to_c4iw_context(pd->context);
424d6b92ffaSHans Petter Selasky 	int ret;
425d6b92ffaSHans Petter Selasky 	void *dbva;
426d6b92ffaSHans Petter Selasky 
427d6b92ffaSHans Petter Selasky 	PDBG("%s enter qp\n", __func__);
428d6b92ffaSHans Petter Selasky 	qhp = calloc(1, sizeof *qhp);
429d6b92ffaSHans Petter Selasky 	if (!qhp)
430d6b92ffaSHans Petter Selasky 		goto err1;
431d6b92ffaSHans Petter Selasky 
432d6b92ffaSHans Petter Selasky 	ret = ibv_cmd_create_qp(pd, &qhp->ibv_qp, attr, &cmd,
433d6b92ffaSHans Petter Selasky 				sizeof cmd, &resp.ibv_resp, sizeof resp);
434d6b92ffaSHans Petter Selasky 	if (ret)
435d6b92ffaSHans Petter Selasky 		goto err2;
436d6b92ffaSHans Petter Selasky 
437d6b92ffaSHans Petter Selasky 	PDBG("%s sqid 0x%x sq key %" PRIx64 " sq db/gts key %" PRIx64
438d6b92ffaSHans Petter Selasky 	       " rqid 0x%x rq key %" PRIx64 " rq db/gts key %" PRIx64
439d6b92ffaSHans Petter Selasky 	       " qid_mask 0x%x\n",
440d6b92ffaSHans Petter Selasky 		__func__,
441d6b92ffaSHans Petter Selasky 		resp.sqid, resp.sq_key, resp.sq_db_gts_key,
442d6b92ffaSHans Petter Selasky 		resp.rqid, resp.rq_key, resp.rq_db_gts_key, resp.qid_mask);
443d6b92ffaSHans Petter Selasky 
444d6b92ffaSHans Petter Selasky 	qhp->wq.qid_mask = resp.qid_mask;
445d6b92ffaSHans Petter Selasky 	qhp->rhp = dev;
446d6b92ffaSHans Petter Selasky 	qhp->wq.sq.qid = resp.sqid;
447d6b92ffaSHans Petter Selasky 	qhp->wq.sq.size = resp.sq_size;
448d6b92ffaSHans Petter Selasky 	qhp->wq.sq.memsize = resp.sq_memsize;
449d6b92ffaSHans Petter Selasky 	qhp->wq.sq.flags = resp.flags & C4IW_QPF_ONCHIP ? T4_SQ_ONCHIP : 0;
450d6b92ffaSHans Petter Selasky 	qhp->wq.sq.flush_cidx = -1;
451d6b92ffaSHans Petter Selasky 	qhp->wq.rq.msn = 1;
452d6b92ffaSHans Petter Selasky 	qhp->wq.rq.qid = resp.rqid;
453d6b92ffaSHans Petter Selasky 	qhp->wq.rq.size = resp.rq_size;
454d6b92ffaSHans Petter Selasky 	qhp->wq.rq.memsize = resp.rq_memsize;
455d6b92ffaSHans Petter Selasky 	if (ma_wr && resp.sq_memsize < (resp.sq_size + 1) *
456d6b92ffaSHans Petter Selasky 	    sizeof *qhp->wq.sq.queue + 16*sizeof(__be64) ) {
457d6b92ffaSHans Petter Selasky 		ma_wr = 0;
458d6b92ffaSHans Petter Selasky 		fprintf(stderr, "libcxgb4 warning - downlevel iw_cxgb4 driver. "
459d6b92ffaSHans Petter Selasky 			"MA workaround disabled.\n");
460d6b92ffaSHans Petter Selasky 	}
461a687910fSSean Lim 	ret = pthread_spin_init(&qhp->lock, PTHREAD_PROCESS_PRIVATE);
462a687910fSSean Lim 	if (ret)
463a687910fSSean Lim 		goto err3;
464d6b92ffaSHans Petter Selasky 
465d6b92ffaSHans Petter Selasky 	dbva = mmap(NULL, c4iw_page_size, PROT_WRITE, MAP_SHARED,
466d6b92ffaSHans Petter Selasky 		    pd->context->cmd_fd, resp.sq_db_gts_key);
467d6b92ffaSHans Petter Selasky 	if (dbva == MAP_FAILED)
468a687910fSSean Lim 		goto err4;
469d6b92ffaSHans Petter Selasky 	qhp->wq.sq.udb = dbva;
470d6b92ffaSHans Petter Selasky 	if (!dev_is_t4(qhp->rhp)) {
471d6b92ffaSHans Petter Selasky 		unsigned long segment_offset = 128 * (qhp->wq.sq.qid &
472d6b92ffaSHans Petter Selasky 						      qhp->wq.qid_mask);
473d6b92ffaSHans Petter Selasky 
474d6b92ffaSHans Petter Selasky 		if (segment_offset < c4iw_page_size) {
475d6b92ffaSHans Petter Selasky 			qhp->wq.sq.udb += segment_offset / 4;
476d6b92ffaSHans Petter Selasky 			qhp->wq.sq.wc_reg_available = 1;
477d6b92ffaSHans Petter Selasky 		} else
478d6b92ffaSHans Petter Selasky 			qhp->wq.sq.bar2_qid = qhp->wq.sq.qid & qhp->wq.qid_mask;
479d6b92ffaSHans Petter Selasky 		qhp->wq.sq.udb += 2;
480d6b92ffaSHans Petter Selasky 	}
481d6b92ffaSHans Petter Selasky 
482d6b92ffaSHans Petter Selasky 	qhp->wq.sq.queue = mmap(NULL, qhp->wq.sq.memsize,
4835c2bacdeSNavdeep Parhar 			    PROT_READ|PROT_WRITE, MAP_SHARED,
484d6b92ffaSHans Petter Selasky 			    pd->context->cmd_fd, resp.sq_key);
485d6b92ffaSHans Petter Selasky 	if (qhp->wq.sq.queue == MAP_FAILED)
486a687910fSSean Lim 		goto err5;
487d6b92ffaSHans Petter Selasky 
488d6b92ffaSHans Petter Selasky 	dbva = mmap(NULL, c4iw_page_size, PROT_WRITE, MAP_SHARED,
489d6b92ffaSHans Petter Selasky 		    pd->context->cmd_fd, resp.rq_db_gts_key);
490d6b92ffaSHans Petter Selasky 	if (dbva == MAP_FAILED)
491a687910fSSean Lim 		goto err6;
492d6b92ffaSHans Petter Selasky 	qhp->wq.rq.udb = dbva;
493d6b92ffaSHans Petter Selasky 	if (!dev_is_t4(qhp->rhp)) {
494d6b92ffaSHans Petter Selasky 		unsigned long segment_offset = 128 * (qhp->wq.rq.qid &
495d6b92ffaSHans Petter Selasky 						      qhp->wq.qid_mask);
496d6b92ffaSHans Petter Selasky 
497d6b92ffaSHans Petter Selasky 		if (segment_offset < c4iw_page_size) {
498d6b92ffaSHans Petter Selasky 			qhp->wq.rq.udb += segment_offset / 4;
499d6b92ffaSHans Petter Selasky 			qhp->wq.rq.wc_reg_available = 1;
500d6b92ffaSHans Petter Selasky 		} else
501d6b92ffaSHans Petter Selasky 			qhp->wq.rq.bar2_qid = qhp->wq.rq.qid & qhp->wq.qid_mask;
502d6b92ffaSHans Petter Selasky 		qhp->wq.rq.udb += 2;
503d6b92ffaSHans Petter Selasky 	}
504d6b92ffaSHans Petter Selasky 	qhp->wq.rq.queue = mmap(NULL, qhp->wq.rq.memsize,
5055c2bacdeSNavdeep Parhar 			    PROT_READ|PROT_WRITE, MAP_SHARED,
506d6b92ffaSHans Petter Selasky 			    pd->context->cmd_fd, resp.rq_key);
507d6b92ffaSHans Petter Selasky 	if (qhp->wq.rq.queue == MAP_FAILED)
508a687910fSSean Lim 		goto err7;
509d6b92ffaSHans Petter Selasky 
510d6b92ffaSHans Petter Selasky 	qhp->wq.sq.sw_sq = calloc(qhp->wq.sq.size, sizeof (struct t4_swsqe));
511d6b92ffaSHans Petter Selasky 	if (!qhp->wq.sq.sw_sq)
512a687910fSSean Lim 		goto err8;
513d6b92ffaSHans Petter Selasky 
514d6b92ffaSHans Petter Selasky 	qhp->wq.rq.sw_rq = calloc(qhp->wq.rq.size, sizeof (uint64_t));
515d6b92ffaSHans Petter Selasky 	if (!qhp->wq.rq.sw_rq)
516a687910fSSean Lim 		goto err9;
517d6b92ffaSHans Petter Selasky 
518d6b92ffaSHans Petter Selasky 	if (t4_sq_onchip(&qhp->wq)) {
519d6b92ffaSHans Petter Selasky 		qhp->wq.sq.ma_sync = mmap(NULL, c4iw_page_size, PROT_WRITE,
520d6b92ffaSHans Petter Selasky 					  MAP_SHARED, pd->context->cmd_fd,
521d6b92ffaSHans Petter Selasky 					  resp.ma_sync_key);
522d6b92ffaSHans Petter Selasky 		if (qhp->wq.sq.ma_sync == MAP_FAILED)
523a687910fSSean Lim 			goto err10;
524d6b92ffaSHans Petter Selasky 		qhp->wq.sq.ma_sync += (A_PCIE_MA_SYNC & (c4iw_page_size - 1));
525d6b92ffaSHans Petter Selasky 	}
526d6b92ffaSHans Petter Selasky 
527d6b92ffaSHans Petter Selasky 	if (ctx->status_page_size) {
528d6b92ffaSHans Petter Selasky 		qhp->wq.db_offp = &ctx->status_page->db_off;
529d6b92ffaSHans Petter Selasky 	} else {
530d6b92ffaSHans Petter Selasky 		qhp->wq.db_offp =
531d6b92ffaSHans Petter Selasky 			&qhp->wq.rq.queue[qhp->wq.rq.size].status.db_off;
532d6b92ffaSHans Petter Selasky 	}
533d6b92ffaSHans Petter Selasky 
534d6b92ffaSHans Petter Selasky 	PDBG("%s sq dbva %p sq qva %p sq depth %u sq memsize %lu "
535d6b92ffaSHans Petter Selasky 	       " rq dbva %p rq qva %p rq depth %u rq memsize %lu\n",
536d6b92ffaSHans Petter Selasky 	     __func__,
537d6b92ffaSHans Petter Selasky 	     qhp->wq.sq.udb, qhp->wq.sq.queue,
538d6b92ffaSHans Petter Selasky 	     qhp->wq.sq.size, qhp->wq.sq.memsize,
539d6b92ffaSHans Petter Selasky 	     qhp->wq.rq.udb, qhp->wq.rq.queue,
540d6b92ffaSHans Petter Selasky 	     qhp->wq.rq.size, qhp->wq.rq.memsize);
541d6b92ffaSHans Petter Selasky 
542d6b92ffaSHans Petter Selasky 	qhp->sq_sig_all = attr->sq_sig_all;
543d6b92ffaSHans Petter Selasky 
544d6b92ffaSHans Petter Selasky 	pthread_spin_lock(&dev->lock);
545d6b92ffaSHans Petter Selasky 	dev->qpid2ptr[qhp->wq.sq.qid] = qhp;
546d6b92ffaSHans Petter Selasky 	pthread_spin_unlock(&dev->lock);
547d6b92ffaSHans Petter Selasky 	INC_STAT(qp);
548d6b92ffaSHans Petter Selasky 	return &qhp->ibv_qp;
549a687910fSSean Lim err10:
550d6b92ffaSHans Petter Selasky 	free(qhp->wq.rq.sw_rq);
551a687910fSSean Lim err9:
552d6b92ffaSHans Petter Selasky 	free(qhp->wq.sq.sw_sq);
553a687910fSSean Lim err8:
554d6b92ffaSHans Petter Selasky 	munmap((void *)qhp->wq.rq.queue, qhp->wq.rq.memsize);
555a687910fSSean Lim err7:
556d6b92ffaSHans Petter Selasky 	munmap(MASKED(qhp->wq.rq.udb), c4iw_page_size);
557a687910fSSean Lim err6:
558d6b92ffaSHans Petter Selasky 	munmap((void *)qhp->wq.sq.queue, qhp->wq.sq.memsize);
559a687910fSSean Lim err5:
560d6b92ffaSHans Petter Selasky 	munmap(MASKED(qhp->wq.sq.udb), c4iw_page_size);
561a687910fSSean Lim err4:
562a687910fSSean Lim 	pthread_spin_destroy(&qhp->lock);
563d6b92ffaSHans Petter Selasky err3:
564d6b92ffaSHans Petter Selasky 	(void)ibv_cmd_destroy_qp(&qhp->ibv_qp);
565d6b92ffaSHans Petter Selasky err2:
566d6b92ffaSHans Petter Selasky 	free(qhp);
567d6b92ffaSHans Petter Selasky err1:
568d6b92ffaSHans Petter Selasky 	return NULL;
569d6b92ffaSHans Petter Selasky }
570d6b92ffaSHans Petter Selasky 
c4iw_create_qp(struct ibv_pd * pd,struct ibv_qp_init_attr * attr)571d6b92ffaSHans Petter Selasky struct ibv_qp *c4iw_create_qp(struct ibv_pd *pd,
572d6b92ffaSHans Petter Selasky 				     struct ibv_qp_init_attr *attr)
573d6b92ffaSHans Petter Selasky {
574d6b92ffaSHans Petter Selasky 	struct c4iw_dev *dev = to_c4iw_dev(pd->context->device);
575d6b92ffaSHans Petter Selasky 
576d6b92ffaSHans Petter Selasky 	if (dev->abi_version == 0)
577d6b92ffaSHans Petter Selasky 		return create_qp_v0(pd, attr);
578d6b92ffaSHans Petter Selasky 	return create_qp(pd, attr);
579d6b92ffaSHans Petter Selasky }
580d6b92ffaSHans Petter Selasky 
reset_qp(struct c4iw_qp * qhp)581d6b92ffaSHans Petter Selasky static void reset_qp(struct c4iw_qp *qhp)
582d6b92ffaSHans Petter Selasky {
583d6b92ffaSHans Petter Selasky 	PDBG("%s enter qp %p\n", __func__, qhp);
584d6b92ffaSHans Petter Selasky 	qhp->wq.sq.cidx = 0;
585d6b92ffaSHans Petter Selasky 	qhp->wq.sq.wq_pidx = qhp->wq.sq.pidx = qhp->wq.sq.in_use = 0;
586d6b92ffaSHans Petter Selasky 	qhp->wq.rq.cidx = qhp->wq.rq.pidx = qhp->wq.rq.in_use = 0;
587d6b92ffaSHans Petter Selasky 	qhp->wq.sq.oldest_read = NULL;
588d6b92ffaSHans Petter Selasky 	memset(qhp->wq.sq.queue, 0, qhp->wq.sq.memsize);
589d6b92ffaSHans Petter Selasky 	if (t4_sq_onchip(&qhp->wq))
590d6b92ffaSHans Petter Selasky 		mmio_flush_writes();
591d6b92ffaSHans Petter Selasky 	memset(qhp->wq.rq.queue, 0, qhp->wq.rq.memsize);
592d6b92ffaSHans Petter Selasky }
593d6b92ffaSHans Petter Selasky 
c4iw_modify_qp(struct ibv_qp * ibqp,struct ibv_qp_attr * attr,int attr_mask)594d6b92ffaSHans Petter Selasky int c4iw_modify_qp(struct ibv_qp *ibqp, struct ibv_qp_attr *attr,
595d6b92ffaSHans Petter Selasky 		   int attr_mask)
596d6b92ffaSHans Petter Selasky {
597d6b92ffaSHans Petter Selasky 	struct ibv_modify_qp cmd = {};
598d6b92ffaSHans Petter Selasky 	struct c4iw_qp *qhp = to_c4iw_qp(ibqp);
599d6b92ffaSHans Petter Selasky 	int ret;
600d6b92ffaSHans Petter Selasky 
601d6b92ffaSHans Petter Selasky 	PDBG("%s enter qp %p new state %d\n", __func__, ibqp, attr_mask & IBV_QP_STATE ? attr->qp_state : -1);
602d6b92ffaSHans Petter Selasky 	pthread_spin_lock(&qhp->lock);
603d6b92ffaSHans Petter Selasky 	if (t4_wq_in_error(&qhp->wq))
604d6b92ffaSHans Petter Selasky 		c4iw_flush_qp(qhp);
605d6b92ffaSHans Petter Selasky 	ret = ibv_cmd_modify_qp(ibqp, attr, attr_mask, &cmd, sizeof cmd);
606d6b92ffaSHans Petter Selasky 	if (!ret && (attr_mask & IBV_QP_STATE) && attr->qp_state == IBV_QPS_RESET)
607d6b92ffaSHans Petter Selasky 		reset_qp(qhp);
608d6b92ffaSHans Petter Selasky 	pthread_spin_unlock(&qhp->lock);
609d6b92ffaSHans Petter Selasky 	return ret;
610d6b92ffaSHans Petter Selasky }
611d6b92ffaSHans Petter Selasky 
c4iw_destroy_qp(struct ibv_qp * ibqp)612d6b92ffaSHans Petter Selasky int c4iw_destroy_qp(struct ibv_qp *ibqp)
613d6b92ffaSHans Petter Selasky {
614d6b92ffaSHans Petter Selasky 	int ret;
615d6b92ffaSHans Petter Selasky 	struct c4iw_qp *qhp = to_c4iw_qp(ibqp);
616d6b92ffaSHans Petter Selasky 	struct c4iw_dev *dev = to_c4iw_dev(ibqp->context->device);
617d6b92ffaSHans Petter Selasky 
618d6b92ffaSHans Petter Selasky 	PDBG("%s enter qp %p\n", __func__, ibqp);
619d6b92ffaSHans Petter Selasky 	pthread_spin_lock(&qhp->lock);
620d6b92ffaSHans Petter Selasky 	c4iw_flush_qp(qhp);
621d6b92ffaSHans Petter Selasky 	pthread_spin_unlock(&qhp->lock);
622d6b92ffaSHans Petter Selasky 
623d6b92ffaSHans Petter Selasky 	ret = ibv_cmd_destroy_qp(ibqp);
624d6b92ffaSHans Petter Selasky 	if (ret) {
625d6b92ffaSHans Petter Selasky 		return ret;
626d6b92ffaSHans Petter Selasky 	}
627d6b92ffaSHans Petter Selasky 	if (t4_sq_onchip(&qhp->wq)) {
628d6b92ffaSHans Petter Selasky 		qhp->wq.sq.ma_sync -= (A_PCIE_MA_SYNC & (c4iw_page_size - 1));
629d6b92ffaSHans Petter Selasky 		munmap((void *)qhp->wq.sq.ma_sync, c4iw_page_size);
630d6b92ffaSHans Petter Selasky 	}
631d6b92ffaSHans Petter Selasky 	munmap(MASKED(qhp->wq.sq.udb), c4iw_page_size);
632d6b92ffaSHans Petter Selasky 	munmap(MASKED(qhp->wq.rq.udb), c4iw_page_size);
633d6b92ffaSHans Petter Selasky 	munmap(qhp->wq.sq.queue, qhp->wq.sq.memsize);
634d6b92ffaSHans Petter Selasky 	munmap(qhp->wq.rq.queue, qhp->wq.rq.memsize);
635d6b92ffaSHans Petter Selasky 
636d6b92ffaSHans Petter Selasky 	pthread_spin_lock(&dev->lock);
637d6b92ffaSHans Petter Selasky 	dev->qpid2ptr[qhp->wq.sq.qid] = NULL;
638d6b92ffaSHans Petter Selasky 	pthread_spin_unlock(&dev->lock);
639d6b92ffaSHans Petter Selasky 
640d6b92ffaSHans Petter Selasky 	free(qhp->wq.rq.sw_rq);
641d6b92ffaSHans Petter Selasky 	free(qhp->wq.sq.sw_sq);
642a687910fSSean Lim 	pthread_spin_destroy(&qhp->lock);
643d6b92ffaSHans Petter Selasky 	free(qhp);
644d6b92ffaSHans Petter Selasky 	return 0;
645d6b92ffaSHans Petter Selasky }
646d6b92ffaSHans Petter Selasky 
c4iw_query_qp(struct ibv_qp * ibqp,struct ibv_qp_attr * attr,int attr_mask,struct ibv_qp_init_attr * init_attr)647d6b92ffaSHans Petter Selasky int c4iw_query_qp(struct ibv_qp *ibqp, struct ibv_qp_attr *attr,
648d6b92ffaSHans Petter Selasky 		  int attr_mask, struct ibv_qp_init_attr *init_attr)
649d6b92ffaSHans Petter Selasky {
650d6b92ffaSHans Petter Selasky 	struct ibv_query_qp cmd;
651d6b92ffaSHans Petter Selasky 	struct c4iw_qp *qhp = to_c4iw_qp(ibqp);
652d6b92ffaSHans Petter Selasky 	int ret;
653d6b92ffaSHans Petter Selasky 
654d6b92ffaSHans Petter Selasky 	pthread_spin_lock(&qhp->lock);
655d6b92ffaSHans Petter Selasky 	if (t4_wq_in_error(&qhp->wq))
656d6b92ffaSHans Petter Selasky 		c4iw_flush_qp(qhp);
657d6b92ffaSHans Petter Selasky 	ret = ibv_cmd_query_qp(ibqp, attr, attr_mask, init_attr, &cmd, sizeof cmd);
658d6b92ffaSHans Petter Selasky 	pthread_spin_unlock(&qhp->lock);
659d6b92ffaSHans Petter Selasky 	return ret;
660d6b92ffaSHans Petter Selasky }
661d6b92ffaSHans Petter Selasky 
c4iw_create_ah(struct ibv_pd * pd,struct ibv_ah_attr * attr)662d6b92ffaSHans Petter Selasky struct ibv_ah *c4iw_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr)
663d6b92ffaSHans Petter Selasky {
664d6b92ffaSHans Petter Selasky 	return NULL;
665d6b92ffaSHans Petter Selasky }
666d6b92ffaSHans Petter Selasky 
c4iw_destroy_ah(struct ibv_ah * ah)667d6b92ffaSHans Petter Selasky int c4iw_destroy_ah(struct ibv_ah *ah)
668d6b92ffaSHans Petter Selasky {
669d6b92ffaSHans Petter Selasky 	return ENOSYS;
670d6b92ffaSHans Petter Selasky }
671d6b92ffaSHans Petter Selasky 
c4iw_attach_mcast(struct ibv_qp * ibqp,const union ibv_gid * gid,uint16_t lid)672d6b92ffaSHans Petter Selasky int c4iw_attach_mcast(struct ibv_qp *ibqp, const union ibv_gid *gid,
673d6b92ffaSHans Petter Selasky 		      uint16_t lid)
674d6b92ffaSHans Petter Selasky {
675d6b92ffaSHans Petter Selasky 	struct c4iw_qp *qhp = to_c4iw_qp(ibqp);
676d6b92ffaSHans Petter Selasky 	int ret;
677d6b92ffaSHans Petter Selasky 
678d6b92ffaSHans Petter Selasky 	pthread_spin_lock(&qhp->lock);
679d6b92ffaSHans Petter Selasky 	if (t4_wq_in_error(&qhp->wq))
680d6b92ffaSHans Petter Selasky 		c4iw_flush_qp(qhp);
681d6b92ffaSHans Petter Selasky 	ret = ibv_cmd_attach_mcast(ibqp, gid, lid);
682d6b92ffaSHans Petter Selasky 	pthread_spin_unlock(&qhp->lock);
683d6b92ffaSHans Petter Selasky 	return ret;
684d6b92ffaSHans Petter Selasky }
685d6b92ffaSHans Petter Selasky 
c4iw_detach_mcast(struct ibv_qp * ibqp,const union ibv_gid * gid,uint16_t lid)686d6b92ffaSHans Petter Selasky int c4iw_detach_mcast(struct ibv_qp *ibqp, const union ibv_gid *gid,
687d6b92ffaSHans Petter Selasky 		      uint16_t lid)
688d6b92ffaSHans Petter Selasky {
689d6b92ffaSHans Petter Selasky 	struct c4iw_qp *qhp = to_c4iw_qp(ibqp);
690d6b92ffaSHans Petter Selasky 	int ret;
691d6b92ffaSHans Petter Selasky 
692d6b92ffaSHans Petter Selasky 	pthread_spin_lock(&qhp->lock);
693d6b92ffaSHans Petter Selasky 	if (t4_wq_in_error(&qhp->wq))
694d6b92ffaSHans Petter Selasky 		c4iw_flush_qp(qhp);
695d6b92ffaSHans Petter Selasky 	ret = ibv_cmd_detach_mcast(ibqp, gid, lid);
696d6b92ffaSHans Petter Selasky 	pthread_spin_unlock(&qhp->lock);
697d6b92ffaSHans Petter Selasky 	return ret;
698d6b92ffaSHans Petter Selasky }
699d6b92ffaSHans Petter Selasky 
c4iw_async_event(struct ibv_async_event * event)700d6b92ffaSHans Petter Selasky void c4iw_async_event(struct ibv_async_event *event)
701d6b92ffaSHans Petter Selasky {
702d6b92ffaSHans Petter Selasky 	PDBG("%s type %d obj %p\n", __func__, event->event_type,
703d6b92ffaSHans Petter Selasky 	event->element.cq);
704d6b92ffaSHans Petter Selasky 
705d6b92ffaSHans Petter Selasky 	switch (event->event_type) {
706d6b92ffaSHans Petter Selasky 	case IBV_EVENT_CQ_ERR:
707d6b92ffaSHans Petter Selasky 		break;
708d6b92ffaSHans Petter Selasky 	case IBV_EVENT_QP_FATAL:
709d6b92ffaSHans Petter Selasky 	case IBV_EVENT_QP_REQ_ERR:
710d6b92ffaSHans Petter Selasky 	case IBV_EVENT_QP_ACCESS_ERR:
711d6b92ffaSHans Petter Selasky 	case IBV_EVENT_PATH_MIG_ERR: {
712d6b92ffaSHans Petter Selasky 		struct c4iw_qp *qhp = to_c4iw_qp(event->element.qp);
713d6b92ffaSHans Petter Selasky 		pthread_spin_lock(&qhp->lock);
714d6b92ffaSHans Petter Selasky 		c4iw_flush_qp(qhp);
715d6b92ffaSHans Petter Selasky 		pthread_spin_unlock(&qhp->lock);
716d6b92ffaSHans Petter Selasky 		break;
717d6b92ffaSHans Petter Selasky 	}
718d6b92ffaSHans Petter Selasky 	case IBV_EVENT_SQ_DRAINED:
719d6b92ffaSHans Petter Selasky 	case IBV_EVENT_PATH_MIG:
720d6b92ffaSHans Petter Selasky 	case IBV_EVENT_COMM_EST:
721d6b92ffaSHans Petter Selasky 	case IBV_EVENT_QP_LAST_WQE_REACHED:
722d6b92ffaSHans Petter Selasky 	default:
723d6b92ffaSHans Petter Selasky 		break;
724d6b92ffaSHans Petter Selasky 	}
725d6b92ffaSHans Petter Selasky }
726