Commit | Line | Data |
---|---|---|
fab97220 HS |
1 | /* |
2 | * IBM eServer eHCA Infiniband device driver for Linux on POWER | |
3 | * | |
4 | * Struct definition for eHCA internal structures | |
5 | * | |
6 | * Authors: Heiko J Schick <schickhj@de.ibm.com> | |
7 | * Christoph Raisch <raisch@de.ibm.com> | |
a6a12947 | 8 | * Joachim Fenkes <fenkes@de.ibm.com> |
fab97220 HS |
9 | * |
10 | * Copyright (c) 2005 IBM Corporation | |
11 | * | |
12 | * All rights reserved. | |
13 | * | |
14 | * This source code is distributed under a dual license of GPL v2.0 and OpenIB | |
15 | * BSD. | |
16 | * | |
17 | * OpenIB BSD License | |
18 | * | |
19 | * Redistribution and use in source and binary forms, with or without | |
20 | * modification, are permitted provided that the following conditions are met: | |
21 | * | |
22 | * Redistributions of source code must retain the above copyright notice, this | |
23 | * list of conditions and the following disclaimer. | |
24 | * | |
25 | * Redistributions in binary form must reproduce the above copyright notice, | |
26 | * this list of conditions and the following disclaimer in the documentation | |
27 | * and/or other materials | |
28 | * provided with the distribution. | |
29 | * | |
30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
31 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
32 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
33 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
34 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
35 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
36 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | |
37 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER | |
38 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
39 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
40 | * POSSIBILITY OF SUCH DAMAGE. | |
41 | */ | |
42 | ||
43 | #ifndef __EHCA_CLASSES_H__ | |
44 | #define __EHCA_CLASSES_H__ | |
45 | ||
fab97220 HS |
46 | struct ehca_module; |
47 | struct ehca_qp; | |
48 | struct ehca_cq; | |
49 | struct ehca_eq; | |
50 | struct ehca_mr; | |
51 | struct ehca_mw; | |
52 | struct ehca_pd; | |
53 | struct ehca_av; | |
54 | ||
31726798 | 55 | #include <linux/wait.h> |
1fea3910 | 56 | #include <linux/mutex.h> |
31726798 | 57 | |
78d8d5f9 HNN |
58 | #include <rdma/ib_verbs.h> |
59 | #include <rdma/ib_user_verbs.h> | |
60 | ||
fab97220 HS |
61 | #ifdef CONFIG_PPC64 |
62 | #include "ehca_classes_pSeries.h" | |
63 | #endif | |
78d8d5f9 HNN |
64 | #include "ipz_pt_fn.h" |
65 | #include "ehca_qes.h" | |
66 | #include "ehca_irq.h" | |
fab97220 | 67 | |
78d8d5f9 | 68 | #define EHCA_EQE_CACHE_SIZE 20 |
d227fa72 | 69 | #define EHCA_MAX_NUM_QUEUES 0xffff |
fab97220 | 70 | |
78d8d5f9 HNN |
71 | struct ehca_eqe_cache_entry { |
72 | struct ehca_eqe *eqe; | |
73 | struct ehca_cq *cq; | |
74 | }; | |
fab97220 HS |
75 | |
76 | struct ehca_eq { | |
77 | u32 length; | |
78 | struct ipz_queue ipz_queue; | |
79 | struct ipz_eq_handle ipz_eq_handle; | |
80 | struct work_struct work; | |
81 | struct h_galpas galpas; | |
82 | int is_initialized; | |
83 | struct ehca_pfeq pf; | |
84 | spinlock_t spinlock; | |
85 | struct tasklet_struct interrupt_task; | |
86 | u32 ist; | |
78d8d5f9 HNN |
87 | spinlock_t irq_spinlock; |
88 | struct ehca_eqe_cache_entry eqe_cache[EHCA_EQE_CACHE_SIZE]; | |
fab97220 HS |
89 | }; |
90 | ||
8705ce5b JF |
91 | struct ehca_sma_attr { |
92 | u16 lid, lmc, sm_sl, sm_lid; | |
93 | u16 pkey_tbl_len, pkeys[16]; | |
94 | }; | |
95 | ||
fab97220 HS |
96 | struct ehca_sport { |
97 | struct ib_cq *ibcq_aqp1; | |
b8b50e35 | 98 | struct ib_qp *ibqp_sqp[2]; |
bbdd267e HNN |
99 | /* lock to serialze modify_qp() calls for sqp in normal |
100 | * and irq path (when event PORT_ACTIVE is received first time) | |
101 | */ | |
102 | spinlock_t mod_sqp_lock; | |
fab97220 | 103 | enum ib_port_state port_state; |
8705ce5b | 104 | struct ehca_sma_attr saved_attr; |
2b5e6b12 | 105 | u32 pma_qp_nr; |
fab97220 HS |
106 | }; |
107 | ||
08c283ac HNN |
108 | #define HCA_CAP_MR_PGSIZE_4K 0x80000000 |
109 | #define HCA_CAP_MR_PGSIZE_64K 0x40000000 | |
110 | #define HCA_CAP_MR_PGSIZE_1M 0x20000000 | |
111 | #define HCA_CAP_MR_PGSIZE_16M 0x10000000 | |
5bb7d929 | 112 | |
fab97220 HS |
113 | struct ehca_shca { |
114 | struct ib_device ib_device; | |
2dc11581 | 115 | struct platform_device *ofdev; |
fab97220 HS |
116 | u8 num_ports; |
117 | int hw_level; | |
118 | struct list_head shca_list; | |
119 | struct ipz_adapter_handle ipz_hca_handle; | |
120 | struct ehca_sport sport[2]; | |
121 | struct ehca_eq eq; | |
122 | struct ehca_eq neq; | |
123 | struct ehca_mr *maxmr; | |
124 | struct ehca_pd *pd; | |
125 | struct h_galpas galpas; | |
c4ed790d | 126 | struct mutex modify_mutex; |
91f13aa3 | 127 | u64 hca_cap; |
5bb7d929 HNN |
128 | /* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */ |
129 | u32 hca_cap_mr_pgsize; | |
91f13aa3 | 130 | int max_mtu; |
19f42821 SR |
131 | int max_num_qps; |
132 | int max_num_cqs; | |
d227fa72 SR |
133 | atomic_t num_cqs; |
134 | atomic_t num_qps; | |
fab97220 HS |
135 | }; |
136 | ||
137 | struct ehca_pd { | |
138 | struct ib_pd ib_pd; | |
139 | struct ipz_pd fw_pd; | |
e2f81daf SR |
140 | /* small queue mgmt */ |
141 | struct mutex lock; | |
142 | struct list_head free[2]; | |
143 | struct list_head full[2]; | |
fab97220 HS |
144 | }; |
145 | ||
a6a12947 JF |
146 | enum ehca_ext_qp_type { |
147 | EQPT_NORMAL = 0, | |
148 | EQPT_LLQP = 1, | |
149 | EQPT_SRQBASE = 2, | |
150 | EQPT_SRQ = 3, | |
151 | }; | |
152 | ||
bbdd267e HNN |
153 | /* struct to cache modify_qp()'s parms for GSI/SMI qp */ |
154 | struct ehca_mod_qp_parm { | |
155 | int mask; | |
156 | struct ib_qp_attr attr; | |
157 | }; | |
158 | ||
159 | #define EHCA_MOD_QP_PARM_MAX 4 | |
160 | ||
6773f079 AS |
161 | #define QMAP_IDX_MASK 0xFFFFULL |
162 | ||
163 | /* struct for tracking if cqes have been reported to the application */ | |
164 | struct ehca_qmap_entry { | |
165 | u16 app_wr_id; | |
7ec4f463 SR |
166 | u8 reported; |
167 | u8 cqe_req; | |
6773f079 AS |
168 | }; |
169 | ||
b9012e0a AS |
170 | struct ehca_queue_map { |
171 | struct ehca_qmap_entry *map; | |
172 | unsigned int entries; | |
173 | unsigned int tail; | |
174 | unsigned int left_to_poll; | |
7ec4f463 | 175 | unsigned int next_wqe_idx; /* Idx to first wqe to be flushed */ |
b9012e0a AS |
176 | }; |
177 | ||
1c721940 SR |
178 | /* function to calculate the next index for the qmap */ |
179 | static inline unsigned int next_index(unsigned int cur_index, unsigned int limit) | |
180 | { | |
181 | unsigned int temp = cur_index + 1; | |
182 | return (temp == limit) ? 0 : temp; | |
183 | } | |
184 | ||
fab97220 | 185 | struct ehca_qp { |
a6a12947 JF |
186 | union { |
187 | struct ib_qp ib_qp; | |
188 | struct ib_srq ib_srq; | |
189 | }; | |
fab97220 | 190 | u32 qp_type; |
a6a12947 | 191 | enum ehca_ext_qp_type ext_type; |
863fb09f | 192 | enum ib_qp_state state; |
fab97220 | 193 | struct ipz_queue ipz_squeue; |
b9012e0a | 194 | struct ehca_queue_map sq_map; |
fab97220 | 195 | struct ipz_queue ipz_rqueue; |
b9012e0a | 196 | struct ehca_queue_map rq_map; |
fab97220 HS |
197 | struct h_galpas galpas; |
198 | u32 qkey; | |
199 | u32 real_qp_num; | |
200 | u32 token; | |
201 | spinlock_t spinlock_s; | |
202 | spinlock_t spinlock_r; | |
203 | u32 sq_max_inline_data_size; | |
204 | struct ipz_qp_handle ipz_qp_handle; | |
205 | struct ehca_pfqp pf; | |
206 | struct ib_qp_init_attr init_attr; | |
fab97220 HS |
207 | struct ehca_cq *send_cq; |
208 | struct ehca_cq *recv_cq; | |
209 | unsigned int sqerr_purgeflag; | |
210 | struct hlist_node list_entries; | |
bbdd267e HNN |
211 | /* array to cache modify_qp()'s parms for GSI/SMI qp */ |
212 | struct ehca_mod_qp_parm *mod_qp_parm; | |
213 | int mod_qp_parm_idx; | |
4c34bdf5 HNN |
214 | /* mmap counter for resources mapped into user space */ |
215 | u32 mm_count_squeue; | |
216 | u32 mm_count_rqueue; | |
217 | u32 mm_count_galpa; | |
2ec8e662 JF |
218 | /* unsolicited ack circumvention */ |
219 | int unsol_ack_circ; | |
220 | int mtu_shift; | |
221 | u32 message_count; | |
222 | u32 packet_count; | |
12137c59 SR |
223 | atomic_t nr_events; /* events seen */ |
224 | wait_queue_head_t wait_completion; | |
5b673b71 | 225 | int mig_armed; |
b9012e0a AS |
226 | struct list_head sq_err_node; |
227 | struct list_head rq_err_node; | |
fab97220 HS |
228 | }; |
229 | ||
a6a12947 JF |
230 | #define IS_SRQ(qp) (qp->ext_type == EQPT_SRQ) |
231 | #define HAS_SQ(qp) (qp->ext_type != EQPT_SRQ) | |
232 | #define HAS_RQ(qp) (qp->ext_type != EQPT_SRQBASE) | |
233 | ||
fab97220 HS |
234 | /* must be power of 2 */ |
235 | #define QP_HASHTAB_LEN 8 | |
236 | ||
237 | struct ehca_cq { | |
238 | struct ib_cq ib_cq; | |
239 | struct ipz_queue ipz_queue; | |
240 | struct h_galpas galpas; | |
241 | spinlock_t spinlock; | |
242 | u32 cq_number; | |
243 | u32 token; | |
244 | u32 nr_of_entries; | |
245 | struct ipz_cq_handle ipz_cq_handle; | |
246 | struct ehca_pfcq pf; | |
247 | spinlock_t cb_lock; | |
fab97220 HS |
248 | struct hlist_head qp_hashtab[QP_HASHTAB_LEN]; |
249 | struct list_head entry; | |
28db6beb JF |
250 | u32 nr_callbacks; /* #events assigned to cpu by scaling code */ |
251 | atomic_t nr_events; /* #events seen */ | |
31726798 | 252 | wait_queue_head_t wait_completion; |
fab97220 | 253 | spinlock_t task_lock; |
4c34bdf5 HNN |
254 | /* mmap counter for resources mapped into user space */ |
255 | u32 mm_count_queue; | |
256 | u32 mm_count_galpa; | |
b9012e0a AS |
257 | struct list_head sqp_err_list; |
258 | struct list_head rqp_err_list; | |
fab97220 HS |
259 | }; |
260 | ||
261 | enum ehca_mr_flag { | |
262 | EHCA_MR_FLAG_FMR = 0x80000000, /* FMR, created with ehca_alloc_fmr */ | |
263 | EHCA_MR_FLAG_MAXMR = 0x40000000, /* max-MR */ | |
264 | }; | |
265 | ||
266 | struct ehca_mr { | |
267 | union { | |
268 | struct ib_mr ib_mr; /* must always be first in ehca_mr */ | |
269 | struct ib_fmr ib_fmr; /* must always be first in ehca_mr */ | |
270 | } ib; | |
f7c6a7b5 | 271 | struct ib_umem *umem; |
fab97220 HS |
272 | spinlock_t mrlock; |
273 | ||
274 | enum ehca_mr_flag flags; | |
df17bfd4 HNN |
275 | u32 num_kpages; /* number of kernel pages */ |
276 | u32 num_hwpages; /* number of hw pages to form MR */ | |
5bb7d929 | 277 | u64 hwpage_size; /* hw page size used for this MR */ |
fab97220 HS |
278 | int acl; /* ACL (stored here for usage in reregister) */ |
279 | u64 *start; /* virtual start address (stored here for */ | |
2b94397a | 280 | /* usage in reregister) */ |
fab97220 HS |
281 | u64 size; /* size (stored here for usage in reregister) */ |
282 | u32 fmr_page_size; /* page size for FMR */ | |
283 | u32 fmr_max_pages; /* max pages for FMR */ | |
284 | u32 fmr_max_maps; /* max outstanding maps for FMR */ | |
285 | u32 fmr_map_cnt; /* map counter for FMR */ | |
286 | /* fw specific data */ | |
287 | struct ipz_mrmw_handle ipz_mr_handle; /* MR handle for h-calls */ | |
288 | struct h_galpas galpas; | |
fab97220 HS |
289 | }; |
290 | ||
291 | struct ehca_mw { | |
292 | struct ib_mw ib_mw; /* gen2 mw, must always be first in ehca_mw */ | |
293 | spinlock_t mwlock; | |
294 | ||
295 | u8 never_bound; /* indication MW was never bound */ | |
296 | struct ipz_mrmw_handle ipz_mw_handle; /* MW handle for h-calls */ | |
297 | struct h_galpas galpas; | |
298 | }; | |
299 | ||
300 | enum ehca_mr_pgi_type { | |
301 | EHCA_MR_PGI_PHYS = 1, /* type of ehca_reg_phys_mr, | |
302 | * ehca_rereg_phys_mr, | |
303 | * ehca_reg_internal_maxmr */ | |
304 | EHCA_MR_PGI_USER = 2, /* type of ehca_reg_user_mr */ | |
305 | EHCA_MR_PGI_FMR = 3 /* type of ehca_map_phys_fmr */ | |
306 | }; | |
307 | ||
308 | struct ehca_mr_pginfo { | |
309 | enum ehca_mr_pgi_type type; | |
df17bfd4 HNN |
310 | u64 num_kpages; |
311 | u64 kpage_cnt; | |
5bb7d929 | 312 | u64 hwpage_size; /* hw page size used for this MR */ |
df17bfd4 HNN |
313 | u64 num_hwpages; /* number of hw pages */ |
314 | u64 hwpage_cnt; /* counter for hw pages */ | |
315 | u64 next_hwpage; /* next hw page in buffer/chunk/listelem */ | |
fab97220 | 316 | |
df17bfd4 HNN |
317 | union { |
318 | struct { /* type EHCA_MR_PGI_PHYS section */ | |
319 | int num_phys_buf; | |
320 | struct ib_phys_buf *phys_buf_array; | |
321 | u64 next_buf; | |
322 | } phy; | |
323 | struct { /* type EHCA_MR_PGI_USER section */ | |
324 | struct ib_umem *region; | |
eeb8461e | 325 | struct scatterlist *next_sg; |
df17bfd4 HNN |
326 | u64 next_nmap; |
327 | } usr; | |
328 | struct { /* type EHCA_MR_PGI_FMR section */ | |
329 | u64 fmr_pgsize; | |
330 | u64 *page_list; | |
331 | u64 next_listelem; | |
332 | } fmr; | |
333 | } u; | |
fab97220 HS |
334 | }; |
335 | ||
336 | /* output parameters for MR/FMR hipz calls */ | |
337 | struct ehca_mr_hipzout_parms { | |
338 | struct ipz_mrmw_handle handle; | |
339 | u32 lkey; | |
340 | u32 rkey; | |
341 | u64 len; | |
342 | u64 vaddr; | |
343 | u32 acl; | |
344 | }; | |
345 | ||
346 | /* output parameters for MW hipz calls */ | |
347 | struct ehca_mw_hipzout_parms { | |
348 | struct ipz_mrmw_handle handle; | |
349 | u32 rkey; | |
350 | }; | |
351 | ||
352 | struct ehca_av { | |
353 | struct ib_ah ib_ah; | |
354 | struct ehca_ud_av av; | |
355 | }; | |
356 | ||
357 | struct ehca_ucontext { | |
358 | struct ib_ucontext ib_ucontext; | |
359 | }; | |
360 | ||
fab97220 HS |
361 | int ehca_init_pd_cache(void); |
362 | void ehca_cleanup_pd_cache(void); | |
363 | int ehca_init_cq_cache(void); | |
364 | void ehca_cleanup_cq_cache(void); | |
365 | int ehca_init_qp_cache(void); | |
366 | void ehca_cleanup_qp_cache(void); | |
367 | int ehca_init_av_cache(void); | |
368 | void ehca_cleanup_av_cache(void); | |
369 | int ehca_init_mrmw_cache(void); | |
370 | void ehca_cleanup_mrmw_cache(void); | |
e2f81daf SR |
371 | int ehca_init_small_qp_cache(void); |
372 | void ehca_cleanup_small_qp_cache(void); | |
fab97220 | 373 | |
26ed687f JF |
374 | extern rwlock_t ehca_qp_idr_lock; |
375 | extern rwlock_t ehca_cq_idr_lock; | |
fab97220 HS |
376 | extern struct idr ehca_qp_idr; |
377 | extern struct idr ehca_cq_idr; | |
94202694 | 378 | extern spinlock_t shca_list_lock; |
fab97220 HS |
379 | |
380 | extern int ehca_static_rate; | |
381 | extern int ehca_port_act_time; | |
90ab5ee9 RR |
382 | extern bool ehca_use_hp_mr; |
383 | extern bool ehca_scaling_code; | |
3d758a4a | 384 | extern int ehca_lock_hcalls; |
bbdd267e | 385 | extern int ehca_nr_ports; |
d227fa72 SR |
386 | extern int ehca_max_cq; |
387 | extern int ehca_max_qp; | |
fab97220 HS |
388 | |
389 | struct ipzu_queue_resp { | |
fab97220 HS |
390 | u32 qe_size; /* queue entry size */ |
391 | u32 act_nr_of_sg; | |
392 | u32 queue_length; /* queue length allocated in bytes */ | |
393 | u32 pagesize; | |
394 | u32 toggle_state; | |
e2f81daf | 395 | u32 offset; /* save offset within a page for small_qp */ |
fab97220 HS |
396 | }; |
397 | ||
398 | struct ehca_create_cq_resp { | |
399 | u32 cq_number; | |
400 | u32 token; | |
401 | struct ipzu_queue_resp ipz_queue; | |
e390d3b5 HNN |
402 | u32 fw_handle_ofs; |
403 | u32 dummy; | |
fab97220 HS |
404 | }; |
405 | ||
406 | struct ehca_create_qp_resp { | |
407 | u32 qp_num; | |
408 | u32 token; | |
409 | u32 qp_type; | |
a6a12947 | 410 | u32 ext_type; |
fab97220 HS |
411 | u32 qkey; |
412 | /* qp_num assigned by ehca: sqp0/1 may have got different numbers */ | |
413 | u32 real_qp_num; | |
e390d3b5 | 414 | u32 fw_handle_ofs; |
a6607223 | 415 | u32 dummy; |
fab97220 HS |
416 | struct ipzu_queue_resp ipz_squeue; |
417 | struct ipzu_queue_resp ipz_rqueue; | |
fab97220 HS |
418 | }; |
419 | ||
420 | struct ehca_alloc_cq_parms { | |
421 | u32 nr_cqe; | |
422 | u32 act_nr_of_entries; | |
423 | u32 act_pages; | |
424 | struct ipz_eq_handle eq_handle; | |
425 | }; | |
426 | ||
9a79fc0a JF |
427 | enum ehca_service_type { |
428 | ST_RC = 0, | |
429 | ST_UC = 1, | |
430 | ST_RD = 2, | |
431 | ST_UD = 3, | |
432 | }; | |
433 | ||
9a79fc0a JF |
434 | enum ehca_ll_comp_flags { |
435 | LLQP_SEND_COMP = 0x20, | |
436 | LLQP_RECV_COMP = 0x40, | |
437 | LLQP_COMP_MASK = 0x60, | |
438 | }; | |
439 | ||
e2f81daf SR |
440 | struct ehca_alloc_queue_parms { |
441 | /* input parameters */ | |
442 | int max_wr; | |
443 | int max_sge; | |
444 | int page_size; | |
445 | int is_small; | |
446 | ||
447 | /* output parameters */ | |
448 | u16 act_nr_wqes; | |
449 | u8 act_nr_sges; | |
450 | u32 queue_size; /* bytes for small queues, pages otherwise */ | |
451 | }; | |
452 | ||
fab97220 | 453 | struct ehca_alloc_qp_parms { |
e2f81daf SR |
454 | struct ehca_alloc_queue_parms squeue; |
455 | struct ehca_alloc_queue_parms rqueue; | |
456 | ||
457 | /* input parameters */ | |
9a79fc0a | 458 | enum ehca_service_type servicetype; |
e2f81daf | 459 | int qp_storage; |
fab97220 | 460 | int sigtype; |
9a79fc0a JF |
461 | enum ehca_ext_qp_type ext_type; |
462 | enum ehca_ll_comp_flags ll_comp_flags; | |
fab97220 HS |
463 | int ud_av_l_key_ctl; |
464 | ||
9a79fc0a JF |
465 | u32 token; |
466 | struct ipz_eq_handle eq_handle; | |
467 | struct ipz_pd pd; | |
468 | struct ipz_cq_handle send_cq_handle, recv_cq_handle; | |
469 | ||
470 | u32 srq_qpn, srq_token, srq_limit; | |
471 | ||
e2f81daf | 472 | /* output parameters */ |
9a79fc0a JF |
473 | u32 real_qp_num; |
474 | struct ipz_qp_handle qp_handle; | |
475 | struct h_galpas galpas; | |
fab97220 HS |
476 | }; |
477 | ||
478 | int ehca_cq_assign_qp(struct ehca_cq *cq, struct ehca_qp *qp); | |
479 | int ehca_cq_unassign_qp(struct ehca_cq *cq, unsigned int qp_num); | |
2b94397a | 480 | struct ehca_qp *ehca_cq_get_qp(struct ehca_cq *cq, int qp_num); |
fab97220 HS |
481 | |
482 | #endif |