infiniband: add in export.h for files using EXPORT_SYMBOL/THIS_MODULE
[pandora-kernel.git] / drivers / infiniband / core / verbs.c
1 /*
2  * Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
3  * Copyright (c) 2004 Infinicon Corporation.  All rights reserved.
4  * Copyright (c) 2004 Intel Corporation.  All rights reserved.
5  * Copyright (c) 2004 Topspin Corporation.  All rights reserved.
6  * Copyright (c) 2004 Voltaire Corporation.  All rights reserved.
7  * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
8  * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
9  *
10  * This software is available to you under a choice of one of two
11  * licenses.  You may choose to be licensed under the terms of the GNU
12  * General Public License (GPL) Version 2, available from the file
13  * COPYING in the main directory of this source tree, or the
14  * OpenIB.org BSD license below:
15  *
16  *     Redistribution and use in source and binary forms, with or
17  *     without modification, are permitted provided that the following
18  *     conditions are met:
19  *
20  *      - Redistributions of source code must retain the above
21  *        copyright notice, this list of conditions and the following
22  *        disclaimer.
23  *
24  *      - Redistributions in binary form must reproduce the above
25  *        copyright notice, this list of conditions and the following
26  *        disclaimer in the documentation and/or other materials
27  *        provided with the distribution.
28  *
29  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
33  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
34  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
35  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36  * SOFTWARE.
37  */
38
39 #include <linux/errno.h>
40 #include <linux/err.h>
41 #include <linux/export.h>
42 #include <linux/string.h>
43
44 #include <rdma/ib_verbs.h>
45 #include <rdma/ib_cache.h>
46
47 int ib_rate_to_mult(enum ib_rate rate)
48 {
49         switch (rate) {
50         case IB_RATE_2_5_GBPS: return  1;
51         case IB_RATE_5_GBPS:   return  2;
52         case IB_RATE_10_GBPS:  return  4;
53         case IB_RATE_20_GBPS:  return  8;
54         case IB_RATE_30_GBPS:  return 12;
55         case IB_RATE_40_GBPS:  return 16;
56         case IB_RATE_60_GBPS:  return 24;
57         case IB_RATE_80_GBPS:  return 32;
58         case IB_RATE_120_GBPS: return 48;
59         default:               return -1;
60         }
61 }
62 EXPORT_SYMBOL(ib_rate_to_mult);
63
64 enum ib_rate mult_to_ib_rate(int mult)
65 {
66         switch (mult) {
67         case 1:  return IB_RATE_2_5_GBPS;
68         case 2:  return IB_RATE_5_GBPS;
69         case 4:  return IB_RATE_10_GBPS;
70         case 8:  return IB_RATE_20_GBPS;
71         case 12: return IB_RATE_30_GBPS;
72         case 16: return IB_RATE_40_GBPS;
73         case 24: return IB_RATE_60_GBPS;
74         case 32: return IB_RATE_80_GBPS;
75         case 48: return IB_RATE_120_GBPS;
76         default: return IB_RATE_PORT_CURRENT;
77         }
78 }
79 EXPORT_SYMBOL(mult_to_ib_rate);
80
81 enum rdma_transport_type
82 rdma_node_get_transport(enum rdma_node_type node_type)
83 {
84         switch (node_type) {
85         case RDMA_NODE_IB_CA:
86         case RDMA_NODE_IB_SWITCH:
87         case RDMA_NODE_IB_ROUTER:
88                 return RDMA_TRANSPORT_IB;
89         case RDMA_NODE_RNIC:
90                 return RDMA_TRANSPORT_IWARP;
91         default:
92                 BUG();
93                 return 0;
94         }
95 }
96 EXPORT_SYMBOL(rdma_node_get_transport);
97
98 enum rdma_link_layer rdma_port_get_link_layer(struct ib_device *device, u8 port_num)
99 {
100         if (device->get_link_layer)
101                 return device->get_link_layer(device, port_num);
102
103         switch (rdma_node_get_transport(device->node_type)) {
104         case RDMA_TRANSPORT_IB:
105                 return IB_LINK_LAYER_INFINIBAND;
106         case RDMA_TRANSPORT_IWARP:
107                 return IB_LINK_LAYER_ETHERNET;
108         default:
109                 return IB_LINK_LAYER_UNSPECIFIED;
110         }
111 }
112 EXPORT_SYMBOL(rdma_port_get_link_layer);
113
114 /* Protection domains */
115
116 struct ib_pd *ib_alloc_pd(struct ib_device *device)
117 {
118         struct ib_pd *pd;
119
120         pd = device->alloc_pd(device, NULL, NULL);
121
122         if (!IS_ERR(pd)) {
123                 pd->device  = device;
124                 pd->uobject = NULL;
125                 atomic_set(&pd->usecnt, 0);
126         }
127
128         return pd;
129 }
130 EXPORT_SYMBOL(ib_alloc_pd);
131
132 int ib_dealloc_pd(struct ib_pd *pd)
133 {
134         if (atomic_read(&pd->usecnt))
135                 return -EBUSY;
136
137         return pd->device->dealloc_pd(pd);
138 }
139 EXPORT_SYMBOL(ib_dealloc_pd);
140
141 /* Address handles */
142
143 struct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
144 {
145         struct ib_ah *ah;
146
147         ah = pd->device->create_ah(pd, ah_attr);
148
149         if (!IS_ERR(ah)) {
150                 ah->device  = pd->device;
151                 ah->pd      = pd;
152                 ah->uobject = NULL;
153                 atomic_inc(&pd->usecnt);
154         }
155
156         return ah;
157 }
158 EXPORT_SYMBOL(ib_create_ah);
159
160 int ib_init_ah_from_wc(struct ib_device *device, u8 port_num, struct ib_wc *wc,
161                        struct ib_grh *grh, struct ib_ah_attr *ah_attr)
162 {
163         u32 flow_class;
164         u16 gid_index;
165         int ret;
166
167         memset(ah_attr, 0, sizeof *ah_attr);
168         ah_attr->dlid = wc->slid;
169         ah_attr->sl = wc->sl;
170         ah_attr->src_path_bits = wc->dlid_path_bits;
171         ah_attr->port_num = port_num;
172
173         if (wc->wc_flags & IB_WC_GRH) {
174                 ah_attr->ah_flags = IB_AH_GRH;
175                 ah_attr->grh.dgid = grh->sgid;
176
177                 ret = ib_find_cached_gid(device, &grh->dgid, &port_num,
178                                          &gid_index);
179                 if (ret)
180                         return ret;
181
182                 ah_attr->grh.sgid_index = (u8) gid_index;
183                 flow_class = be32_to_cpu(grh->version_tclass_flow);
184                 ah_attr->grh.flow_label = flow_class & 0xFFFFF;
185                 ah_attr->grh.hop_limit = 0xFF;
186                 ah_attr->grh.traffic_class = (flow_class >> 20) & 0xFF;
187         }
188         return 0;
189 }
190 EXPORT_SYMBOL(ib_init_ah_from_wc);
191
192 struct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, struct ib_wc *wc,
193                                    struct ib_grh *grh, u8 port_num)
194 {
195         struct ib_ah_attr ah_attr;
196         int ret;
197
198         ret = ib_init_ah_from_wc(pd->device, port_num, wc, grh, &ah_attr);
199         if (ret)
200                 return ERR_PTR(ret);
201
202         return ib_create_ah(pd, &ah_attr);
203 }
204 EXPORT_SYMBOL(ib_create_ah_from_wc);
205
206 int ib_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
207 {
208         return ah->device->modify_ah ?
209                 ah->device->modify_ah(ah, ah_attr) :
210                 -ENOSYS;
211 }
212 EXPORT_SYMBOL(ib_modify_ah);
213
214 int ib_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
215 {
216         return ah->device->query_ah ?
217                 ah->device->query_ah(ah, ah_attr) :
218                 -ENOSYS;
219 }
220 EXPORT_SYMBOL(ib_query_ah);
221
222 int ib_destroy_ah(struct ib_ah *ah)
223 {
224         struct ib_pd *pd;
225         int ret;
226
227         pd = ah->pd;
228         ret = ah->device->destroy_ah(ah);
229         if (!ret)
230                 atomic_dec(&pd->usecnt);
231
232         return ret;
233 }
234 EXPORT_SYMBOL(ib_destroy_ah);
235
236 /* Shared receive queues */
237
238 struct ib_srq *ib_create_srq(struct ib_pd *pd,
239                              struct ib_srq_init_attr *srq_init_attr)
240 {
241         struct ib_srq *srq;
242
243         if (!pd->device->create_srq)
244                 return ERR_PTR(-ENOSYS);
245
246         srq = pd->device->create_srq(pd, srq_init_attr, NULL);
247
248         if (!IS_ERR(srq)) {
249                 srq->device        = pd->device;
250                 srq->pd            = pd;
251                 srq->uobject       = NULL;
252                 srq->event_handler = srq_init_attr->event_handler;
253                 srq->srq_context   = srq_init_attr->srq_context;
254                 atomic_inc(&pd->usecnt);
255                 atomic_set(&srq->usecnt, 0);
256         }
257
258         return srq;
259 }
260 EXPORT_SYMBOL(ib_create_srq);
261
262 int ib_modify_srq(struct ib_srq *srq,
263                   struct ib_srq_attr *srq_attr,
264                   enum ib_srq_attr_mask srq_attr_mask)
265 {
266         return srq->device->modify_srq ?
267                 srq->device->modify_srq(srq, srq_attr, srq_attr_mask, NULL) :
268                 -ENOSYS;
269 }
270 EXPORT_SYMBOL(ib_modify_srq);
271
272 int ib_query_srq(struct ib_srq *srq,
273                  struct ib_srq_attr *srq_attr)
274 {
275         return srq->device->query_srq ?
276                 srq->device->query_srq(srq, srq_attr) : -ENOSYS;
277 }
278 EXPORT_SYMBOL(ib_query_srq);
279
280 int ib_destroy_srq(struct ib_srq *srq)
281 {
282         struct ib_pd *pd;
283         int ret;
284
285         if (atomic_read(&srq->usecnt))
286                 return -EBUSY;
287
288         pd = srq->pd;
289
290         ret = srq->device->destroy_srq(srq);
291         if (!ret)
292                 atomic_dec(&pd->usecnt);
293
294         return ret;
295 }
296 EXPORT_SYMBOL(ib_destroy_srq);
297
298 /* Queue pairs */
299
300 struct ib_qp *ib_create_qp(struct ib_pd *pd,
301                            struct ib_qp_init_attr *qp_init_attr)
302 {
303         struct ib_qp *qp;
304
305         qp = pd->device->create_qp(pd, qp_init_attr, NULL);
306
307         if (!IS_ERR(qp)) {
308                 qp->device        = pd->device;
309                 qp->pd            = pd;
310                 qp->send_cq       = qp_init_attr->send_cq;
311                 qp->recv_cq       = qp_init_attr->recv_cq;
312                 qp->srq           = qp_init_attr->srq;
313                 qp->uobject       = NULL;
314                 qp->event_handler = qp_init_attr->event_handler;
315                 qp->qp_context    = qp_init_attr->qp_context;
316                 qp->qp_type       = qp_init_attr->qp_type;
317                 atomic_inc(&pd->usecnt);
318                 atomic_inc(&qp_init_attr->send_cq->usecnt);
319                 atomic_inc(&qp_init_attr->recv_cq->usecnt);
320                 if (qp_init_attr->srq)
321                         atomic_inc(&qp_init_attr->srq->usecnt);
322         }
323
324         return qp;
325 }
326 EXPORT_SYMBOL(ib_create_qp);
327
328 static const struct {
329         int                     valid;
330         enum ib_qp_attr_mask    req_param[IB_QPT_RAW_ETHERTYPE + 1];
331         enum ib_qp_attr_mask    opt_param[IB_QPT_RAW_ETHERTYPE + 1];
332 } qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = {
333         [IB_QPS_RESET] = {
334                 [IB_QPS_RESET] = { .valid = 1 },
335                 [IB_QPS_INIT]  = {
336                         .valid = 1,
337                         .req_param = {
338                                 [IB_QPT_UD]  = (IB_QP_PKEY_INDEX                |
339                                                 IB_QP_PORT                      |
340                                                 IB_QP_QKEY),
341                                 [IB_QPT_UC]  = (IB_QP_PKEY_INDEX                |
342                                                 IB_QP_PORT                      |
343                                                 IB_QP_ACCESS_FLAGS),
344                                 [IB_QPT_RC]  = (IB_QP_PKEY_INDEX                |
345                                                 IB_QP_PORT                      |
346                                                 IB_QP_ACCESS_FLAGS),
347                                 [IB_QPT_SMI] = (IB_QP_PKEY_INDEX                |
348                                                 IB_QP_QKEY),
349                                 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX                |
350                                                 IB_QP_QKEY),
351                         }
352                 },
353         },
354         [IB_QPS_INIT]  = {
355                 [IB_QPS_RESET] = { .valid = 1 },
356                 [IB_QPS_ERR] =   { .valid = 1 },
357                 [IB_QPS_INIT]  = {
358                         .valid = 1,
359                         .opt_param = {
360                                 [IB_QPT_UD]  = (IB_QP_PKEY_INDEX                |
361                                                 IB_QP_PORT                      |
362                                                 IB_QP_QKEY),
363                                 [IB_QPT_UC]  = (IB_QP_PKEY_INDEX                |
364                                                 IB_QP_PORT                      |
365                                                 IB_QP_ACCESS_FLAGS),
366                                 [IB_QPT_RC]  = (IB_QP_PKEY_INDEX                |
367                                                 IB_QP_PORT                      |
368                                                 IB_QP_ACCESS_FLAGS),
369                                 [IB_QPT_SMI] = (IB_QP_PKEY_INDEX                |
370                                                 IB_QP_QKEY),
371                                 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX                |
372                                                 IB_QP_QKEY),
373                         }
374                 },
375                 [IB_QPS_RTR]   = {
376                         .valid = 1,
377                         .req_param = {
378                                 [IB_QPT_UC]  = (IB_QP_AV                        |
379                                                 IB_QP_PATH_MTU                  |
380                                                 IB_QP_DEST_QPN                  |
381                                                 IB_QP_RQ_PSN),
382                                 [IB_QPT_RC]  = (IB_QP_AV                        |
383                                                 IB_QP_PATH_MTU                  |
384                                                 IB_QP_DEST_QPN                  |
385                                                 IB_QP_RQ_PSN                    |
386                                                 IB_QP_MAX_DEST_RD_ATOMIC        |
387                                                 IB_QP_MIN_RNR_TIMER),
388                         },
389                         .opt_param = {
390                                  [IB_QPT_UD]  = (IB_QP_PKEY_INDEX               |
391                                                  IB_QP_QKEY),
392                                  [IB_QPT_UC]  = (IB_QP_ALT_PATH                 |
393                                                  IB_QP_ACCESS_FLAGS             |
394                                                  IB_QP_PKEY_INDEX),
395                                  [IB_QPT_RC]  = (IB_QP_ALT_PATH                 |
396                                                  IB_QP_ACCESS_FLAGS             |
397                                                  IB_QP_PKEY_INDEX),
398                                  [IB_QPT_SMI] = (IB_QP_PKEY_INDEX               |
399                                                  IB_QP_QKEY),
400                                  [IB_QPT_GSI] = (IB_QP_PKEY_INDEX               |
401                                                  IB_QP_QKEY),
402                          }
403                 }
404         },
405         [IB_QPS_RTR]   = {
406                 [IB_QPS_RESET] = { .valid = 1 },
407                 [IB_QPS_ERR] =   { .valid = 1 },
408                 [IB_QPS_RTS]   = {
409                         .valid = 1,
410                         .req_param = {
411                                 [IB_QPT_UD]  = IB_QP_SQ_PSN,
412                                 [IB_QPT_UC]  = IB_QP_SQ_PSN,
413                                 [IB_QPT_RC]  = (IB_QP_TIMEOUT                   |
414                                                 IB_QP_RETRY_CNT                 |
415                                                 IB_QP_RNR_RETRY                 |
416                                                 IB_QP_SQ_PSN                    |
417                                                 IB_QP_MAX_QP_RD_ATOMIC),
418                                 [IB_QPT_SMI] = IB_QP_SQ_PSN,
419                                 [IB_QPT_GSI] = IB_QP_SQ_PSN,
420                         },
421                         .opt_param = {
422                                  [IB_QPT_UD]  = (IB_QP_CUR_STATE                |
423                                                  IB_QP_QKEY),
424                                  [IB_QPT_UC]  = (IB_QP_CUR_STATE                |
425                                                  IB_QP_ALT_PATH                 |
426                                                  IB_QP_ACCESS_FLAGS             |
427                                                  IB_QP_PATH_MIG_STATE),
428                                  [IB_QPT_RC]  = (IB_QP_CUR_STATE                |
429                                                  IB_QP_ALT_PATH                 |
430                                                  IB_QP_ACCESS_FLAGS             |
431                                                  IB_QP_MIN_RNR_TIMER            |
432                                                  IB_QP_PATH_MIG_STATE),
433                                  [IB_QPT_SMI] = (IB_QP_CUR_STATE                |
434                                                  IB_QP_QKEY),
435                                  [IB_QPT_GSI] = (IB_QP_CUR_STATE                |
436                                                  IB_QP_QKEY),
437                          }
438                 }
439         },
440         [IB_QPS_RTS]   = {
441                 [IB_QPS_RESET] = { .valid = 1 },
442                 [IB_QPS_ERR] =   { .valid = 1 },
443                 [IB_QPS_RTS]   = {
444                         .valid = 1,
445                         .opt_param = {
446                                 [IB_QPT_UD]  = (IB_QP_CUR_STATE                 |
447                                                 IB_QP_QKEY),
448                                 [IB_QPT_UC]  = (IB_QP_CUR_STATE                 |
449                                                 IB_QP_ACCESS_FLAGS              |
450                                                 IB_QP_ALT_PATH                  |
451                                                 IB_QP_PATH_MIG_STATE),
452                                 [IB_QPT_RC]  = (IB_QP_CUR_STATE                 |
453                                                 IB_QP_ACCESS_FLAGS              |
454                                                 IB_QP_ALT_PATH                  |
455                                                 IB_QP_PATH_MIG_STATE            |
456                                                 IB_QP_MIN_RNR_TIMER),
457                                 [IB_QPT_SMI] = (IB_QP_CUR_STATE                 |
458                                                 IB_QP_QKEY),
459                                 [IB_QPT_GSI] = (IB_QP_CUR_STATE                 |
460                                                 IB_QP_QKEY),
461                         }
462                 },
463                 [IB_QPS_SQD]   = {
464                         .valid = 1,
465                         .opt_param = {
466                                 [IB_QPT_UD]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
467                                 [IB_QPT_UC]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
468                                 [IB_QPT_RC]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
469                                 [IB_QPT_SMI] = IB_QP_EN_SQD_ASYNC_NOTIFY,
470                                 [IB_QPT_GSI] = IB_QP_EN_SQD_ASYNC_NOTIFY
471                         }
472                 },
473         },
474         [IB_QPS_SQD]   = {
475                 [IB_QPS_RESET] = { .valid = 1 },
476                 [IB_QPS_ERR] =   { .valid = 1 },
477                 [IB_QPS_RTS]   = {
478                         .valid = 1,
479                         .opt_param = {
480                                 [IB_QPT_UD]  = (IB_QP_CUR_STATE                 |
481                                                 IB_QP_QKEY),
482                                 [IB_QPT_UC]  = (IB_QP_CUR_STATE                 |
483                                                 IB_QP_ALT_PATH                  |
484                                                 IB_QP_ACCESS_FLAGS              |
485                                                 IB_QP_PATH_MIG_STATE),
486                                 [IB_QPT_RC]  = (IB_QP_CUR_STATE                 |
487                                                 IB_QP_ALT_PATH                  |
488                                                 IB_QP_ACCESS_FLAGS              |
489                                                 IB_QP_MIN_RNR_TIMER             |
490                                                 IB_QP_PATH_MIG_STATE),
491                                 [IB_QPT_SMI] = (IB_QP_CUR_STATE                 |
492                                                 IB_QP_QKEY),
493                                 [IB_QPT_GSI] = (IB_QP_CUR_STATE                 |
494                                                 IB_QP_QKEY),
495                         }
496                 },
497                 [IB_QPS_SQD]   = {
498                         .valid = 1,
499                         .opt_param = {
500                                 [IB_QPT_UD]  = (IB_QP_PKEY_INDEX                |
501                                                 IB_QP_QKEY),
502                                 [IB_QPT_UC]  = (IB_QP_AV                        |
503                                                 IB_QP_ALT_PATH                  |
504                                                 IB_QP_ACCESS_FLAGS              |
505                                                 IB_QP_PKEY_INDEX                |
506                                                 IB_QP_PATH_MIG_STATE),
507                                 [IB_QPT_RC]  = (IB_QP_PORT                      |
508                                                 IB_QP_AV                        |
509                                                 IB_QP_TIMEOUT                   |
510                                                 IB_QP_RETRY_CNT                 |
511                                                 IB_QP_RNR_RETRY                 |
512                                                 IB_QP_MAX_QP_RD_ATOMIC          |
513                                                 IB_QP_MAX_DEST_RD_ATOMIC        |
514                                                 IB_QP_ALT_PATH                  |
515                                                 IB_QP_ACCESS_FLAGS              |
516                                                 IB_QP_PKEY_INDEX                |
517                                                 IB_QP_MIN_RNR_TIMER             |
518                                                 IB_QP_PATH_MIG_STATE),
519                                 [IB_QPT_SMI] = (IB_QP_PKEY_INDEX                |
520                                                 IB_QP_QKEY),
521                                 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX                |
522                                                 IB_QP_QKEY),
523                         }
524                 }
525         },
526         [IB_QPS_SQE]   = {
527                 [IB_QPS_RESET] = { .valid = 1 },
528                 [IB_QPS_ERR] =   { .valid = 1 },
529                 [IB_QPS_RTS]   = {
530                         .valid = 1,
531                         .opt_param = {
532                                 [IB_QPT_UD]  = (IB_QP_CUR_STATE                 |
533                                                 IB_QP_QKEY),
534                                 [IB_QPT_UC]  = (IB_QP_CUR_STATE                 |
535                                                 IB_QP_ACCESS_FLAGS),
536                                 [IB_QPT_SMI] = (IB_QP_CUR_STATE                 |
537                                                 IB_QP_QKEY),
538                                 [IB_QPT_GSI] = (IB_QP_CUR_STATE                 |
539                                                 IB_QP_QKEY),
540                         }
541                 }
542         },
543         [IB_QPS_ERR] = {
544                 [IB_QPS_RESET] = { .valid = 1 },
545                 [IB_QPS_ERR] =   { .valid = 1 }
546         }
547 };
548
549 int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
550                        enum ib_qp_type type, enum ib_qp_attr_mask mask)
551 {
552         enum ib_qp_attr_mask req_param, opt_param;
553
554         if (cur_state  < 0 || cur_state  > IB_QPS_ERR ||
555             next_state < 0 || next_state > IB_QPS_ERR)
556                 return 0;
557
558         if (mask & IB_QP_CUR_STATE  &&
559             cur_state != IB_QPS_RTR && cur_state != IB_QPS_RTS &&
560             cur_state != IB_QPS_SQD && cur_state != IB_QPS_SQE)
561                 return 0;
562
563         if (!qp_state_table[cur_state][next_state].valid)
564                 return 0;
565
566         req_param = qp_state_table[cur_state][next_state].req_param[type];
567         opt_param = qp_state_table[cur_state][next_state].opt_param[type];
568
569         if ((mask & req_param) != req_param)
570                 return 0;
571
572         if (mask & ~(req_param | opt_param | IB_QP_STATE))
573                 return 0;
574
575         return 1;
576 }
577 EXPORT_SYMBOL(ib_modify_qp_is_ok);
578
579 int ib_modify_qp(struct ib_qp *qp,
580                  struct ib_qp_attr *qp_attr,
581                  int qp_attr_mask)
582 {
583         return qp->device->modify_qp(qp, qp_attr, qp_attr_mask, NULL);
584 }
585 EXPORT_SYMBOL(ib_modify_qp);
586
587 int ib_query_qp(struct ib_qp *qp,
588                 struct ib_qp_attr *qp_attr,
589                 int qp_attr_mask,
590                 struct ib_qp_init_attr *qp_init_attr)
591 {
592         return qp->device->query_qp ?
593                 qp->device->query_qp(qp, qp_attr, qp_attr_mask, qp_init_attr) :
594                 -ENOSYS;
595 }
596 EXPORT_SYMBOL(ib_query_qp);
597
598 int ib_destroy_qp(struct ib_qp *qp)
599 {
600         struct ib_pd *pd;
601         struct ib_cq *scq, *rcq;
602         struct ib_srq *srq;
603         int ret;
604
605         pd  = qp->pd;
606         scq = qp->send_cq;
607         rcq = qp->recv_cq;
608         srq = qp->srq;
609
610         ret = qp->device->destroy_qp(qp);
611         if (!ret) {
612                 atomic_dec(&pd->usecnt);
613                 atomic_dec(&scq->usecnt);
614                 atomic_dec(&rcq->usecnt);
615                 if (srq)
616                         atomic_dec(&srq->usecnt);
617         }
618
619         return ret;
620 }
621 EXPORT_SYMBOL(ib_destroy_qp);
622
623 /* Completion queues */
624
625 struct ib_cq *ib_create_cq(struct ib_device *device,
626                            ib_comp_handler comp_handler,
627                            void (*event_handler)(struct ib_event *, void *),
628                            void *cq_context, int cqe, int comp_vector)
629 {
630         struct ib_cq *cq;
631
632         cq = device->create_cq(device, cqe, comp_vector, NULL, NULL);
633
634         if (!IS_ERR(cq)) {
635                 cq->device        = device;
636                 cq->uobject       = NULL;
637                 cq->comp_handler  = comp_handler;
638                 cq->event_handler = event_handler;
639                 cq->cq_context    = cq_context;
640                 atomic_set(&cq->usecnt, 0);
641         }
642
643         return cq;
644 }
645 EXPORT_SYMBOL(ib_create_cq);
646
647 int ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
648 {
649         return cq->device->modify_cq ?
650                 cq->device->modify_cq(cq, cq_count, cq_period) : -ENOSYS;
651 }
652 EXPORT_SYMBOL(ib_modify_cq);
653
654 int ib_destroy_cq(struct ib_cq *cq)
655 {
656         if (atomic_read(&cq->usecnt))
657                 return -EBUSY;
658
659         return cq->device->destroy_cq(cq);
660 }
661 EXPORT_SYMBOL(ib_destroy_cq);
662
663 int ib_resize_cq(struct ib_cq *cq, int cqe)
664 {
665         return cq->device->resize_cq ?
666                 cq->device->resize_cq(cq, cqe, NULL) : -ENOSYS;
667 }
668 EXPORT_SYMBOL(ib_resize_cq);
669
670 /* Memory regions */
671
672 struct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags)
673 {
674         struct ib_mr *mr;
675
676         mr = pd->device->get_dma_mr(pd, mr_access_flags);
677
678         if (!IS_ERR(mr)) {
679                 mr->device  = pd->device;
680                 mr->pd      = pd;
681                 mr->uobject = NULL;
682                 atomic_inc(&pd->usecnt);
683                 atomic_set(&mr->usecnt, 0);
684         }
685
686         return mr;
687 }
688 EXPORT_SYMBOL(ib_get_dma_mr);
689
690 struct ib_mr *ib_reg_phys_mr(struct ib_pd *pd,
691                              struct ib_phys_buf *phys_buf_array,
692                              int num_phys_buf,
693                              int mr_access_flags,
694                              u64 *iova_start)
695 {
696         struct ib_mr *mr;
697
698         if (!pd->device->reg_phys_mr)
699                 return ERR_PTR(-ENOSYS);
700
701         mr = pd->device->reg_phys_mr(pd, phys_buf_array, num_phys_buf,
702                                      mr_access_flags, iova_start);
703
704         if (!IS_ERR(mr)) {
705                 mr->device  = pd->device;
706                 mr->pd      = pd;
707                 mr->uobject = NULL;
708                 atomic_inc(&pd->usecnt);
709                 atomic_set(&mr->usecnt, 0);
710         }
711
712         return mr;
713 }
714 EXPORT_SYMBOL(ib_reg_phys_mr);
715
716 int ib_rereg_phys_mr(struct ib_mr *mr,
717                      int mr_rereg_mask,
718                      struct ib_pd *pd,
719                      struct ib_phys_buf *phys_buf_array,
720                      int num_phys_buf,
721                      int mr_access_flags,
722                      u64 *iova_start)
723 {
724         struct ib_pd *old_pd;
725         int ret;
726
727         if (!mr->device->rereg_phys_mr)
728                 return -ENOSYS;
729
730         if (atomic_read(&mr->usecnt))
731                 return -EBUSY;
732
733         old_pd = mr->pd;
734
735         ret = mr->device->rereg_phys_mr(mr, mr_rereg_mask, pd,
736                                         phys_buf_array, num_phys_buf,
737                                         mr_access_flags, iova_start);
738
739         if (!ret && (mr_rereg_mask & IB_MR_REREG_PD)) {
740                 atomic_dec(&old_pd->usecnt);
741                 atomic_inc(&pd->usecnt);
742         }
743
744         return ret;
745 }
746 EXPORT_SYMBOL(ib_rereg_phys_mr);
747
748 int ib_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr)
749 {
750         return mr->device->query_mr ?
751                 mr->device->query_mr(mr, mr_attr) : -ENOSYS;
752 }
753 EXPORT_SYMBOL(ib_query_mr);
754
755 int ib_dereg_mr(struct ib_mr *mr)
756 {
757         struct ib_pd *pd;
758         int ret;
759
760         if (atomic_read(&mr->usecnt))
761                 return -EBUSY;
762
763         pd = mr->pd;
764         ret = mr->device->dereg_mr(mr);
765         if (!ret)
766                 atomic_dec(&pd->usecnt);
767
768         return ret;
769 }
770 EXPORT_SYMBOL(ib_dereg_mr);
771
772 struct ib_mr *ib_alloc_fast_reg_mr(struct ib_pd *pd, int max_page_list_len)
773 {
774         struct ib_mr *mr;
775
776         if (!pd->device->alloc_fast_reg_mr)
777                 return ERR_PTR(-ENOSYS);
778
779         mr = pd->device->alloc_fast_reg_mr(pd, max_page_list_len);
780
781         if (!IS_ERR(mr)) {
782                 mr->device  = pd->device;
783                 mr->pd      = pd;
784                 mr->uobject = NULL;
785                 atomic_inc(&pd->usecnt);
786                 atomic_set(&mr->usecnt, 0);
787         }
788
789         return mr;
790 }
791 EXPORT_SYMBOL(ib_alloc_fast_reg_mr);
792
793 struct ib_fast_reg_page_list *ib_alloc_fast_reg_page_list(struct ib_device *device,
794                                                           int max_page_list_len)
795 {
796         struct ib_fast_reg_page_list *page_list;
797
798         if (!device->alloc_fast_reg_page_list)
799                 return ERR_PTR(-ENOSYS);
800
801         page_list = device->alloc_fast_reg_page_list(device, max_page_list_len);
802
803         if (!IS_ERR(page_list)) {
804                 page_list->device = device;
805                 page_list->max_page_list_len = max_page_list_len;
806         }
807
808         return page_list;
809 }
810 EXPORT_SYMBOL(ib_alloc_fast_reg_page_list);
811
812 void ib_free_fast_reg_page_list(struct ib_fast_reg_page_list *page_list)
813 {
814         page_list->device->free_fast_reg_page_list(page_list);
815 }
816 EXPORT_SYMBOL(ib_free_fast_reg_page_list);
817
818 /* Memory windows */
819
820 struct ib_mw *ib_alloc_mw(struct ib_pd *pd)
821 {
822         struct ib_mw *mw;
823
824         if (!pd->device->alloc_mw)
825                 return ERR_PTR(-ENOSYS);
826
827         mw = pd->device->alloc_mw(pd);
828         if (!IS_ERR(mw)) {
829                 mw->device  = pd->device;
830                 mw->pd      = pd;
831                 mw->uobject = NULL;
832                 atomic_inc(&pd->usecnt);
833         }
834
835         return mw;
836 }
837 EXPORT_SYMBOL(ib_alloc_mw);
838
839 int ib_dealloc_mw(struct ib_mw *mw)
840 {
841         struct ib_pd *pd;
842         int ret;
843
844         pd = mw->pd;
845         ret = mw->device->dealloc_mw(mw);
846         if (!ret)
847                 atomic_dec(&pd->usecnt);
848
849         return ret;
850 }
851 EXPORT_SYMBOL(ib_dealloc_mw);
852
853 /* "Fast" memory regions */
854
855 struct ib_fmr *ib_alloc_fmr(struct ib_pd *pd,
856                             int mr_access_flags,
857                             struct ib_fmr_attr *fmr_attr)
858 {
859         struct ib_fmr *fmr;
860
861         if (!pd->device->alloc_fmr)
862                 return ERR_PTR(-ENOSYS);
863
864         fmr = pd->device->alloc_fmr(pd, mr_access_flags, fmr_attr);
865         if (!IS_ERR(fmr)) {
866                 fmr->device = pd->device;
867                 fmr->pd     = pd;
868                 atomic_inc(&pd->usecnt);
869         }
870
871         return fmr;
872 }
873 EXPORT_SYMBOL(ib_alloc_fmr);
874
875 int ib_unmap_fmr(struct list_head *fmr_list)
876 {
877         struct ib_fmr *fmr;
878
879         if (list_empty(fmr_list))
880                 return 0;
881
882         fmr = list_entry(fmr_list->next, struct ib_fmr, list);
883         return fmr->device->unmap_fmr(fmr_list);
884 }
885 EXPORT_SYMBOL(ib_unmap_fmr);
886
887 int ib_dealloc_fmr(struct ib_fmr *fmr)
888 {
889         struct ib_pd *pd;
890         int ret;
891
892         pd = fmr->pd;
893         ret = fmr->device->dealloc_fmr(fmr);
894         if (!ret)
895                 atomic_dec(&pd->usecnt);
896
897         return ret;
898 }
899 EXPORT_SYMBOL(ib_dealloc_fmr);
900
901 /* Multicast groups */
902
903 int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
904 {
905         if (!qp->device->attach_mcast)
906                 return -ENOSYS;
907         if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
908                 return -EINVAL;
909
910         return qp->device->attach_mcast(qp, gid, lid);
911 }
912 EXPORT_SYMBOL(ib_attach_mcast);
913
914 int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
915 {
916         if (!qp->device->detach_mcast)
917                 return -ENOSYS;
918         if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
919                 return -EINVAL;
920
921         return qp->device->detach_mcast(qp, gid, lid);
922 }
923 EXPORT_SYMBOL(ib_detach_mcast);