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