[IBAL, HW] Remove pointers from ci_umv_buf_t.
[mirror/winof/.git] / hw / mthca / kernel / mthca_provider.h
1 /*\r
2  * Copyright (c) 2004 Topspin Communications.  All rights reserved.\r
3  * Copyright (c) 2005 Cisco Systems.  All rights reserved.\r
4  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.\r
5  *\r
6  * This software is available to you under a choice of one of two\r
7  * licenses.  You may choose to be licensed under the terms of the GNU\r
8  * General Public License (GPL) Version 2, available from the file\r
9  * COPYING in the main directory of this source tree, or the\r
10  * OpenIB.org BSD license below:\r
11  *\r
12  *     Redistribution and use in source and binary forms, with or\r
13  *     without modification, are permitted provided that the following\r
14  *     conditions are met:\r
15  *\r
16  *      - Redistributions of source code must retain the above\r
17  *        copyright notice, this list of conditions and the following\r
18  *        disclaimer.\r
19  *\r
20  *      - Redistributions in binary form must reproduce the above\r
21  *        copyright notice, this list of conditions and the following\r
22  *        disclaimer in the documentation and/or other materials\r
23  *        provided with the distribution.\r
24  *\r
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
26  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
27  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
28  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
29  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
30  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
31  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
32  * SOFTWARE.\r
33  *\r
34  * $Id$\r
35  */\r
36 \r
37 #ifndef MTHCA_PROVIDER_H\r
38 #define MTHCA_PROVIDER_H\r
39 \r
40 #include <ib_verbs.h>\r
41 #include <ib_pack.h>\r
42 #include <iba/ib_ci.h>\r
43 \r
44 typedef uint32_t mthca_mpt_access_t;\r
45 #define MTHCA_MPT_FLAG_ATOMIC        (1 << 14)\r
46 #define MTHCA_MPT_FLAG_REMOTE_WRITE  (1 << 13)\r
47 #define MTHCA_MPT_FLAG_REMOTE_READ   (1 << 12)\r
48 #define MTHCA_MPT_FLAG_LOCAL_WRITE   (1 << 11)\r
49 #define MTHCA_MPT_FLAG_LOCAL_READ    (1 << 10)\r
50 \r
51 union mthca_buf {\r
52         struct scatterlist direct;\r
53         struct scatterlist *page_list;\r
54 };\r
55 \r
56 struct mthca_uar {\r
57         PFN_NUMBER pfn;\r
58         int           index;\r
59 };\r
60 \r
61 struct mthca_user_db_table;\r
62 \r
63 struct mthca_ucontext {\r
64         struct ib_ucontext          ibucontext;\r
65         struct mthca_uar            uar;\r
66         struct mthca_user_db_table *db_tab;\r
67         // for user UAR \r
68         PMDL    mdl;\r
69         PVOID   kva;\r
70         SIZE_T uar_size;        \r
71 };\r
72 \r
73 struct mthca_mtt;\r
74 \r
75 struct mthca_mr {\r
76         //NB: the start of this structure is to be equal to mlnx_mro_t !\r
77         //NB: the structure was not inserted here for not to mix driver and provider structures\r
78         struct ib_mr      ibmr;\r
79         struct mthca_mtt *mtt;\r
80         int                     iobuf_used;\r
81         mt_iobuf_t      iobuf;\r
82         void *secure_handle;\r
83 };\r
84 \r
85 struct mthca_fmr {\r
86         struct ib_fmr      ibfmr;\r
87         struct ib_fmr_attr attr;\r
88         struct mthca_mtt  *mtt;\r
89         int                maps;\r
90         union {\r
91                 struct {\r
92                         struct mthca_mpt_entry __iomem *mpt;\r
93                         u64 __iomem *mtts;\r
94                 } tavor;\r
95                 struct {\r
96                         struct mthca_mpt_entry *mpt;\r
97                         __be64 *mtts;\r
98                 } arbel;\r
99         } mem;\r
100 };\r
101 \r
102 struct mthca_pd {\r
103         struct ib_pd    ibpd;\r
104         u32             pd_num;\r
105         atomic_t        sqp_count;\r
106         struct mthca_mr ntmr;\r
107         int             privileged;\r
108 };\r
109 \r
110 struct mthca_eq {\r
111         struct mthca_dev      *dev;\r
112         int                    eqn;\r
113         int                    eq_num;\r
114         u32                    eqn_mask;\r
115         u32                    cons_index;\r
116         u16                    msi_x_vector;\r
117         u16                    msi_x_entry;\r
118         int                    have_irq;\r
119         int                    nent;\r
120         struct scatterlist *page_list;\r
121         struct mthca_mr        mr;\r
122         KDPC                            dpc;                    /* DPC for MSI-X interrupts */\r
123         spinlock_t  lock;                       /* spinlock for simult DPCs */\r
124 };\r
125 \r
126 struct mthca_av;\r
127 \r
128 enum mthca_ah_type {\r
129         MTHCA_AH_ON_HCA,\r
130         MTHCA_AH_PCI_POOL,\r
131         MTHCA_AH_KMALLOC\r
132 };\r
133 \r
134 struct mthca_ah {\r
135         struct ib_ah       ibah;\r
136         enum mthca_ah_type type;\r
137         u32                key;\r
138         struct mthca_av   *av;\r
139         dma_addr_t         avdma;\r
140 };\r
141 \r
142 /*\r
143  * Quick description of our CQ/QP locking scheme:\r
144  *\r
145  * We have one global lock that protects dev->cq/qp_table.  Each\r
146  * struct mthca_cq/qp also has its own lock.  An individual qp lock\r
147  * may be taken inside of an individual cq lock.  Both cqs attached to\r
148  * a qp may be locked, with the send cq locked first.  No other\r
149  * nesting should be done.\r
150  *\r
151  * Each struct mthca_cq/qp also has an atomic_t ref count.  The\r
152  * pointer from the cq/qp_table to the struct counts as one reference.\r
153  * This reference also is good for access through the consumer API, so\r
154  * modifying the CQ/QP etc doesn't need to take another reference.\r
155  * Access because of a completion being polled does need a reference.\r
156  *\r
157  * Finally, each struct mthca_cq/qp has a wait_queue_head_t for the\r
158  * destroy function to sleep on.\r
159  *\r
160  * This means that access from the consumer API requires nothing but\r
161  * taking the struct's lock.\r
162  *\r
163  * Access because of a completion event should go as follows:\r
164  * - lock cq/qp_table and look up struct\r
165  * - increment ref count in struct\r
166  * - drop cq/qp_table lock\r
167  * - lock struct, do your thing, and unlock struct\r
168  * - decrement ref count; if zero, wake up waiters\r
169  *\r
170  * To destroy a CQ/QP, we can do the following:\r
171  * - lock cq/qp_table, remove pointer, unlock cq/qp_table lock\r
172  * - decrement ref count\r
173  * - wait_event until ref count is zero\r
174  *\r
175  * It is the consumer's responsibilty to make sure that no QP\r
176  * operations (WQE posting or state modification) are pending when the\r
177  * QP is destroyed.  Also, the consumer must make sure that calls to\r
178  * qp_modify are serialized.\r
179  *\r
180  * Possible optimizations (wait for profile data to see if/where we\r
181  * have locks bouncing between CPUs):\r
182  * - split cq/qp table lock into n separate (cache-aligned) locks,\r
183  *   indexed (say) by the page in the table\r
184  * - split QP struct lock into three (one for common info, one for the\r
185  *   send queue and one for the receive queue)\r
186  */\r
187 //TODO: check correctness of the above requirement: "It is the consumer's responsibilty to make sure that no QP\r
188 // operations (WQE posting or state modification) are pending when the QP is destroyed"\r
189 \r
190 struct mthca_cq {\r
191         struct ib_cq           ibcq;\r
192         void                                            *cq_context;    // leo: for IBAL shim\r
193         spinlock_t             lock;\r
194         atomic_t               refcount;\r
195         int                    cqn;\r
196         u32                    cons_index;\r
197         int                    is_direct;\r
198         int                    is_kernel;\r
199 \r
200         /* Next fields are Arbel only */\r
201         int                    set_ci_db_index;\r
202         __be32                *set_ci_db;\r
203         int                    arm_db_index;\r
204         __be32                *arm_db;\r
205         int                    arm_sn;\r
206         int                    u_arm_db_index;\r
207         int                *p_u_arm_sn;\r
208 \r
209         union mthca_buf        queue;\r
210         struct mthca_mr        mr;\r
211         wait_queue_head_t      wait;\r
212         KMUTEX                      mutex;\r
213 };\r
214 \r
215 struct mthca_srq {\r
216         struct ib_srq           ibsrq;\r
217         spinlock_t              lock;\r
218         atomic_t                refcount;\r
219         int                     srqn;\r
220         int                     max;\r
221         int                     max_gs;\r
222         int                     wqe_shift;\r
223         int                     first_free;\r
224         int                     last_free;\r
225         u16                     counter;  /* Arbel only */\r
226         int                     db_index; /* Arbel only */\r
227         __be32                 *db;       /* Arbel only */\r
228         void                   *last;\r
229 \r
230         int                     is_direct;\r
231         u64                    *wrid;\r
232         union mthca_buf         queue;\r
233         struct mthca_mr         mr;\r
234 \r
235         wait_queue_head_t       wait;\r
236         KMUTEX                  mutex;\r
237         void                            *srq_context;   \r
238 };\r
239 \r
240 struct mthca_wq {\r
241         spinlock_t lock;\r
242         int        max;\r
243         unsigned   next_ind;\r
244         unsigned   last_comp;\r
245         unsigned   head;\r
246         unsigned   tail;\r
247         void      *last;\r
248         int        max_gs;\r
249         int        wqe_shift;\r
250 \r
251         int        db_index;    /* Arbel only */\r
252         __be32    *db;\r
253 };\r
254 \r
255 struct mthca_qp {\r
256         struct ib_qp           ibqp;\r
257         void                                            *qp_context;    // leo: for IBAL shim\r
258         //TODO: added just because absense of ibv_query_qp\r
259         // thereafter it may be worth to be replaced by struct ib_qp_attr qp_attr;\r
260         struct ib_qp_init_attr qp_init_attr;    // leo: for query_qp\r
261         atomic_t               refcount;\r
262         u32                    qpn;\r
263         int                    is_direct;\r
264         u8                     transport;\r
265         u8                     state;\r
266         u8                     atomic_rd_en;\r
267         u8                     resp_depth;\r
268 \r
269         struct mthca_mr        mr;\r
270 \r
271         struct mthca_wq        rq;\r
272         struct mthca_wq        sq;\r
273         enum ib_sig_type       sq_policy;\r
274         int                    send_wqe_offset;\r
275         int                    max_inline_data;\r
276 \r
277         u64                   *wrid;\r
278         union mthca_buf        queue;\r
279 \r
280         wait_queue_head_t      wait;\r
281         KMUTEX                      mutex;\r
282 };\r
283 \r
284 struct mthca_sqp {\r
285         struct mthca_qp qp;\r
286         int             port;\r
287         int             pkey_index;\r
288         u32             qkey;\r
289         u32             send_psn;\r
290         struct ib_ud_header ud_header;\r
291         struct scatterlist sg;\r
292 };\r
293 \r
294 static inline struct mthca_ucontext *to_mucontext(struct ib_ucontext *ibucontext)\r
295 {\r
296         return container_of(ibucontext, struct mthca_ucontext, ibucontext);\r
297 }\r
298 \r
299 static inline struct mthca_fmr *to_mfmr(struct ib_fmr *ibfmr)\r
300 {\r
301         return container_of(ibfmr, struct mthca_fmr, ibfmr);\r
302 }\r
303 \r
304 static inline struct mthca_mr *to_mmr(struct ib_mr *ibmr)\r
305 {\r
306         return container_of(ibmr, struct mthca_mr, ibmr);\r
307 }\r
308 \r
309 static inline struct mthca_pd *to_mpd(struct ib_pd *ibpd)\r
310 {\r
311         return container_of(ibpd, struct mthca_pd, ibpd);\r
312 }\r
313 \r
314 static inline struct mthca_ah *to_mah(struct ib_ah *ibah)\r
315 {\r
316         return container_of(ibah, struct mthca_ah, ibah);\r
317 }\r
318 \r
319 static inline struct mthca_cq *to_mcq(struct ib_cq *ibcq)\r
320 {\r
321         return container_of(ibcq, struct mthca_cq, ibcq);\r
322 }\r
323 \r
324 static inline struct mthca_srq *to_msrq(struct ib_srq *ibsrq)\r
325 {\r
326         return container_of(ibsrq, struct mthca_srq, ibsrq);\r
327 }\r
328 \r
329 static inline struct mthca_qp *to_mqp(struct ib_qp *ibqp)\r
330 {\r
331         return container_of(ibqp, struct mthca_qp, ibqp);\r
332 }\r
333 \r
334 static inline struct mthca_sqp *to_msqp(struct mthca_qp *qp)\r
335 {\r
336         return container_of(qp, struct mthca_sqp, qp);\r
337 }\r
338 \r
339 static inline uint8_t start_port(struct ib_device *device)\r
340 {\r
341         return device->node_type == IB_NODE_SWITCH ? 0 : 1;\r
342 }\r
343 \r
344 static inline uint8_t end_port(struct ib_device *device)\r
345 {\r
346         return device->node_type == IB_NODE_SWITCH ? 0 : device->phys_port_cnt;\r
347 }\r
348 \r
349 static inline int ib_copy_from_umv_buf(void *dest, ci_umv_buf_t* const p_umv_buf, size_t len)\r
350 {\r
351         RtlCopyMemory(dest, (void*)(ULONG_PTR)p_umv_buf->p_inout_buf,  len);\r
352         return 0;\r
353 }\r
354 \r
355 static inline int ib_copy_to_umv_buf(ci_umv_buf_t* const p_umv_buf, void *src, size_t len)\r
356 {\r
357         if (p_umv_buf->output_size < len) {\r
358                 p_umv_buf->status = IB_INSUFFICIENT_MEMORY;\r
359                 p_umv_buf->output_size = 0;\r
360                 return -EFAULT;\r
361         }\r
362         RtlCopyMemory((void*)(ULONG_PTR)p_umv_buf->p_inout_buf, src, len);\r
363         p_umv_buf->status = IB_SUCCESS;\r
364         p_umv_buf->output_size = (uint32_t)len;\r
365         return 0;\r
366 }\r
367 \r
368 \r
369 \r
370 // API\r
371 int mthca_query_device(struct ib_device *ibdev,\r
372                               struct ib_device_attr *props);\r
373 \r
374 int mthca_query_port(struct ib_device *ibdev,\r
375                             u8 port, struct ib_port_attr *props);\r
376 \r
377 int mthca_modify_port(struct ib_device *ibdev,\r
378                              u8 port, int port_modify_mask,\r
379                              struct ib_port_modify *props);\r
380 \r
381 struct ib_pd *mthca_alloc_pd(struct ib_device *ibdev,\r
382                                     struct ib_ucontext *context,\r
383                                     ci_umv_buf_t* const                 p_umv_buf);\r
384 \r
385 int mthca_dealloc_pd(struct ib_pd *pd);\r
386 \r
387 int mthca_dereg_mr(struct ib_mr *mr);\r
388 \r
389 int mthca_query_srq(struct ib_srq *ibsrq, ib_srq_attr_t *srq_attr);\r
390 \r
391 struct ib_ucontext *mthca_alloc_ucontext(struct ib_device *ibdev,\r
392                                                 ci_umv_buf_t* const                     p_umv_buf);\r
393 \r
394 int mthca_dealloc_ucontext(struct ib_ucontext *context);\r
395 \r
396 struct ib_mr *mthca_get_dma_mr(struct ib_pd *pd, mthca_qp_access_t acc);\r
397 \r
398 int mthca_poll_cq_list(\r
399         IN              struct ib_cq *ibcq, \r
400         IN      OUT                     ib_wc_t** const                         pp_free_wclist,\r
401                 OUT                     ib_wc_t** const                         pp_done_wclist );\r
402 \r
403 \r
404 #endif /* MTHCA_PROVIDER_H */\r