docs/how-to-build.md: use proper markup for directory names
[unleashed/tickless.git] / include / sys / ib / adapters / tavor / tavor_hw.h
blob1f0b3b9eab2026e551167b2293bd1600b2c9fa7c
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #ifndef _SYS_IB_ADAPTERS_TAVOR_HW_H
28 #define _SYS_IB_ADAPTERS_TAVOR_HW_H
31 * tavor_hw.h
32 * Contains all the structure definitions and #defines for all Tavor
33 * hardware resources and registers (as defined by the Tavor register
34 * specification). Wherever possible, the names in the Tavor spec
35 * have been preserved in the structure and field names below.
38 #include <sys/types.h>
39 #include <sys/conf.h>
40 #include <sys/ddi.h>
41 #include <sys/sunddi.h>
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
49 * Offsets into the CMD BAR (BAR 0) for many of the more interesting hardware
50 * registers. These registers include the HCR (more below), the Event Cause
51 * Register (ECR) and its related clear register, the Interrupt Clear register
52 * (CLR_INT), and the software reset register (SW_RESET).
54 #define TAVOR_CMD_HCR_OFFSET 0x80680
55 #define TAVOR_CMD_ECR_OFFSET 0x80700
56 #define TAVOR_CMD_CLR_ECR_OFFSET 0x80708
57 #define TAVOR_CMD_CLR_INT_OFFSET 0xF00D8
58 #define TAVOR_CMD_SW_RESET_OFFSET 0xF0010
61 * Ownership flags used to define hardware or software ownership for
62 * various Tavor resources
64 #define TAVOR_HW_OWNER 0x1
65 #define TAVOR_SW_OWNER 0x0
68 * Determines whether or not virtual-to-physical address translation is
69 * required. Several of the Tavor hardware structures can be optionally
70 * accessed by Tavor without going through the TPT address translation
71 * tables.
73 #define TAVOR_VA2PA_XLAT_ENABLED 0x1
74 #define TAVOR_VA2PA_XLAT_DISABLED 0x0
77 * HCA Command Register (HCR)
78 * The HCR command interface provides privileged access to the HCA in
79 * order to query, configure and modify HCA execution. It is the
80 * primary mechanism through which mailboxes may be posted to Tavor
81 * firmware. To use this interface software fills the HCR with pointers
82 * to input and output mailboxes. Some commands support immediate
83 * parameters, however, and for these commands the HCR will contain the
84 * input or output parameters. Command execution completion can be
85 * detected either by the software polling the HCR or by waiting for a
86 * command completion event.
88 struct tavor_hw_hcr_s {
89 uint32_t in_param0;
90 uint32_t in_param1;
91 uint32_t input_modifier;
92 uint32_t out_param0;
93 uint32_t out_param1;
94 uint32_t token;
95 uint32_t cmd;
97 #define TAVOR_HCR_TOKEN_MASK 0xFFFF0000
98 #define TAVOR_HCR_TOKEN_SHIFT 16
100 #define TAVOR_HCR_CMD_STATUS_MASK 0xFF000000
101 #define TAVOR_HCR_CMD_GO_MASK 0x00800000
102 #define TAVOR_HCR_CMD_E_MASK 0x00400000
103 #define TAVOR_HCR_CMD_OPMOD_MASK 0x0000F000
104 #define TAVOR_HCR_CMD_OPCODE_MASK 0x00000FFF
105 #define TAVOR_HCR_CMD_STATUS_SHFT 24
106 #define TAVOR_HCR_CMD_GO_SHFT 23
107 #define TAVOR_HCR_CMD_E_SHFT 22
108 #define TAVOR_HCR_CMD_OPMOD_SHFT 12
112 * Tavor "QUERY_DEV_LIM" command
113 * The QUERY_DEV_LIM command returns the device limits and capabilities
114 * supported by the Tavor device. This command should be run before
115 * running the INIT_HCA command (below) in order to determine the maximum
116 * capabilities of the device and which optional features are supported.
118 #ifdef _LITTLE_ENDIAN
119 struct tavor_hw_querydevlim_s {
120 uint32_t rsrv0[4];
121 uint32_t log_max_ee :5;
122 uint32_t :3;
123 uint32_t log_rsvd_ee :4;
124 uint32_t :4;
125 uint32_t log_max_srq :5;
126 uint32_t :7;
127 uint32_t log_rsvd_srq :4;
128 uint32_t log_max_qp :5;
129 uint32_t :3;
130 uint32_t log_rsvd_qp :4;
131 uint32_t :4;
132 uint32_t log_max_qp_sz :8;
133 uint32_t log_max_srq_sz :8;
134 uint32_t log_max_eq :3;
135 uint32_t :5;
136 uint32_t num_rsvd_eq :4;
137 uint32_t :4;
138 uint32_t log_max_mpt :6;
139 uint32_t :10;
140 uint32_t log_max_cq :5;
141 uint32_t :3;
142 uint32_t log_rsvd_cq :4;
143 uint32_t :4;
144 uint32_t log_max_cq_sz :8;
145 uint32_t :8;
146 uint32_t log_max_av :6;
147 uint32_t :26;
148 uint32_t log_max_mttseg :6;
149 uint32_t :2;
150 uint32_t log_rsvd_mpt :4;
151 uint32_t :4;
152 uint32_t log_max_mrw_sz :8;
153 uint32_t :4;
154 uint32_t log_rsvd_mttseg :4;
155 uint32_t log_max_ra_glob :6;
156 uint32_t :26;
157 uint32_t log_max_ras_qp :6;
158 uint32_t :10;
159 uint32_t log_max_raq_qp :6;
160 uint32_t :10;
161 uint32_t num_ports :4;
162 uint32_t max_vl :4;
163 uint32_t max_port_width :4;
164 uint32_t max_mtu :4;
165 uint32_t ca_ack_delay :5;
166 uint32_t :11;
167 uint32_t :32;
168 uint32_t log_max_pkey :4;
169 uint32_t :12;
170 uint32_t stat_rate_sup :16;
171 uint32_t log_max_gid :4;
172 uint32_t :28;
173 uint32_t rc :1;
174 uint32_t uc :1;
175 uint32_t ud :1;
176 uint32_t rd :1;
177 uint32_t raw_ipv6 :1;
178 uint32_t raw_ether :1;
179 uint32_t srq :1;
180 uint32_t :1;
181 uint32_t pkey_v :1;
182 uint32_t qkey_v :1;
183 uint32_t :6;
184 uint32_t mem_win :1;
185 uint32_t apm :1;
186 uint32_t atomic :1;
187 uint32_t raw_multi :1;
188 uint32_t avp :1;
189 uint32_t ud_multi :1;
190 uint32_t :2;
191 uint32_t pg_on_demand :1;
192 uint32_t router :1;
193 uint32_t :6;
194 uint32_t :32;
195 uint32_t :32;
196 uint32_t log_pg_sz :8;
197 uint32_t :8;
198 uint32_t log_max_uar_sz :6;
199 uint32_t :6;
200 uint32_t num_rsvd_uar :4;
201 uint32_t :32;
202 uint32_t max_desc_sz :16;
203 uint32_t max_sg :8;
204 uint32_t :8;
205 uint32_t rsrv1[2];
206 uint32_t log_max_rdd :6;
207 uint32_t :6;
208 uint32_t num_rsvd_rdd :4;
209 uint32_t log_max_pd :6;
210 uint32_t :6;
211 uint32_t num_rsvd_pd :4;
212 uint32_t log_max_mcg :8;
213 uint32_t num_rsvd_mcg :4;
214 uint32_t :4;
215 uint32_t log_max_qp_mcg :8;
216 uint32_t :8;
217 uint32_t rsrv2[6];
218 uint32_t eqpc_entry_sz :16;
219 uint32_t eeec_entry_sz :16;
220 uint32_t qpc_entry_sz :16;
221 uint32_t eec_entry_sz :16;
222 uint32_t uarscr_entry_sz :16;
223 uint32_t srq_entry_sz :16;
224 uint32_t cqc_entry_sz :16;
225 uint32_t eqc_entry_sz :16;
226 uint32_t rsrv3[28];
228 #else
229 struct tavor_hw_querydevlim_s {
230 uint32_t rsrv0[4];
231 uint32_t log_max_srq_sz :8;
232 uint32_t log_max_qp_sz :8;
233 uint32_t :4;
234 uint32_t log_rsvd_qp :4;
235 uint32_t :3;
236 uint32_t log_max_qp :5;
237 uint32_t log_rsvd_srq :4;
238 uint32_t :7;
239 uint32_t log_max_srq :5;
240 uint32_t :4;
241 uint32_t log_rsvd_ee :4;
242 uint32_t :3;
243 uint32_t log_max_ee :5;
244 uint32_t :8;
245 uint32_t log_max_cq_sz :8;
246 uint32_t :4;
247 uint32_t log_rsvd_cq :4;
248 uint32_t :3;
249 uint32_t log_max_cq :5;
250 uint32_t :10;
251 uint32_t log_max_mpt :6;
252 uint32_t :4;
253 uint32_t num_rsvd_eq :4;
254 uint32_t :5;
255 uint32_t log_max_eq :3;
256 uint32_t log_rsvd_mttseg :4;
257 uint32_t :4;
258 uint32_t log_max_mrw_sz :8;
259 uint32_t :4;
260 uint32_t log_rsvd_mpt :4;
261 uint32_t :2;
262 uint32_t log_max_mttseg :6;
263 uint32_t :26;
264 uint32_t log_max_av :6;
265 uint32_t :10;
266 uint32_t log_max_raq_qp :6;
267 uint32_t :10;
268 uint32_t log_max_ras_qp :6;
269 uint32_t :26;
270 uint32_t log_max_ra_glob :6;
271 uint32_t :32;
272 uint32_t :11;
273 uint32_t ca_ack_delay :5;
274 uint32_t max_mtu :4;
275 uint32_t max_port_width :4;
276 uint32_t max_vl :4;
277 uint32_t num_ports :4;
278 uint32_t :28;
279 uint32_t log_max_gid :4;
280 uint32_t stat_rate_sup :16;
281 uint32_t :12;
282 uint32_t log_max_pkey :4;
283 uint32_t :32;
284 uint32_t :6;
285 uint32_t router :1;
286 uint32_t pg_on_demand :1;
287 uint32_t :2;
288 uint32_t ud_multi :1;
289 uint32_t avp :1;
290 uint32_t raw_multi :1;
291 uint32_t atomic :1;
292 uint32_t apm :1;
293 uint32_t mem_win :1;
294 uint32_t :6;
295 uint32_t qkey_v :1;
296 uint32_t pkey_v :1;
297 uint32_t :1;
298 uint32_t srq :1;
299 uint32_t raw_ether :1;
300 uint32_t raw_ipv6 :1;
301 uint32_t rd :1;
302 uint32_t ud :1;
303 uint32_t uc :1;
304 uint32_t rc :1;
305 uint32_t num_rsvd_uar :4;
306 uint32_t :6;
307 uint32_t log_max_uar_sz :6;
308 uint32_t :8;
309 uint32_t log_pg_sz :8;
310 uint32_t :32;
311 uint32_t :8;
312 uint32_t max_sg :8;
313 uint32_t max_desc_sz :16;
314 uint32_t :32;
315 uint32_t rsrv1[2];
316 uint32_t :8;
317 uint32_t log_max_qp_mcg :8;
318 uint32_t :4;
319 uint32_t num_rsvd_mcg :4;
320 uint32_t log_max_mcg :8;
321 uint32_t num_rsvd_pd :4;
322 uint32_t :6;
323 uint32_t log_max_pd :6;
324 uint32_t num_rsvd_rdd :4;
325 uint32_t :6;
326 uint32_t log_max_rdd :6;
327 uint32_t rsrv2[6];
328 uint32_t eec_entry_sz :16;
329 uint32_t qpc_entry_sz :16;
330 uint32_t eeec_entry_sz :16;
331 uint32_t eqpc_entry_sz :16;
332 uint32_t eqc_entry_sz :16;
333 uint32_t cqc_entry_sz :16;
334 uint32_t srq_entry_sz :16;
335 uint32_t uarscr_entry_sz :16;
336 uint32_t rsrv3[28];
338 #endif
342 * Tavor "QUERY_FW" command
343 * The QUERY_FW command retrieves the firmware revision and the Command
344 * Interface revision. The command also returns the HCA attached local
345 * memory area (DDR) which is used by the firmware. Below we also
346 * include some defines which are used to enforce a minimum firmware
347 * version check (see tavor_fw_version_check() for more details).
349 #ifdef _LITTLE_ENDIAN
350 struct tavor_hw_queryfw_s {
351 uint32_t fw_rev_minor :16;
352 uint32_t fw_rev_subminor :16;
353 uint32_t fw_rev_major :16;
354 uint32_t :16;
355 uint32_t log_max_cmd :8;
356 uint32_t :23;
357 uint32_t dbg_trace :1;
358 uint32_t cmd_intf_rev :16;
359 uint32_t :16;
360 uint32_t rsrv0[4];
361 uint64_t fw_baseaddr;
362 uint64_t fw_endaddr;
363 uint64_t error_buf_addr;
364 uint32_t :32;
365 uint32_t error_buf_sz;
366 uint32_t rsrv1[48];
368 #else
369 struct tavor_hw_queryfw_s {
370 uint32_t :16;
371 uint32_t fw_rev_major :16;
372 uint32_t fw_rev_subminor :16;
373 uint32_t fw_rev_minor :16;
374 uint32_t :16;
375 uint32_t cmd_intf_rev :16;
376 uint32_t dbg_trace :1;
377 uint32_t :23;
378 uint32_t log_max_cmd :8;
379 uint32_t rsrv0[4];
380 uint64_t fw_baseaddr;
381 uint64_t fw_endaddr;
382 uint64_t error_buf_addr;
383 uint32_t error_buf_sz;
384 uint32_t rsrv1[49];
386 #endif
387 #define TAVOR_FW_VER_MAJOR 0x0003
388 #define TAVOR_FW_VER_MINOR 0x0001
389 #define TAVOR_FW_VER_SUBMINOR 0x0000
390 #define TAVOR_COMPAT_FW_VER_MAJOR 0x0004
391 #define TAVOR_COMPAT_FW_VER_MINOR 0x0005
392 #define TAVOR_COMPAT_FW_VER_SUBMINOR 0x0003
396 * Tavor "QUERY_DDR" command
397 * The QUERY_DDR command retrieves information regarding the HCA attached
398 * local memory area (DDR). This information includes: the DIMM PCI BAR,
399 * the total address space provided by the HCA attached local memory, and
400 * some DIMM-specific information. Note: Some of the HCA attached local
401 * memory is reserved for use by firmware. This extent of this reserved
402 * area can be obtained through the QUERY_FW command (above).
404 * Below we first define the tavor_hw_queryddr_dimm_t or "Logical DIMM
405 * Information" structure. Four of these are present in the QUERY_DDR
406 * command.
408 #ifdef _LITTLE_ENDIAN
409 typedef struct tavor_hw_queryddr_dimm_s {
410 uint32_t spd :1;
411 uint32_t sladr :3;
412 uint32_t sock_num :2;
413 uint32_t syn :4;
414 uint32_t :22;
415 uint32_t dimmsz :16;
416 uint32_t :8;
417 uint32_t dimmstatus :1;
418 uint32_t dimm_hidden :1;
419 uint32_t write_only :1;
420 uint32_t :5;
421 uint32_t vendor_id_l;
422 uint32_t vendor_id_h;
423 uint32_t dimm_baseaddr_l;
424 uint32_t dimm_baseaddr_h;
425 uint32_t rsrv0[2];
426 } tavor_hw_queryddr_dimm_t;
427 #else
428 typedef struct tavor_hw_queryddr_dimm_s {
429 uint32_t :5;
430 uint32_t write_only :1;
431 uint32_t dimm_hidden :1;
432 uint32_t dimmstatus :1;
433 uint32_t :8;
434 uint32_t dimmsz :16;
435 uint32_t :22;
436 uint32_t syn :4;
437 uint32_t sock_num :2;
438 uint32_t sladr :3;
439 uint32_t spd :1;
440 uint32_t vendor_id_h;
441 uint32_t vendor_id_l;
442 uint32_t dimm_baseaddr_h;
443 uint32_t dimm_baseaddr_l;
444 uint32_t rsrv0[2];
445 } tavor_hw_queryddr_dimm_t;
446 #endif
447 #define TAVOR_DIMMSTATUS_ENABLED 0x0
448 #define TAVOR_DIMMSTATUS_DISABLED 0x1
450 #define TAVOR_DIMM_ERR_NONE 0x0
451 #define TAVOR_DIMM_ERR_SPD 0x1
452 #define TAVOR_DIMM_ERR_BOUNDS 0x2
453 #define TAVOR_DIMM_ERR_CONFLICT 0x3
454 #define TAVOR_DIMM_ERR_SIZETRIM 0x5
456 #define TAVOR_DIMM_SPD_FROM_DIMM 0x0
457 #define TAVOR_DIMM_SPD_FROM_NVMEM 0x1
459 #ifdef _LITTLE_ENDIAN
460 struct tavor_hw_queryddr_s {
461 uint64_t ddr_baseaddr;
462 uint64_t ddr_endaddr;
463 uint32_t :32;
464 uint32_t data_integrity :2;
465 uint32_t auto_precharge :2;
466 uint32_t ddr_hidden :1;
467 uint32_t :27;
468 uint32_t rsrv0[10];
469 tavor_hw_queryddr_dimm_t dimm[4];
470 uint32_t rsrv1[16];
472 #else
473 struct tavor_hw_queryddr_s {
474 uint64_t ddr_baseaddr;
475 uint64_t ddr_endaddr;
476 uint32_t :27;
477 uint32_t ddr_hidden :1;
478 uint32_t auto_precharge :2;
479 uint32_t data_integrity :2;
480 uint32_t :32;
481 uint32_t rsrv0[10];
482 tavor_hw_queryddr_dimm_t dimm[4];
483 uint32_t rsrv1[16];
485 #endif
486 #define TAVOR_AUTO_PRECHRG_NONE 0x0
487 #define TAVOR_AUTO_PRECHRG_PER_TRANS 0x1
488 #define TAVOR_AUTO_PRECHRG_PER_64B 0x2
490 #define TAVOR_DATA_INT_NONE 0x0
491 #define TAVOR_DATA_INT_PARITY 0x1
492 #define TAVOR_DATA_INT_ECC_DETECT_ONLY 0x2
493 #define TAVOR_DATA_INT_ECC_CORRECT 0x3
497 * Tavor "QUERY_ADAPTER" command
498 * The QUERY_ADAPTER command retrieves adapter specific parameters. The
499 * command also retrieves the PCI(X) interrupt pin routing for each of
500 * the INTx# pins supported by the device. This information is used by
501 * the driver during interrupt processing in order to clear the appropriate
502 * interrupt bit.
504 #ifdef _LITTLE_ENDIAN
505 struct tavor_hw_queryadapter_s {
506 uint32_t device_id;
507 uint32_t vendor_id;
508 uint32_t :32;
509 uint32_t rev_id;
510 uint32_t :32;
511 uint32_t :24;
512 uint32_t inta_pin :8;
513 uint32_t rsrv0[58];
515 #else
516 struct tavor_hw_queryadapter_s {
517 uint32_t vendor_id;
518 uint32_t device_id;
519 uint32_t rev_id;
520 uint32_t :32;
521 uint32_t inta_pin :8;
522 uint32_t :24;
523 uint32_t :32;
524 uint32_t rsrv0[58];
526 #endif
527 #define TAVOR_REV_A0 0xA0
528 #define TAVOR_REV_A1 0xA1
532 * Tavor "INIT_HCA" and "QUERY_HCA" commands
533 * The INIT_HCA command configures all HCA resources in HCA attached local
534 * memory and some system relevant information. The same mailbox output
535 * format is used by the QUERY_HCA command. All parameters, which are
536 * specifically the output of the QUERY_HCA command are marked as
537 * "QUERY_HCA only". These parameters are not configurable through the
538 * INIT_HCA command, but can be retrieved as read-only through the
539 * QUERY_HCA command.
541 * Below we first define several structures which help make up the whole
542 * of the INIT_HCA/QUERY_HCA command. These are:
543 * tavor_hw_qp_ee_cq_eq_rdb_t for "QPC/EEC/CQC/EQC/RDB Parameters",
544 * tavor_udav_mem_param_t for "Memory Access Parameters for UDAV Table",
545 * tavor_multicast_param_t for "Multicast Support Parameters",
546 * tavor_tpt_param_t for "Translation and Protection Table Parameters",
547 * and tavor_uar_param_t for Tavor "UAR Parameters".
549 #ifdef _LITTLE_ENDIAN
550 typedef struct tavor_hw_qp_ee_cq_eq_rdb_s {
551 uint32_t rsrv0[4];
552 uint32_t log_num_qp :5;
553 uint32_t :2;
554 uint32_t qpc_baseaddr_l :25;
555 uint32_t qpc_baseaddr_h;
556 uint32_t rsrv1[2];
557 uint32_t log_num_ee :5;
558 uint32_t :2;
559 uint32_t eec_baseaddr_l :25;
560 uint32_t eec_baseaddr_h;
561 uint32_t log_num_srq :5;
562 uint32_t srqc_baseaddr_l :27;
563 uint32_t srqc_baseaddr_h;
564 uint32_t log_num_cq :5;
565 uint32_t :1;
566 uint32_t cqc_baseaddr_l :26;
567 uint32_t cqc_baseaddr_h;
568 uint32_t rsrv2[2];
569 uint64_t eqpc_baseaddr;
570 uint32_t rsrv3[2];
571 uint64_t eeec_baseaddr;
572 uint32_t rsrv4[2];
573 uint32_t log_num_eq :4;
574 uint32_t :2;
575 uint32_t eqc_baseaddr_l :26;
576 uint32_t eqc_baseaddr_h;
577 uint32_t rsrv5[2];
578 uint32_t rdb_baseaddr_l;
579 uint32_t rdb_baseaddr_h;
580 uint32_t rsrv6[2];
581 } tavor_hw_qp_ee_cq_eq_rdb_t;
582 #else
583 typedef struct tavor_hw_qp_ee_cq_eq_rdb_s {
584 uint32_t rsrv0[4];
585 uint32_t qpc_baseaddr_h;
586 uint32_t qpc_baseaddr_l :25;
587 uint32_t :2;
588 uint32_t log_num_qp :5;
589 uint32_t rsrv1[2];
590 uint32_t eec_baseaddr_h;
591 uint32_t eec_baseaddr_l :25;
592 uint32_t :2;
593 uint32_t log_num_ee :5;
594 uint32_t srqc_baseaddr_h;
595 uint32_t srqc_baseaddr_l :27;
596 uint32_t log_num_srq :5;
597 uint32_t cqc_baseaddr_h;
598 uint32_t cqc_baseaddr_l :26;
599 uint32_t :1;
600 uint32_t log_num_cq :5;
601 uint32_t rsrv2[2];
602 uint64_t eqpc_baseaddr;
603 uint32_t rsrv3[2];
604 uint64_t eeec_baseaddr;
605 uint32_t rsrv4[2];
606 uint32_t eqc_baseaddr_h;
607 uint32_t eqc_baseaddr_l :26;
608 uint32_t :2;
609 uint32_t log_num_eq :4;
610 uint32_t rsrv5[2];
611 uint32_t rdb_baseaddr_h;
612 uint32_t rdb_baseaddr_l;
613 uint32_t rsrv6[2];
614 } tavor_hw_qp_ee_cq_eq_rdb_t;
615 #endif
617 #ifdef _LITTLE_ENDIAN
618 typedef struct tavor_udav_mem_param_s {
619 uint32_t udav_pd :24;
620 uint32_t :5;
621 uint32_t udav_xlat_en :1;
622 uint32_t :2;
623 uint32_t udav_lkey;
624 } tavor_udav_mem_param_t;
625 #else
626 typedef struct tavor_udav_mem_param_s {
627 uint32_t udav_lkey;
628 uint32_t :2;
629 uint32_t udav_xlat_en :1;
630 uint32_t :5;
631 uint32_t udav_pd :24;
632 } tavor_udav_mem_param_t;
633 #endif
635 #ifdef _LITTLE_ENDIAN
636 typedef struct tavor_multicast_param_s {
637 uint64_t mc_baseaddr;
638 uint32_t rsrv0[2];
639 uint32_t mc_tbl_hash_sz :17;
640 uint32_t :15;
641 uint32_t log_mc_tbl_ent :16;
642 uint32_t :16;
643 uint32_t :32;
644 uint32_t log_mc_tbl_sz :5;
645 uint32_t :19;
646 uint32_t mc_hash_fn :3;
647 uint32_t :5;
648 } tavor_multicast_param_t;
649 #else
650 typedef struct tavor_multicast_param_s {
651 uint64_t mc_baseaddr;
652 uint32_t rsrv0[2];
653 uint32_t :16;
654 uint32_t log_mc_tbl_ent :16;
655 uint32_t :15;
656 uint32_t mc_tbl_hash_sz :17;
657 uint32_t :5;
658 uint32_t mc_hash_fn :3;
659 uint32_t :19;
660 uint32_t log_mc_tbl_sz :5;
661 uint32_t :32;
662 } tavor_multicast_param_t;
663 #endif
664 #define TAVOR_MCG_DEFAULT_HASH_FN 0x0
666 #ifdef _LITTLE_ENDIAN
667 typedef struct tavor_tpt_param_s {
668 uint64_t mpt_baseaddr;
669 uint32_t mtt_version :8;
670 uint32_t :24;
671 uint32_t log_mpt_sz :6;
672 uint32_t :2;
673 uint32_t pgfault_rnr_to :5;
674 uint32_t :3;
675 uint32_t mttseg_sz :3;
676 uint32_t :13;
677 uint64_t mtt_baseaddr;
678 uint32_t rsrv0[2];
679 } tavor_tpt_param_t;
680 #else
681 typedef struct tavor_tpt_param_s {
682 uint64_t mpt_baseaddr;
683 uint32_t :13;
684 uint32_t mttseg_sz :3;
685 uint32_t :3;
686 uint32_t pgfault_rnr_to :5;
687 uint32_t :2;
688 uint32_t log_mpt_sz :6;
689 uint32_t :24;
690 uint32_t mtt_version :8;
691 uint64_t mtt_baseaddr;
692 uint32_t rsrv0[2];
693 } tavor_tpt_param_t;
694 #endif
696 #ifdef _LITTLE_ENDIAN
697 typedef struct tavor_uar_param_s {
698 uint32_t :20;
699 uint32_t uar_baseaddr_l :12; /* QUERY_HCA only */
700 uint32_t uar_baseaddr_h; /* QUERY_HCA only */
701 uint32_t :32;
702 uint32_t uar_pg_sz :8;
703 uint32_t :24;
704 uint64_t uarscr_baseaddr;
705 uint32_t rsrv0[2];
706 } tavor_uar_param_t;
707 #else
708 typedef struct tavor_uar_param_s {
709 uint32_t uar_baseaddr_h; /* QUERY_HCA only */
710 uint32_t uar_baseaddr_l :12; /* QUERY_HCA only */
711 uint32_t :20;
712 uint32_t :24;
713 uint32_t uar_pg_sz :8;
714 uint32_t :32;
715 uint64_t uarscr_baseaddr;
716 uint32_t rsrv0[2];
717 } tavor_uar_param_t;
718 #endif
720 #ifdef _LITTLE_ENDIAN
721 struct tavor_hw_initqueryhca_s {
722 uint32_t rsrv0[2];
723 uint32_t :24;
724 uint32_t hca_core_clock :8; /* QUERY_HCA only */
725 uint32_t :32;
726 uint32_t udav_port_chk :1;
727 uint32_t big_endian :1;
728 uint32_t udav_chk :1;
729 uint32_t :5;
730 uint32_t responder_exu :4;
731 uint32_t :4;
732 uint32_t wqe_quota :15;
733 uint32_t wqe_quota_en :1;
734 uint32_t :8;
735 uint32_t router_qp :16;
736 uint32_t :7;
737 uint32_t router_en :1;
738 uint32_t rsrv1[2];
739 tavor_hw_qp_ee_cq_eq_rdb_t context;
740 uint32_t rsrv2[4];
741 tavor_udav_mem_param_t udav;
742 uint32_t rsrv3[2];
743 tavor_multicast_param_t multi;
744 uint32_t rsrv4[4];
745 tavor_tpt_param_t tpt;
746 uint32_t rsrv5[4];
747 tavor_uar_param_t uar;
748 uint32_t rsrv6[48];
750 #else
751 struct tavor_hw_initqueryhca_s {
752 uint32_t rsrv0[2];
753 uint32_t :32;
754 uint32_t hca_core_clock :8; /* QUERY_HCA only */
755 uint32_t :24;
756 uint32_t router_en :1;
757 uint32_t :7;
758 uint32_t router_qp :16;
759 uint32_t :8;
760 uint32_t wqe_quota_en :1;
761 uint32_t wqe_quota :15;
762 uint32_t :4;
763 uint32_t responder_exu :4;
764 uint32_t :5;
765 uint32_t udav_chk :1;
766 uint32_t big_endian :1;
767 uint32_t udav_port_chk :1;
768 uint32_t rsrv1[2];
769 tavor_hw_qp_ee_cq_eq_rdb_t context;
770 uint32_t rsrv2[4];
771 tavor_udav_mem_param_t udav;
772 uint32_t rsrv3[2];
773 tavor_multicast_param_t multi;
774 uint32_t rsrv4[4];
775 tavor_tpt_param_t tpt;
776 uint32_t rsrv5[4];
777 tavor_uar_param_t uar;
778 uint32_t rsrv6[48];
780 #endif
781 #define TAVOR_UDAV_PROTECT_DISABLED 0x0
782 #define TAVOR_UDAV_PROTECT_ENABLED 0x1
783 #define TAVOR_UDAV_PORTCHK_DISABLED 0x0
784 #define TAVOR_UDAV_PORTCHK_ENABLED 0x1
788 * Tavor "INIT_IB" command
789 * The INIT_IB command enables the physical layer of a given IB port.
790 * It provides control over the IB port attributes. The capabilities
791 * requested here should not exceed the device limits, as retrieved by
792 * the QUERY_DEV_LIM command (above). To query information about the IB
793 * port or node, the driver may submit GetPortInfo or GetNodeInfo MADs
794 * through the Tavor MAD_IFC command.
796 #ifdef _LITTLE_ENDIAN
797 struct tavor_hw_initib_s {
798 uint32_t max_gid :16;
799 uint32_t :16;
800 uint32_t :4;
801 uint32_t vl_cap :4;
802 uint32_t port_width_cap :4;
803 uint32_t mtu_cap :4;
804 uint32_t set_port_guid0 :1;
805 uint32_t set_node_guid :1;
806 uint32_t set_sysimg_guid :1;
807 uint32_t :13;
808 uint32_t :32;
809 uint32_t max_pkey :16;
810 uint32_t :16;
811 uint64_t guid0;
812 uint64_t node_guid;
813 uint64_t sysimg_guid;
814 uint32_t rsrv0[54];
816 #else
817 struct tavor_hw_initib_s {
818 uint32_t :13;
819 uint32_t set_sysimg_guid :1;
820 uint32_t set_node_guid :1;
821 uint32_t set_port_guid0 :1;
822 uint32_t mtu_cap :4;
823 uint32_t port_width_cap :4;
824 uint32_t vl_cap :4;
825 uint32_t :4;
826 uint32_t :16;
827 uint32_t max_gid :16;
828 uint32_t :16;
829 uint32_t max_pkey :16;
830 uint32_t :32;
831 uint64_t guid0;
832 uint64_t node_guid;
833 uint64_t sysimg_guid;
834 uint32_t rsrv0[54];
836 #endif
839 * Tavor Memory Protection Table (MPT) entries
840 * The Memory Protection Table (MPT) contains the information associated
841 * with all the regions and windows. The MPT table resides in a physically-
842 * contiguous area in HCA attached local memory, and the memory key (R_Key
843 * or L_Key) is used to calculate the physical address for accessing the
844 * entries in the table.
846 * The following structure is used in the SW2HW_MPT, QUERY_MPT, and
847 * HW2SW_MPT commands.
848 * The SW2HW_MPT command transfers ownership of an MPT entry from software
849 * to hardware. The command takes the MPT entry from the input mailbox and
850 * stores it in the MPT in the hardware. The command will fail if the
851 * requested MPT entry is already owned by the hardware or if the MPT index
852 * given in the command is inconsistent with the MPT entry memory key.
853 * The QUERY_MPT command retrieves a snapshot of an MPT entry. The command
854 * takes the current state of an MPT entry from the hardware and stores it
855 * in the output mailbox. The command will fail if the requested MPT entry
856 * is already owned by software.
857 * Finally, the HW2SW_MPT command transfers ownership of an MPT entry from
858 * the hardware to the software. The command takes the MPT entry from the
859 * hardware, invalidates it, and stores it in the output mailbox. The
860 * command will fail if the requested entry is already owned by software.
861 * The command will also fail if the MPT entry in question is a Memory
862 * Region which has Memory Windows currently bound to it.
864 #ifdef _LITTLE_ENDIAN
865 struct tavor_hw_mpt_s {
866 uint32_t page_sz :5;
867 uint32_t :27;
868 uint32_t ver :4;
869 uint32_t :4;
870 uint32_t reg_win :1;
871 uint32_t phys_addr :1;
872 uint32_t lr :1;
873 uint32_t lw :1;
874 uint32_t rr :1;
875 uint32_t rw :1;
876 uint32_t atomic :1;
877 uint32_t en_bind :1;
878 uint32_t :1;
879 uint32_t m_io :1;
880 uint32_t :10;
881 uint32_t status :4;
882 uint32_t pd :24;
883 uint32_t :8;
884 uint32_t mem_key;
885 uint64_t start_addr;
886 uint64_t reg_win_len;
887 uint32_t win_cnt;
888 uint32_t lkey;
889 uint32_t mttseg_addr_h;
890 uint32_t win_cnt_limit;
891 uint32_t :32;
892 uint32_t :6;
893 uint32_t mttseg_addr_l :26;
894 uint32_t rsrv0[2];
896 #else
897 struct tavor_hw_mpt_s {
898 uint32_t status :4;
899 uint32_t :10;
900 uint32_t m_io :1;
901 uint32_t :1;
902 uint32_t en_bind :1;
903 uint32_t atomic :1;
904 uint32_t rw :1;
905 uint32_t rr :1;
906 uint32_t lw :1;
907 uint32_t lr :1;
908 uint32_t phys_addr :1;
909 uint32_t reg_win :1;
910 uint32_t :4;
911 uint32_t ver :4;
912 uint32_t :27;
913 uint32_t page_sz :5;
914 uint32_t mem_key;
915 uint32_t :8;
916 uint32_t pd :24;
917 uint64_t start_addr;
918 uint64_t reg_win_len;
919 uint32_t lkey;
920 uint32_t win_cnt;
921 uint32_t win_cnt_limit;
922 uint32_t mttseg_addr_h;
923 uint32_t mttseg_addr_l :26;
924 uint32_t :6;
925 uint32_t :32;
926 uint32_t rsrv0[2];
928 #endif
929 #define TAVOR_MEM_CYCLE_GENERATE 0x1
930 #define TAVOR_IO_CYCLE_GENERATE 0x0
932 #define TAVOR_MPT_IS_WINDOW 0x0
933 #define TAVOR_MPT_IS_REGION 0x1
935 #define TAVOR_MPT_DEFAULT_VERSION 0x0
937 #define TAVOR_UNLIMITED_WIN_BIND 0x0
939 #define TAVOR_PHYSADDR_ENABLED 0x1
940 #define TAVOR_PHYSADDR_DISABLED 0x0
944 * Tavor Memory Translation Table (MTT) entries
945 * After accessing the MPT table (above) and validating the access rights
946 * to the region/window, Tavor address translation moves to the next step
947 * where it translates the virtual address to a physical address. This
948 * translation is performed using the Memory Translation Table entries
949 * (MTT). Note: The MTT in hardware is organized into segments and each
950 * segment contains multiple address translation pages (MTT entries).
951 * Each memory region (MPT above) points to the first segment in the MTT
952 * that corresponds to that region.
954 #ifdef _LITTLE_ENDIAN
955 struct tavor_hw_mtt_s {
956 uint32_t present :1;
957 uint32_t :11;
958 uint32_t ptag_l :20;
959 uint32_t ptag_h;
961 #else
962 struct tavor_hw_mtt_s {
963 uint32_t ptag_h;
964 uint32_t ptag_l :20;
965 uint32_t :11;
966 uint32_t present :1;
968 #endif
969 #define TAVOR_MTT_ENTRY_NOTPRESET 0x0
970 #define TAVOR_MTT_ENTRY_PRESET 0x1
974 * Tavor Event Queue Context Table (EQC) entries
975 * Tavor supports 64 Event Queues, and the status of Event Queues is stored
976 * in the Event Queue Context (EQC) table. The EQC table is a physically-
977 * contiguous memory structure in the HCA attached local memory. Each EQC
978 * table entry contains Event Queue status and information required by
979 * the hardware in order to access the event queue.
981 * The following structure is used in the SW2HW_EQ, QUERY_EQ, and HW2SW_EQ
982 * commands.
983 * The SW2HW_EQ command transfers ownership of an EQ context from software
984 * to hardware. The command takes the EQC entry from the input mailbox and
985 * stores it in the EQC in the hardware. The command will fail if the
986 * requested EQC entry is already owned by the hardware.
987 * The QUERY_EQ command retrieves a snapshot of an EQC entry. The command
988 * stores the snapshot in the output mailbox. The EQC state and its values
989 * are not affected by the QUERY_EQ command.
990 * Finally, the HW2SW_EQ command transfers ownership of an EQC entry from
991 * the hardware to the software. The command takes the EQC entry from the
992 * hardware and stores it in the output mailbox. The EQC entry will be
993 * invalidated as a result of the command. It is the responsibility of the
994 * software to unmap all the events, which might have been previously
995 * mapped to the EQ, prior to issuing the HW2SW_EQ command.
997 #ifdef _LITTLE_ENDIAN
998 struct tavor_hw_eqc_s {
999 uint32_t start_addr_h;
1000 uint32_t :8;
1001 uint32_t state :2;
1002 uint32_t :7;
1003 uint32_t overrun_ignore :1;
1004 uint32_t xlat :1;
1005 uint32_t :5;
1006 uint32_t owner :4;
1007 uint32_t status :4;
1008 uint32_t usr_page :24;
1009 uint32_t log_eq_sz :5;
1010 uint32_t :3;
1011 uint32_t start_addr_l;
1012 uint32_t intr :8;
1013 uint32_t :24;
1014 uint32_t pd :24;
1015 uint32_t :8;
1016 uint32_t lkey;
1017 uint32_t lost_cnt;
1018 uint32_t rsrv0[2];
1019 uint32_t prod_indx;
1020 uint32_t cons_indx;
1021 uint32_t rsrv1[4];
1023 #else
1024 struct tavor_hw_eqc_s {
1025 uint32_t status :4;
1026 uint32_t owner :4;
1027 uint32_t :5;
1028 uint32_t xlat :1;
1029 uint32_t overrun_ignore :1;
1030 uint32_t :7;
1031 uint32_t state :2;
1032 uint32_t :8;
1033 uint32_t start_addr_h;
1034 uint32_t start_addr_l;
1035 uint32_t :3;
1036 uint32_t log_eq_sz :5;
1037 uint32_t usr_page :24;
1038 uint32_t :8;
1039 uint32_t pd :24;
1040 uint32_t :24;
1041 uint32_t intr :8;
1042 uint32_t lost_cnt;
1043 uint32_t lkey;
1044 uint32_t rsrv0[2];
1045 uint32_t cons_indx;
1046 uint32_t prod_indx;
1047 uint32_t rsrv1[4];
1049 #endif
1050 #define TAVOR_EQ_STATUS_OK 0x0
1051 #define TAVOR_EQ_STATUS_OVERFLOW 0x9
1052 #define TAVOR_EQ_STATUS_WRITE_FAILURE 0xA
1054 #define TAVOR_EQ_ARMED 0x1
1055 #define TAVOR_EQ_FIRED 0x2
1056 #define TAVOR_EQ_ALWAYS_ARMED 0x3
1060 * Tavor Event Queue Entries (EQE)
1061 * Each EQE contains enough information for the software to identify the
1062 * source of the event. The following structures are used to define each
1063 * of the various kinds of events that the Tavor hardware will generate.
1064 * Note: The tavor_hw_eqe_t below is the generic "Event Queue Entry". All
1065 * other EQEs differ only in the contents of their "event_data" field.
1067 * Below we first define several structures which define the contents of
1068 * the "event_data" fields:
1069 * tavor_hw_eqe_cq_t for "Completion Queue Events"
1070 * tavor_hw_eqe_cqerr_t for "Completion Queue Error Events"
1071 * tavor_hw_eqe_portstate_t for "Port State Change Events"
1072 * tavor_hw_eqe_cmdcmpl_t for "Command Interface Completion Events"
1073 * tavor_hw_eqe_qp_evt_t for "Queue Pair Events" such as Path Migration
1074 * Succeeded, Path Migration Failed, Communication Established, Send
1075 * Queue Drained, Local WQ Catastrophic Error, Invalid Request Local
1076 * WQ Error, and Local Access Violation WQ Error.
1077 * tavor_hw_eqe_operr_t for "Operational and Catastrophic Error Events"
1078 * such as EQ Overflow, Misbehaved UAR page, Internal Parity Error,
1079 * Uplink bus error, and DDR data error.
1080 * tavor_hw_eqe_pgflt_t for "Not-present Page Fault on WQE or Data
1081 * Buffer Access". (Note: Currently, this event is unsupported).
1083 * Note also: The following structures are not #define'd with both
1084 * little-endian and big-endian definitions. This is because their
1085 * individual fields are not directly accessed except through the macros
1086 * defined below.
1088 typedef struct tavor_hw_eqe_cq_s {
1089 uint32_t :8;
1090 uint32_t cqn :24;
1091 uint32_t rsrv0[5];
1092 } tavor_hw_eqe_cq_t;
1094 typedef struct tavor_hw_eqe_cqerr_s {
1095 uint32_t :8;
1096 uint32_t cqn :24;
1097 uint32_t :32;
1098 uint32_t :24;
1099 uint32_t syndrome :8;
1100 uint32_t rsrv0[3];
1101 } tavor_hw_eqe_cqerr_t;
1102 #define TAVOR_CQERR_OVERFLOW 0x1
1103 #define TAVOR_CQERR_ACCESS_VIOLATION 0x2
1105 typedef struct tavor_hw_eqe_portstate_s {
1106 uint32_t rsrv0[2];
1107 uint32_t :2;
1108 uint32_t port :2;
1109 uint32_t :28;
1110 uint32_t rsrv1[3];
1111 } tavor_hw_eqe_portstate_t;
1112 #define TAVOR_PORT_LINK_ACTIVE 0x4
1113 #define TAVOR_PORT_LINK_DOWN 0x1
1115 typedef struct tavor_hw_eqe_cmdcmpl_s {
1116 uint32_t :16;
1117 uint32_t token :16;
1118 uint32_t :32;
1119 uint32_t :24;
1120 uint32_t status :8;
1121 uint32_t out_param0;
1122 uint32_t out_param1;
1123 uint32_t :32;
1124 } tavor_hw_eqe_cmdcmpl_t;
1126 typedef struct tavor_hw_eqe_qp_evt_s {
1127 uint32_t :8;
1128 uint32_t qpn :24;
1129 uint32_t :32;
1130 uint32_t :3;
1131 uint32_t qp_ee :1;
1132 uint32_t :28;
1133 uint32_t rsrv0[3];
1134 } tavor_hw_eqe_qpevt_t;
1136 typedef struct tavor_hw_eqe_operr_s {
1137 uint32_t rsrv0[2];
1138 uint32_t :24;
1139 uint32_t error_type :8;
1140 uint32_t data;
1141 uint32_t rsrv1[2];
1142 } tavor_hw_eqe_operr_t;
1143 #define TAVOR_ERREVT_EQ_OVERFLOW 0x1
1144 #define TAVOR_ERREVT_BAD_UARPG 0x2
1145 #define TAVOR_ERREVT_UPLINK_BUSERR 0x3
1146 #define TAVOR_ERREVT_DDR_DATAERR 0x4
1147 #define TAVOR_ERREVT_INTERNAL_PARITY 0x5
1149 typedef struct tavor_hw_eqe_pgflt_s {
1150 uint32_t rsrv0[2];
1151 uint32_t :24;
1152 uint32_t fault_type :4;
1153 uint32_t wqv :1;
1154 uint32_t wqe_data :1;
1155 uint32_t rem_loc :1;
1156 uint32_t snd_rcv :1;
1157 uint32_t vaddr_h;
1158 uint32_t vaddr_l;
1159 uint32_t mem_key;
1160 } tavor_hw_eqe_pgflt_t;
1161 #define TAVOR_PGFLT_PG_NOTPRESENT 0x8
1162 #define TAVOR_PGFLT_PG_WRACC_VIOL 0xA
1163 #define TAVOR_PGFLT_UNSUP_NOTPRESENT 0xE
1164 #define TAVOR_PGFLT_UNSUP_WRACC_VIOL 0xF
1165 #define TAVOR_PGFLT_WQE_CAUSED 0x1
1166 #define TAVOR_PGFLT_DATA_CAUSED 0x0
1167 #define TAVOR_PGFLT_REMOTE_CAUSED 0x1
1168 #define TAVOR_PGFLT_LOCAL_CAUSED 0x0
1169 #define TAVOR_PGFLT_SEND_CAUSED 0x1
1170 #define TAVOR_PGFLT_RECV_CAUSED 0x0
1171 #define TAVOR_PGFLT_DESC_CONSUMED 0x1
1172 #define TAVOR_PGFLT_DESC_NOTCONSUMED 0x0
1174 typedef struct tavor_hw_eqe_ecc_s {
1175 uint32_t rsrcv0[4];
1176 uint32_t overflow :1;
1177 uint32_t :15;
1178 uint32_t :2;
1179 uint32_t err_ba :2;
1180 uint32_t err_da :2;
1181 uint32_t err_src_id :3;
1182 uint32_t err_rmw :1;
1183 uint32_t :2;
1184 uint32_t cause_msb :1;
1185 uint32_t :2;
1186 uint32_t cause_lsb :1;
1188 uint32_t err_ca :16;
1189 uint32_t err_ra :16;
1190 } tavor_hw_eqe_ecc_t;
1192 struct tavor_hw_eqe_s {
1193 uint32_t :8;
1194 uint32_t event_type :8;
1195 uint32_t :8;
1196 uint32_t event_subtype :8;
1197 union {
1198 tavor_hw_eqe_cq_t eqe_cq;
1199 tavor_hw_eqe_cqerr_t eqe_cqerr;
1200 tavor_hw_eqe_portstate_t eqe_portstate;
1201 tavor_hw_eqe_cmdcmpl_t eqe_cmdcmpl;
1202 tavor_hw_eqe_qpevt_t eqe_qpevt;
1203 tavor_hw_eqe_operr_t eqe_operr;
1204 tavor_hw_eqe_pgflt_t eqe_pgflt;
1205 tavor_hw_eqe_ecc_t eqe_ecc;
1206 } event_data;
1207 uint32_t :24;
1208 uint32_t owner :1;
1209 uint32_t :7;
1211 #define eqe_cq event_data.eqe_cq
1212 #define eqe_cqerr event_data.eqe_cqerr
1213 #define eqe_portstate event_data.eqe_portstate
1214 #define eqe_cmdcmpl event_data.eqe_cmdcmpl
1215 #define eqe_qpevt event_data.eqe_qpevt
1216 #define eqe_operr event_data.eqe_operr
1217 #define eqe_pgflt event_data.eqe_pgflt
1220 * The following macros are used for extracting (and in some cases filling in)
1221 * information from EQEs
1223 #define TAVOR_EQE_EVTTYPE_MASK 0x00FF0000
1224 #define TAVOR_EQE_EVTTYPE_SHIFT 16
1225 #define TAVOR_EQE_EVTSUBTYPE_MASK 0x000000FF
1226 #define TAVOR_EQE_EVTSUBTYPE_SHIFT 0
1227 #define TAVOR_EQE_CQNUM_MASK 0x00FFFFFF
1228 #define TAVOR_EQE_CQNUM_SHIFT 0
1229 #define TAVOR_EQE_QPNUM_MASK 0x00FFFFFF
1230 #define TAVOR_EQE_QPNUM_SHIFT 0
1231 #define TAVOR_EQE_PORTNUM_MASK 0x30000000
1232 #define TAVOR_EQE_PORTNUM_SHIFT 28
1233 #define TAVOR_EQE_CMDTOKEN_MASK 0x0000FFFF
1234 #define TAVOR_EQE_CMDTOKEN_SHIFT 0
1235 #define TAVOR_EQE_CMDSTATUS_MASK 0x000000FF
1236 #define TAVOR_EQE_CMDSTATUS_SHIFT 0
1237 #define TAVOR_EQE_OPERRTYPE_MASK 0x000000FF
1238 #define TAVOR_EQE_OPERRTYPE_SHIFT 0
1239 #define TAVOR_EQE_OWNER_MASK 0x00000080
1240 #define TAVOR_EQE_OWNER_SHIFT 7
1242 #define TAVOR_EQE_EVTTYPE_GET(eq, eqe) \
1243 ((ddi_get32((eq)->eq_eqinfo.qa_acchdl, \
1244 &((uint32_t *)(eqe))[0]) & TAVOR_EQE_EVTTYPE_MASK) >> \
1245 TAVOR_EQE_EVTTYPE_SHIFT)
1246 #define TAVOR_EQE_EVTSUBTYPE_GET(eq, eqe) \
1247 ((ddi_get32((eq)->eq_eqinfo.qa_acchdl, \
1248 &((uint32_t *)(eqe))[0]) & TAVOR_EQE_EVTSUBTYPE_MASK) >> \
1249 TAVOR_EQE_EVTSUBTYPE_SHIFT)
1250 #define TAVOR_EQE_CQNUM_GET(eq, eqe) \
1251 ((ddi_get32((eq)->eq_eqinfo.qa_acchdl, \
1252 &((uint32_t *)(eqe))[1]) & TAVOR_EQE_CQNUM_MASK) >> \
1253 TAVOR_EQE_CQNUM_SHIFT)
1254 #define TAVOR_EQE_QPNUM_GET(eq, eqe) \
1255 ((ddi_get32((eq)->eq_eqinfo.qa_acchdl, \
1256 &((uint32_t *)(eqe))[1]) & TAVOR_EQE_QPNUM_MASK) >> \
1257 TAVOR_EQE_QPNUM_SHIFT)
1258 #define TAVOR_EQE_PORTNUM_GET(eq, eqe) \
1259 ((ddi_get32((eq)->eq_eqinfo.qa_acchdl, \
1260 &((uint32_t *)(eqe))[3]) & TAVOR_EQE_PORTNUM_MASK) >> \
1261 TAVOR_EQE_PORTNUM_SHIFT)
1262 #define TAVOR_EQE_CMDTOKEN_GET(eq, eqe) \
1263 ((ddi_get32((eq)->eq_eqinfo.qa_acchdl, \
1264 &((uint32_t *)(eqe))[1]) & TAVOR_EQE_CMDTOKEN_MASK) >> \
1265 TAVOR_EQE_CMDTOKEN_SHIFT)
1266 #define TAVOR_EQE_CMDSTATUS_GET(eq, eqe) \
1267 ((ddi_get32((eq)->eq_eqinfo.qa_acchdl, \
1268 &((uint32_t *)(eqe))[3]) & TAVOR_EQE_CMDSTATUS_MASK) >> \
1269 TAVOR_EQE_CMDSTATUS_SHIFT)
1270 #define TAVOR_EQE_CMDOUTP0_GET(eq, eqe) \
1271 (ddi_get32((eq)->eq_eqinfo.qa_acchdl, &((uint32_t *)(eqe))[4]))
1272 #define TAVOR_EQE_CMDOUTP1_GET(eq, eqe) \
1273 (ddi_get32((eq)->eq_eqinfo.qa_acchdl, &((uint32_t *)(eqe))[5]))
1274 #define TAVOR_EQE_OPERRTYPE_GET(eq, eqe) \
1275 ((ddi_get32((eq)->eq_eqinfo.qa_acchdl, \
1276 &((uint32_t *)(eqe))[3]) & TAVOR_EQE_OPERRTYPE_MASK) >> \
1277 TAVOR_EQE_OPERRTYPE_SHIFT)
1278 #define TAVOR_EQE_OPERRDATA_GET(eq, eqe) \
1279 (ddi_get32((eq)->eq_eqinfo.qa_acchdl, &((uint32_t *)(eqe))[4]))
1280 #define TAVOR_EQE_OWNER_IS_SW(eq, eqe) \
1281 (((ddi_get32((eq)->eq_eqinfo.qa_acchdl, \
1282 &((uint32_t *)(eqe))[7]) & TAVOR_EQE_OWNER_MASK) >> \
1283 TAVOR_EQE_OWNER_SHIFT) == TAVOR_SW_OWNER)
1284 #define TAVOR_EQE_OWNER_SET_HW(eq, eqe) \
1285 (ddi_put32((eq)->eq_eqinfo.qa_acchdl, &((uint32_t *)(eqe))[7], \
1286 ((TAVOR_HW_OWNER << TAVOR_EQE_OWNER_SHIFT) & \
1287 TAVOR_EQE_OWNER_MASK)))
1291 * Tavor Completion Queue Context Table (CQC) entries
1292 * The CQC table is a physically-contiguous memory area residing in HCA
1293 * attached local memory. Each CQC table entry contains information
1294 * required by the hardware to access the completion queue to post
1295 * completions (CQE).
1297 * The following structure is used in the SW2HW_CQ, QUERY_CQ, RESIZE_CQ,
1298 * and HW2SW_CQ commands.
1299 * The SW2HW_CQ command transfers ownership of an CQ context from software
1300 * to hardware. The command takes the CQC entry from the input mailbox and
1301 * stores it in the CQC in the hardware. The command will fail if the
1302 * requested CQC entry is already owned by the hardware.
1303 * The QUERY_CQ command retrieves a snapshot of a CQC entry. The command
1304 * stores the snapshot in the output mailbox. The CQC state and its values
1305 * are not affected by the QUERY_CQ command.
1306 * Finally, the HW2SW_CQ command transfers ownership of a CQC entry from
1307 * the hardware to the software. The command takes the CQC entry from the
1308 * hardware and stores it in the output mailbox. The CQC entry will be
1309 * invalidated as a result of the command.
1311 #ifdef _LITTLE_ENDIAN
1312 struct tavor_hw_cqc_s {
1313 uint32_t start_addr_h;
1314 uint32_t :8;
1315 uint32_t state :4;
1316 uint32_t :5;
1317 uint32_t overrun_ignore :1;
1318 uint32_t xlat :1;
1319 uint32_t :9;
1320 uint32_t status :4;
1321 uint32_t usr_page :24;
1322 uint32_t log_cq_sz :5;
1323 uint32_t :3;
1324 uint32_t start_addr_l;
1325 uint32_t c_eqn :8;
1326 uint32_t :24;
1327 uint32_t e_eqn :8;
1328 uint32_t :24;
1329 uint32_t lkey;
1330 uint32_t pd :24;
1331 uint32_t :8;
1332 uint32_t solicit_prod_indx;
1333 uint32_t last_notified_indx;
1334 uint32_t prod_indx;
1335 uint32_t cons_indx;
1336 uint32_t :32;
1337 uint32_t cqn :24;
1338 uint32_t :8;
1339 uint32_t rsrv0[2];
1341 #else
1342 struct tavor_hw_cqc_s {
1343 uint32_t status :4;
1344 uint32_t :9;
1345 uint32_t xlat :1;
1346 uint32_t overrun_ignore :1;
1347 uint32_t :5;
1348 uint32_t state :4;
1349 uint32_t :8;
1350 uint32_t start_addr_h;
1351 uint32_t start_addr_l;
1352 uint32_t :3;
1353 uint32_t log_cq_sz :5;
1354 uint32_t usr_page :24;
1355 uint32_t :24;
1356 uint32_t e_eqn :8;
1357 uint32_t :24;
1358 uint32_t c_eqn :8;
1359 uint32_t :8;
1360 uint32_t pd :24;
1361 uint32_t lkey;
1362 uint32_t last_notified_indx;
1363 uint32_t solicit_prod_indx;
1364 uint32_t cons_indx;
1365 uint32_t prod_indx;
1366 uint32_t :8;
1367 uint32_t cqn :24;
1368 uint32_t :32;
1369 uint32_t rsrv0[2];
1371 #endif
1372 #define TAVOR_CQ_STATUS_OK 0x0
1373 #define TAVOR_CQ_STATUS_OVERFLOW 0x9
1374 #define TAVOR_CQ_STATUS_WRITE_FAILURE 0xA
1376 #define TAVOR_CQ_DISARMED 0x0
1377 #define TAVOR_CQ_ARMED 0x1
1378 #define TAVOR_CQ_ARMED_SOLICITED 0x4
1379 #define TAVOR_CQ_FIRED 0xA
1382 * Tavor Completion Queue Entries (CQE)
1383 * Each CQE contains enough information for the software to associate the
1384 * completion with the Work Queue Element (WQE) to which it corresponds.
1386 * Note: The following structure is not #define'd with both little-endian
1387 * and big-endian definitions. This is because each CQE's individual
1388 * fields are not directly accessed except through the macros defined below.
1390 struct tavor_hw_cqe_s {
1391 uint32_t ver :4;
1392 uint32_t :4;
1393 uint32_t my_qpn :24;
1394 uint32_t :8;
1395 uint32_t my_ee :24;
1396 uint32_t :8;
1397 uint32_t rqpn :24;
1398 uint32_t sl :4;
1399 uint32_t :4;
1400 uint32_t grh :1;
1401 uint32_t ml_path :7;
1402 uint32_t rlid :16;
1403 uint32_t imm_eth_pkey_cred;
1404 uint32_t byte_cnt;
1405 uint32_t wqe_addr :26;
1406 uint32_t wqe_sz :6;
1407 uint32_t opcode :8;
1408 uint32_t send_or_recv :1;
1409 uint32_t :15;
1410 uint32_t owner :1;
1411 uint32_t :7;
1413 #define TAVOR_COMPLETION_RECV 0x0
1414 #define TAVOR_COMPLETION_SEND 0x1
1416 #define TAVOR_CQE_DEFAULT_VERSION 0x0
1419 * The following macros are used for extracting (and in some cases filling in)
1420 * information from CQEs
1422 #define TAVOR_CQE_QPNUM_MASK 0x00FFFFFF
1423 #define TAVOR_CQE_QPNUM_SHIFT 0
1424 #define TAVOR_CQE_DQPN_MASK 0x00FFFFFF
1425 #define TAVOR_CQE_DQPN_SHIFT 0
1426 #define TAVOR_CQE_SL_MASK 0xF0000000
1427 #define TAVOR_CQE_SL_SHIFT 28
1428 #define TAVOR_CQE_GRH_MASK 0x00800000
1429 #define TAVOR_CQE_GRH_SHIFT 23
1430 #define TAVOR_CQE_PATHBITS_MASK 0x007F0000
1431 #define TAVOR_CQE_PATHBITS_SHIFT 16
1432 #define TAVOR_CQE_DLID_MASK 0x0000FFFF
1433 #define TAVOR_CQE_DLID_SHIFT 0
1434 #define TAVOR_CQE_OPCODE_MASK 0xFF000000
1435 #define TAVOR_CQE_OPCODE_SHIFT 24
1436 #define TAVOR_CQE_SENDRECV_MASK 0x00800000
1437 #define TAVOR_CQE_SENDRECV_SHIFT 23
1438 #define TAVOR_CQE_OWNER_MASK 0x00000080
1439 #define TAVOR_CQE_OWNER_SHIFT 7
1441 #define TAVOR_CQE_QPNUM_GET(cq, cqe) \
1442 ((ddi_get32((cq)->cq_cqinfo.qa_acchdl, \
1443 &((uint32_t *)(cqe))[0]) & TAVOR_CQE_QPNUM_MASK) >> \
1444 TAVOR_CQE_QPNUM_SHIFT)
1445 #define TAVOR_CQE_DQPN_GET(cq, cqe) \
1446 ((ddi_get32((cq)->cq_cqinfo.qa_acchdl, \
1447 &((uint32_t *)(cqe))[2]) & TAVOR_CQE_DQPN_MASK) >> \
1448 TAVOR_CQE_DQPN_SHIFT)
1449 #define TAVOR_CQE_SL_GET(cq, cqe) \
1450 ((ddi_get32((cq)->cq_cqinfo.qa_acchdl, \
1451 &((uint32_t *)(cqe))[3]) & TAVOR_CQE_SL_MASK) >> \
1452 TAVOR_CQE_SL_SHIFT)
1453 #define TAVOR_CQE_GRH_GET(cq, cqe) \
1454 ((ddi_get32((cq)->cq_cqinfo.qa_acchdl, \
1455 &((uint32_t *)(cqe))[3]) & TAVOR_CQE_GRH_MASK) >> \
1456 TAVOR_CQE_GRH_SHIFT)
1457 #define TAVOR_CQE_PATHBITS_GET(cq, cqe) \
1458 ((ddi_get32((cq)->cq_cqinfo.qa_acchdl, \
1459 &((uint32_t *)(cqe))[3]) & TAVOR_CQE_PATHBITS_MASK) >> \
1460 TAVOR_CQE_PATHBITS_SHIFT)
1461 #define TAVOR_CQE_DLID_GET(cq, cqe) \
1462 ((ddi_get32((cq)->cq_cqinfo.qa_acchdl, \
1463 &((uint32_t *)(cqe))[3]) & TAVOR_CQE_DLID_MASK) >> \
1464 TAVOR_CQE_DLID_SHIFT)
1465 #define TAVOR_CQE_IMM_ETH_PKEY_CRED_GET(cq, cqe) \
1466 (ddi_get32((cq)->cq_cqinfo.qa_acchdl, &((uint32_t *)(cqe))[4]))
1467 #define TAVOR_CQE_IMM_ETH_PKEY_CRED_SET(cq, cqe, arg) \
1468 (ddi_put32((cq)->cq_cqinfo.qa_acchdl, &((uint32_t *)(cqe))[4], \
1469 (arg)))
1470 #define TAVOR_CQE_BYTECNT_GET(cq, cqe) \
1471 (ddi_get32((cq)->cq_cqinfo.qa_acchdl, &((uint32_t *)(cqe))[5]))
1472 #define TAVOR_CQE_WQEADDRSZ_GET(cq, cqe) \
1473 (ddi_get32((cq)->cq_cqinfo.qa_acchdl, &((uint32_t *)(cqe))[6]))
1474 #define TAVOR_CQE_WQEADDRSZ_SET(cq, cqe, arg) \
1475 (ddi_put32((cq)->cq_cqinfo.qa_acchdl, &((uint32_t *)(cqe))[6], \
1476 (arg)))
1477 #define TAVOR_CQE_OPCODE_GET(cq, cqe) \
1478 ((ddi_get32((cq)->cq_cqinfo.qa_acchdl, \
1479 &((uint32_t *)(cqe))[7]) & TAVOR_CQE_OPCODE_MASK) >> \
1480 TAVOR_CQE_OPCODE_SHIFT)
1481 #define TAVOR_CQE_SENDRECV_GET(cq, cqe) \
1482 ((ddi_get32((cq)->cq_cqinfo.qa_acchdl, \
1483 &((uint32_t *)(cqe))[7]) & TAVOR_CQE_SENDRECV_MASK) >> \
1484 TAVOR_CQE_SENDRECV_SHIFT)
1485 #define TAVOR_CQE_OWNER_IS_SW(cq, cqe) \
1486 (((ddi_get32((cq)->cq_cqinfo.qa_acchdl, \
1487 &((uint32_t *)(cqe))[7]) & TAVOR_CQE_OWNER_MASK) >> \
1488 TAVOR_CQE_OWNER_SHIFT) == TAVOR_SW_OWNER)
1489 #ifdef _LITTLE_ENDIAN
1490 #define TAVOR_CQE_OWNER_SET_HW(cq, cqe) \
1492 if ((cq)->cq_is_umap) { \
1493 ((uint32_t *)(cqe))[7] = 0x80000000; \
1494 } else { \
1495 ddi_put32((cq)->cq_cqinfo.qa_acchdl, \
1496 &((uint32_t *)(cqe))[7], 0x00000080); \
1499 #else
1500 #define TAVOR_CQE_OWNER_SET_HW(cq, cqe) \
1502 if ((cq)->cq_is_umap) { \
1503 ((uint32_t *)(cqe))[7] = 0x00000080; \
1504 } else { \
1505 ddi_put32((cq)->cq_cqinfo.qa_acchdl, \
1506 &((uint32_t *)(cqe))[7], 0x00000080); \
1509 #endif
1512 * Tavor Shared Receive Queue (SRQ) Context Entry Format
1514 #ifdef _LITTLE_ENDIAN
1515 struct tavor_hw_srqc_s {
1516 uint32_t ds :5;
1517 uint32_t next_wqe_addr_l :27;
1518 uint32_t wqe_addr_h;
1520 uint32_t lkey;
1521 uint32_t pd :24;
1522 uint32_t :4;
1523 uint32_t state :4;
1525 uint32_t wqe_cnt :16;
1526 uint32_t :16;
1527 uint32_t uar :24;
1528 uint32_t :8;
1530 #else
1531 struct tavor_hw_srqc_s {
1532 uint32_t wqe_addr_h;
1533 uint32_t next_wqe_addr_l :27;
1534 uint32_t ds :5;
1536 uint32_t state :4;
1537 uint32_t :4;
1538 uint32_t pd :24;
1539 uint32_t lkey;
1541 uint32_t :8;
1542 uint32_t uar :24;
1543 uint32_t :16;
1544 uint32_t wqe_cnt :16;
1546 #endif
1549 * Tavor MOD_STAT_CFG input mailbox structure
1551 #ifdef _LITTLE_ENDIAN
1552 struct tavor_hw_mod_stat_cfg_s {
1553 uint32_t :32;
1554 uint32_t log_max_srq :5;
1555 uint32_t :1;
1556 uint32_t srq :1;
1557 uint32_t srq_m :1;
1558 uint32_t :24;
1559 uint32_t reserved[62];
1561 #else
1562 struct tavor_hw_mod_stat_cfg_s {
1563 uint32_t :24;
1564 uint32_t srq_m :1;
1565 uint32_t srq :1;
1566 uint32_t :1;
1567 uint32_t log_max_srq :5;
1568 uint32_t :32;
1569 uint32_t reserved[62];
1571 #endif
1574 * Tavor UD Address Vector (UDAV)
1575 * Tavor UDAV are used in conjunction with Unreliable Datagram (UD) send
1576 * WQEs. Each UD send message specifies an address vector that denotes its
1577 * link and (optional) network layer destination address. The IBA verbs
1578 * interface enables the separation of the address administration from the
1579 * send WQE posting. The verbs consumer must use special verbs to create
1580 * and modify address handles (which represent hardware address vectors).
1581 * When posting send WQEs to UD QP, the verbs consumer must supply a
1582 * valid address handle/UDAV.
1584 #ifdef _LITTLE_ENDIAN
1585 struct tavor_hw_udav_s {
1586 uint32_t rlid :16;
1587 uint32_t ml_path :7;
1588 uint32_t grh :1;
1589 uint32_t :8;
1590 uint32_t pd :24;
1591 uint32_t portnum :2;
1592 uint32_t :6;
1593 uint32_t flow_label :20;
1594 uint32_t tclass :8;
1595 uint32_t sl :4;
1596 uint32_t hop_limit :8;
1597 uint32_t max_stat_rate :3;
1598 uint32_t :1;
1599 uint32_t msg_sz :2;
1600 uint32_t :2;
1601 uint32_t mgid_index :6;
1602 uint32_t :10;
1603 uint64_t rgid_h;
1604 uint64_t rgid_l;
1606 #else
1607 struct tavor_hw_udav_s {
1608 uint32_t :6;
1609 uint32_t portnum :2;
1610 uint32_t pd :24;
1611 uint32_t :8;
1612 uint32_t grh :1;
1613 uint32_t ml_path :7;
1614 uint32_t rlid :16;
1615 uint32_t :10;
1616 uint32_t mgid_index :6;
1617 uint32_t :2;
1618 uint32_t msg_sz :2;
1619 uint32_t :1;
1620 uint32_t max_stat_rate :3;
1621 uint32_t hop_limit :8;
1622 uint32_t sl :4;
1623 uint32_t tclass :8;
1624 uint32_t flow_label :20;
1625 uint64_t rgid_h;
1626 uint64_t rgid_l;
1628 #endif
1629 #define TAVOR_UDAV_MODIFY_MASK0 0xFCFFFFFFFF000000ULL
1630 #define TAVOR_UDAV_MODIFY_MASK1 0xFFC0F80000000000ULL
1634 * Tavor Queue Pair Context Table (QPC) entries
1635 * The QPC table is a physically-contiguous memory area residing in HCA
1636 * attached local memory. Each QPC entry is accessed for reads and writes
1637 * by the HCA while executing work requests on the associated QP.
1639 * The following structure is used in the RST2INIT_QP, INIT2INIT_QP,
1640 * INIT2RTR_QP, RTR2RTS_QP, RTS2RTS_QP, SQERR2RTS_QP, TOERR_QP, RTS2SQD_QP,
1641 * SQD2RTS_QP, TORST_QP, and QUERY_QP commands.
1642 * With the exception of the QUERY_QP command, each of these commands reads
1643 * from some portion of the QPC in the input mailbox and modified the QPC
1644 * stored in the hardware. The QUERY_QP command retrieves a snapshot of a
1645 * QPC entry. The command stores the snapshot in the output mailbox. The
1646 * QPC state and its values are not affected by the QUERY_QP command.
1648 * Below we first define the tavor_hw_addr_path_t or "Tavor Address Path"
1649 * structure. This structure is used to provide address path information
1650 * (both primary and secondary) for each QP context. Note: Since this
1651 * structure is _very_ similar to the tavor_hw_udav_t structure above,
1652 * we are able to leverage the similarity with filling in and reading from
1653 * the two types of structures. See tavor_get_addr_path() and
1654 * tavor_set_addr_path() in tavor_misc.c for more details.
1656 #ifdef _LITTLE_ENDIAN
1657 struct tavor_hw_addr_path_s {
1658 uint32_t rlid :16;
1659 uint32_t ml_path :7;
1660 uint32_t grh :1;
1661 uint32_t :5;
1662 uint32_t rnr_retry :3;
1663 uint32_t pkey_indx :7;
1664 uint32_t :17;
1665 uint32_t portnum :2;
1666 uint32_t :6;
1667 uint32_t flow_label :20;
1668 uint32_t tclass :8;
1669 uint32_t sl :4;
1670 uint32_t hop_limit :8;
1671 uint32_t max_stat_rate :3;
1672 uint32_t :5;
1673 uint32_t mgid_index :6;
1674 uint32_t :5;
1675 uint32_t ack_timeout :5;
1676 uint64_t rgid_h;
1677 uint64_t rgid_l;
1679 #else
1680 struct tavor_hw_addr_path_s {
1681 uint32_t :6;
1682 uint32_t portnum :2;
1683 uint32_t :17;
1684 uint32_t pkey_indx :7;
1685 uint32_t rnr_retry :3;
1686 uint32_t :5;
1687 uint32_t grh :1;
1688 uint32_t ml_path :7;
1689 uint32_t rlid :16;
1690 uint32_t ack_timeout :5;
1691 uint32_t :5;
1692 uint32_t mgid_index :6;
1693 uint32_t :5;
1694 uint32_t max_stat_rate :3;
1695 uint32_t hop_limit :8;
1696 uint32_t sl :4;
1697 uint32_t tclass :8;
1698 uint32_t flow_label :20;
1699 uint64_t rgid_h;
1700 uint64_t rgid_l;
1702 #endif
1704 #ifdef _LITTLE_ENDIAN
1705 struct tavor_hw_qpc_s {
1706 uint32_t sched_q :4;
1707 uint32_t :28;
1708 uint32_t :8;
1709 uint32_t de :1;
1710 uint32_t :2;
1711 uint32_t pm_state :2;
1712 uint32_t :3;
1713 uint32_t serv_type :3;
1714 uint32_t :9;
1715 uint32_t state :4;
1716 uint32_t usr_page :24;
1717 uint32_t :8;
1718 uint32_t :24;
1719 uint32_t msg_max :5;
1720 uint32_t mtu :3;
1721 uint32_t rem_qpn :24;
1722 uint32_t :8;
1723 uint32_t loc_qpn :24;
1724 uint32_t :8;
1725 uint32_t :32;
1726 uint32_t :32;
1727 tavor_hw_addr_path_t pri_addr_path;
1728 tavor_hw_addr_path_t alt_addr_path;
1729 uint32_t pd :24;
1730 uint32_t :8;
1731 uint32_t rdd :24;
1732 uint32_t :8;
1733 uint32_t wqe_lkey;
1734 uint32_t wqe_baseaddr;
1735 uint32_t :32;
1736 uint32_t :3;
1737 uint32_t ssc :1;
1738 uint32_t sic :1;
1739 uint32_t cur_retry_cnt :3;
1740 uint32_t cur_rnr_retry :3;
1741 uint32_t :2;
1742 uint32_t sae :1;
1743 uint32_t swe :1;
1744 uint32_t sre :1;
1745 uint32_t retry_cnt :3;
1746 uint32_t :2;
1747 uint32_t sra_max :3;
1748 uint32_t flight_lim :4;
1749 uint32_t ack_req_freq :4;
1750 uint32_t cqn_snd :24;
1751 uint32_t :8;
1752 uint32_t next_snd_psn :24;
1753 uint32_t :8;
1754 uint64_t next_snd_wqe;
1755 uint32_t ssn :24;
1756 uint32_t :8;
1757 uint32_t last_acked_psn :24;
1758 uint32_t :8;
1759 uint32_t next_rcv_psn :24;
1760 uint32_t min_rnr_nak :5;
1761 uint32_t :3;
1762 uint32_t :3;
1763 uint32_t rsc :1;
1764 uint32_t ric :1;
1765 uint32_t :8;
1766 uint32_t rae :1;
1767 uint32_t rwe :1;
1768 uint32_t rre :1;
1769 uint32_t :5;
1770 uint32_t rra_max :3;
1771 uint32_t :8;
1772 uint32_t cqn_rcv :24;
1773 uint32_t :8;
1774 uint32_t :5;
1775 uint32_t ra_buff_indx :27;
1776 uint64_t next_rcv_wqe;
1777 uint32_t srq_number :24;
1778 uint32_t srq_en :1;
1779 uint32_t :7;
1780 uint32_t qkey;
1781 uint32_t :32;
1782 uint32_t rmsn :24;
1783 uint32_t :8;
1784 uint32_t rsrv0[18];
1786 #else
1787 struct tavor_hw_qpc_s {
1788 uint32_t state :4;
1789 uint32_t :9;
1790 uint32_t serv_type :3;
1791 uint32_t :3;
1792 uint32_t pm_state :2;
1793 uint32_t :2;
1794 uint32_t de :1;
1795 uint32_t :8;
1796 uint32_t :28;
1797 uint32_t sched_q :4;
1798 uint32_t mtu :3;
1799 uint32_t msg_max :5;
1800 uint32_t :24;
1801 uint32_t :8;
1802 uint32_t usr_page :24;
1803 uint32_t :8;
1804 uint32_t loc_qpn :24;
1805 uint32_t :8;
1806 uint32_t rem_qpn :24;
1807 uint32_t :32;
1808 uint32_t :32;
1809 tavor_hw_addr_path_t pri_addr_path;
1810 tavor_hw_addr_path_t alt_addr_path;
1811 uint32_t :8;
1812 uint32_t rdd :24;
1813 uint32_t :8;
1814 uint32_t pd :24;
1815 uint32_t wqe_baseaddr;
1816 uint32_t wqe_lkey;
1817 uint32_t ack_req_freq :4;
1818 uint32_t flight_lim :4;
1819 uint32_t sra_max :3;
1820 uint32_t :2;
1821 uint32_t retry_cnt :3;
1822 uint32_t sre :1;
1823 uint32_t swe :1;
1824 uint32_t sae :1;
1825 uint32_t :2;
1826 uint32_t cur_rnr_retry :3;
1827 uint32_t cur_retry_cnt :3;
1828 uint32_t sic :1;
1829 uint32_t ssc :1;
1830 uint32_t :3;
1831 uint32_t :32;
1832 uint32_t :8;
1833 uint32_t next_snd_psn :24;
1834 uint32_t :8;
1835 uint32_t cqn_snd :24;
1836 uint64_t next_snd_wqe;
1837 uint32_t :8;
1838 uint32_t last_acked_psn :24;
1839 uint32_t :8;
1840 uint32_t ssn :24;
1841 uint32_t :8;
1842 uint32_t rra_max :3;
1843 uint32_t :5;
1844 uint32_t rre :1;
1845 uint32_t rwe :1;
1846 uint32_t rae :1;
1847 uint32_t :8;
1848 uint32_t ric :1;
1849 uint32_t rsc :1;
1850 uint32_t :3;
1851 uint32_t :3;
1852 uint32_t min_rnr_nak :5;
1853 uint32_t next_rcv_psn :24;
1854 uint32_t ra_buff_indx :27;
1855 uint32_t :5;
1856 uint32_t :8;
1857 uint32_t cqn_rcv :24;
1858 uint64_t next_rcv_wqe;
1859 uint32_t qkey;
1860 uint32_t :7;
1861 uint32_t srq_en :1;
1862 uint32_t srq_number :24;
1863 uint32_t :8;
1864 uint32_t rmsn :24;
1865 uint32_t :32;
1866 uint32_t rsrv0[18];
1868 #endif
1869 #define TAVOR_QP_RESET 0x0
1870 #define TAVOR_QP_INIT 0x1
1871 #define TAVOR_QP_RTR 0x2
1872 #define TAVOR_QP_RTS 0x3
1873 #define TAVOR_QP_SQERR 0x4
1874 #define TAVOR_QP_SQD 0x5
1875 #define TAVOR_QP_ERR 0x6
1876 #define TAVOR_QP_SQDRAINING 0x7
1878 #define TAVOR_QP_RC 0x0
1879 #define TAVOR_QP_UC 0x1
1880 #define TAVOR_QP_UD 0x3
1881 #define TAVOR_QP_MLX 0x7
1883 #define TAVOR_QP_PMSTATE_MIGRATED 0x3
1884 #define TAVOR_QP_PMSTATE_ARMED 0x0
1885 #define TAVOR_QP_PMSTATE_REARM 0x1
1887 #define TAVOR_QP_DESC_EVT_DISABLED 0x0
1888 #define TAVOR_QP_DESC_EVT_ENABLED 0x1
1890 #define TAVOR_QP_FLIGHT_LIM_UNLIMITED 0xF
1892 #define TAVOR_QP_SQ_ALL_SIGNALED 0x1
1893 #define TAVOR_QP_SQ_WR_SIGNALED 0x0
1894 #define TAVOR_QP_RQ_ALL_SIGNALED 0x1
1895 #define TAVOR_QP_RQ_WR_SIGNALED 0x0
1897 #define TAVOR_QP_SRQ_ENABLED 0x1
1898 #define TAVOR_QP_SRQ_DISABLED 0x0
1902 * Tavor Multicast Group Member (MCG)
1903 * Tavor MCG are organized in a physically-contiguous memory table (the
1904 * Multicast Group Table) in the HCA attached local memory. This table is
1905 * actually comprised of two consecutive tables: the Multicast Group Hash
1906 * Table (MGHT) and the Additional Multicast Group Members Table (AMGM).
1907 * Each such entry contains an MGID and a list of QPs that are attached to
1908 * the multicast group. Each such entry may also include an index to an
1909 * Additional Multicast Group Member Table (AMGM) entry. The AMGMs are
1910 * used to form a linked list of MCG entries that all map to the same hash
1911 * value. The MCG entry size is configured through the INIT_HCA command.
1912 * Note: An MCG actually consists of a single tavor_hw_mcg_t and some
1913 * number of tavor_hw_mcg_qp_list_t (such that the combined structure is a
1914 * power-of-2).
1916 * The following structures are used in the READ_MGM and WRITE_MGM commands.
1917 * The READ_MGM command reads an MCG entry from the multicast table and
1918 * returns it in the output mailbox. Note: This operation does not affect
1919 * the MCG entry state or values.
1920 * The WRITE_MGM command retrieves an MCG entry from the input mailbox and
1921 * stores it in the multicast group table at the index specified in the
1922 * command. Once the command has finished execution, the multicast group
1923 * table is updated. The old entry contents are lost.
1925 #ifdef _LITTLE_ENDIAN
1926 struct tavor_hw_mcg_s {
1927 uint32_t :32;
1928 uint32_t :6;
1929 uint32_t next_gid_indx :26;
1930 uint32_t :32;
1931 uint32_t :32;
1932 uint64_t mgid_h;
1933 uint64_t mgid_l;
1935 #else
1936 struct tavor_hw_mcg_s {
1937 uint32_t next_gid_indx :26;
1938 uint32_t :6;
1939 uint32_t :32;
1940 uint32_t :32;
1941 uint32_t :32;
1942 uint64_t mgid_h;
1943 uint64_t mgid_l;
1945 #endif
1947 /* Multicast Group Member - QP List entries */
1948 #ifdef _LITTLE_ENDIAN
1949 struct tavor_hw_mcg_qp_list_s {
1950 uint32_t qpn :24;
1951 uint32_t :7;
1952 uint32_t q :1;
1954 #else
1955 struct tavor_hw_mcg_qp_list_s {
1956 uint32_t q :1;
1957 uint32_t :7;
1958 uint32_t qpn :24;
1960 #endif
1961 #define TAVOR_MCG_QPN_INVALID 0x0
1962 #define TAVOR_MCG_QPN_VALID 0x1
1965 * Structure for getting the peformance counters from the HCA
1968 #ifdef _LITTLE_ENDIAN
1969 struct tavor_hw_sm_perfcntr_s {
1970 uint32_t linkdown :8;
1971 uint32_t linkerrrec :8;
1972 uint32_t symerr :16;
1974 uint32_t cntrsel :16;
1975 uint32_t portsel :8;
1976 uint32_t :8;
1978 uint32_t portxmdiscard :16;
1979 uint32_t portrcvswrelay :16;
1981 uint32_t portrcvrem :16;
1982 uint32_t portrcv :16;
1984 uint32_t vl15drop :16;
1985 uint32_t :16;
1987 uint32_t xsbuffovrun :4;
1988 uint32_t locallinkint :4;
1989 uint32_t :8;
1990 uint32_t portrcconstr :8;
1991 uint32_t portxmconstr :8;
1993 uint32_t portrcdata;
1995 uint32_t portxmdata;
1997 uint32_t portrcpkts;
1999 uint32_t portxmpkts;
2001 uint32_t reserved;
2003 uint32_t portxmwait;
2005 #else /* BIG ENDIAN */
2006 struct tavor_hw_sm_perfcntr_s {
2007 uint32_t :8;
2008 uint32_t portsel :8;
2009 uint32_t cntrsel :16;
2011 uint32_t symerr :16;
2012 uint32_t linkerrrec :8;
2013 uint32_t linkdown :8;
2015 uint32_t portrcv :16;
2016 uint32_t portrcvrem :16;
2018 uint32_t portrcvswrelay :16;
2019 uint32_t portxmdiscard :16;
2021 uint32_t portxmconstr :8;
2022 uint32_t portrcconstr :8;
2023 uint32_t :8;
2024 uint32_t locallinkint :4;
2025 uint32_t xsbuffovrun :4;
2027 uint32_t :16;
2028 uint32_t vl15drop :16;
2030 uint32_t portxmdata;
2032 uint32_t portrcdata;
2034 uint32_t portxmpkts;
2036 uint32_t portrcpkts;
2038 uint32_t portxmwait;
2040 uint32_t reserved;
2042 #endif
2046 * Tavor User Access Region (UAR)
2047 * Tavor doorbells are each rung by writing to the doorbell registers that
2048 * form a User Access Region (UAR). A doorbell is a write-only hardware
2049 * register which enables passing information from software to hardware
2050 * with minimum software latency. A write operation from the host software
2051 * to these doorbell registers passes information about the HCA resources
2052 * and initiates processing of the doorbell data. There are 6 types of
2053 * doorbells in Tavor.
2055 * "Send Doorbell" for synchronizing the attachment of a WQE (or a chain
2056 * of WQEs) to the send queue.
2057 * "RD Send Doorbell" (Same as above, except for RD QPs) is not supported.
2058 * "Receive Doorbell" for synchronizing the attachment of a WQE (or a chain
2059 * of WQEs) to the receive queue.
2060 * "CQ Doorbell" for updating the CQ consumer index and requesting
2061 * completion notifications.
2062 * "EQ Doorbell" for updating the EQ consumer index, arming interrupt
2063 * triggering, and disarming CQ notification requests.
2064 * "InfiniBlast" (which would have enabled access to the "InfiniBlast
2065 * buffer") is not supported.
2067 * Note: The tavor_hw_uar_t below is the container for all of the various
2068 * doorbell types. Below we first define several structures which make up
2069 * the contents of those doorbell types.
2071 * Note also: The following structures are not #define'd with both little-
2072 * endian and big-endian definitions. This is because each doorbell type
2073 * is not directly accessed except through a single ddi_put64() operation
2074 * (see tavor_qp_send_doorbell, tavor_qp_recv_doorbell, tavor_cq_doorbell,
2075 * or tavor_eq_doorbell)
2077 typedef struct tavor_hw_uar_send_s {
2078 uint32_t nda :26;
2079 uint32_t fence :1;
2080 uint32_t nopcode :5;
2081 uint32_t qpn :24;
2082 uint32_t :2;
2083 uint32_t nds :6;
2084 } tavor_hw_uar_send_t;
2085 #define TAVOR_QPSNDDB_NDA_MASK 0xFFFFFFC0
2086 #define TAVOR_QPSNDDB_NDA_SHIFT 0x20
2087 #define TAVOR_QPSNDDB_F_SHIFT 0x25
2088 #define TAVOR_QPSNDDB_NOPCODE_SHIFT 0x20
2089 #define TAVOR_QPSNDDB_QPN_SHIFT 0x8
2091 typedef struct tavor_hw_uar_recv_s {
2092 uint32_t nda :26;
2093 uint32_t nds :6;
2094 uint32_t qpn :24;
2095 uint32_t credits :8;
2096 } tavor_hw_uar_recv_t;
2097 #define TAVOR_QPRCVDB_NDA_MASK 0xFFFFFFC0
2098 #define TAVOR_QPRCVDB_NDA_SHIFT 0x20
2099 #define TAVOR_QPRCVDB_NDS_SHIFT 0x20
2100 #define TAVOR_QPRCVDB_QPN_SHIFT 0x8
2101 /* Max descriptors per Tavor doorbell */
2102 #define TAVOR_QP_MAXDESC_PER_DB 256
2104 typedef struct tavor_hw_uar_cq_s {
2105 uint32_t cmd :8;
2106 uint32_t cqn :24;
2107 uint32_t param;
2108 } tavor_hw_uar_cq_t;
2109 #define TAVOR_CQDB_CMD_SHIFT 0x38
2110 #define TAVOR_CQDB_CQN_SHIFT 0x20
2112 #define TAVOR_CQDB_INCR_CONSINDX 0x01
2113 #define TAVOR_CQDB_NOTIFY_CQ 0x02
2114 #define TAVOR_CQDB_NOTIFY_CQ_SOLICIT 0x03
2115 #define TAVOR_CQDB_SET_CONSINDX 0x04
2116 /* Default value for use in NOTIFY_CQ doorbell */
2117 #define TAVOR_CQDB_DEFAULT_PARAM 0xFFFFFFFF
2119 typedef struct tavor_hw_uar_eq_s {
2120 uint32_t cmd :8;
2121 uint32_t :18;
2122 uint32_t eqn :6;
2123 uint32_t param;
2124 } tavor_hw_uar_eq_t;
2125 #define TAVOR_EQDB_CMD_SHIFT 0x38
2126 #define TAVOR_EQDB_EQN_SHIFT 0x20
2128 #define TAVOR_EQDB_INCR_CONSINDX 0x01
2129 #define TAVOR_EQDB_REARM_EQ 0x02
2130 #define TAVOR_EQDB_DISARM_CQ 0x03
2131 #define TAVOR_EQDB_SET_CONSINDX 0x04
2132 #define TAVOR_EQDB_SET_ALWAYSARMED 0x05
2134 struct tavor_hw_uar_s {
2135 uint32_t rsrv0[4]; /* "RD Send" unsupported */
2136 tavor_hw_uar_send_t send;
2137 tavor_hw_uar_recv_t recv;
2138 tavor_hw_uar_cq_t cq;
2139 tavor_hw_uar_eq_t eq;
2140 uint32_t rsrv1[244];
2141 uint32_t iblast[256]; /* "InfiniBlast" unsupported */
2146 * Tavor Send Work Queue Element (WQE)
2147 * A Tavor Send WQE is built of the following segments, each of which is a
2148 * multiple of 16 bytes. Note: Each individual WQE may contain only a
2149 * subset of these segments described below (according to the operation type
2150 * and transport type of the QP).
2152 * The first 16 bytes of ever WQE are formed from the "Next/Ctrl" segment.
2153 * This segment contains the address of the next WQE to be executed and the
2154 * information required in order to allocate the resources to execute the
2155 * next WQE. The "Ctrl" part of this segment contains the control
2156 * information required to execute the WQE, including the opcode and other
2157 * control information.
2158 * The "Datagram" segment contains address information required in order to
2159 * form a UD message.
2160 * The "Bind" segment contains the parameters required for a Bind Memory
2161 * Window operation.
2162 * The "Remote Address" segment is present only in RDMA or Atomic WQEs and
2163 * specifies remote virtual addresses and RKey, respectively. Length of
2164 * the remote access is calculated from the scatter/gather list (for
2165 * RDMA-write/RDMA-read) or set to eight (for Atomic).
2166 * The "Atomic" segment is present only in Atomic WQEs and specifies
2167 * Swap/Add and Compare data.
2169 * Note: The following structures are not #define'd with both little-endian
2170 * and big-endian definitions. This is because their individual fields are
2171 * not directly accessed except through macros defined below.
2173 struct tavor_hw_snd_wqe_nextctrl_s {
2174 uint32_t next_wqe_addr :26;
2175 uint32_t :1;
2176 uint32_t nopcode :5;
2177 uint32_t next_eec :24;
2178 uint32_t dbd :1;
2179 uint32_t fence :1;
2180 uint32_t nds :6;
2182 uint32_t :28;
2183 uint32_t c :1;
2184 uint32_t e :1;
2185 uint32_t s :1;
2186 uint32_t i :1;
2187 uint32_t immediate :32;
2189 #define TAVOR_WQE_NDA_MASK 0x00000000FFFFFFC0ull
2190 #define TAVOR_WQE_NDS_MASK 0x3F
2191 #define TAVOR_WQE_DBD_MASK 0x80
2193 #define TAVOR_WQE_SEND_FENCE_MASK 0x40
2194 #define TAVOR_WQE_SEND_NOPCODE_RDMAW 0x8
2195 #define TAVOR_WQE_SEND_NOPCODE_RDMAWI 0x9
2196 #define TAVOR_WQE_SEND_NOPCODE_SEND 0xA
2197 #define TAVOR_WQE_SEND_NOPCODE_SENDI 0xB
2198 #define TAVOR_WQE_SEND_NOPCODE_RDMAR 0x10
2199 #define TAVOR_WQE_SEND_NOPCODE_ATMCS 0x11
2200 #define TAVOR_WQE_SEND_NOPCODE_ATMFA 0x12
2201 #define TAVOR_WQE_SEND_NOPCODE_BIND 0x18
2203 #define TAVOR_WQE_SEND_SIGNALED_MASK 0x0000000800000000ull
2204 #define TAVOR_WQE_SEND_SOLICIT_MASK 0x0000000200000000ull
2205 #define TAVOR_WQE_SEND_IMMEDIATE_MASK 0x0000000100000000ull
2207 struct tavor_hw_snd_wqe_ud_s {
2208 uint32_t :32;
2209 uint32_t lkey :32;
2210 uint32_t av_addr_h :32;
2211 uint32_t av_addr_l :27;
2212 uint32_t :5;
2213 uint32_t rsrv0[4];
2214 uint32_t :8;
2215 uint32_t dest_qp :24;
2216 uint32_t qkey :32;
2217 uint32_t :32;
2218 uint32_t :32;
2220 #define TAVOR_WQE_SENDHDR_UD_AV_MASK 0xFFFFFFFFFFFFFFE0ull
2221 #define TAVOR_WQE_SENDHDR_UD_DQPN_MASK 0xFFFFFF
2223 struct tavor_hw_snd_wqe_bind_s {
2224 uint32_t ae :1;
2225 uint32_t rw :1;
2226 uint32_t rr :1;
2227 uint32_t :29;
2228 uint32_t :32;
2229 uint32_t new_rkey;
2230 uint32_t reg_lkey;
2231 uint64_t addr;
2232 uint64_t len;
2234 #define TAVOR_WQE_SENDHDR_BIND_ATOM 0x8000000000000000ull
2235 #define TAVOR_WQE_SENDHDR_BIND_WR 0x4000000000000000ull
2236 #define TAVOR_WQE_SENDHDR_BIND_RD 0x2000000000000000ull
2238 struct tavor_hw_snd_wqe_remaddr_s {
2239 uint64_t vaddr;
2240 uint32_t rkey;
2241 uint32_t :32;
2244 struct tavor_hw_snd_wqe_atomic_s {
2245 uint64_t swap_add;
2246 uint64_t compare;
2251 * Tavor "MLX transport" Work Queue Element (WQE)
2252 * The format of the MLX WQE is similar to that of the Send WQE (above)
2253 * with the following exceptions. MLX WQEs are used for sending MADs on
2254 * special QPs 0 and 1. Everything following the "Next/Ctrl" header
2255 * (defined below) consists of scatter-gather list entries. The contents
2256 * of these SGLs (also defined below) will be put on the wire exactly as
2257 * they appear in the buffers. In addition, the VCRC and the ICRC of each
2258 * sent packet can be modified by changing values in the following header
2259 * or in the payload of the packet itself.
2261 struct tavor_hw_mlx_wqe_nextctrl_s {
2262 uint32_t next_wqe_addr :26;
2263 uint32_t :1;
2264 uint32_t nopcode :5;
2265 uint32_t :24;
2266 uint32_t dbd :1;
2267 uint32_t :1;
2268 uint32_t nds :6;
2270 uint32_t :14;
2271 uint32_t vl15 :1;
2272 uint32_t slr :1;
2273 uint32_t :1;
2274 uint32_t max_srate :3;
2275 uint32_t sl :4;
2276 uint32_t :4;
2277 uint32_t c :1;
2278 uint32_t e :1;
2279 uint32_t :2;
2280 uint32_t rlid :16;
2281 uint32_t vcrc :16;
2283 #define TAVOR_WQE_MLXHDR_VL15_MASK 0x0002000000000000ull
2284 #define TAVOR_WQE_MLXHDR_SLR_MASK 0x0001000000000000ull
2285 #define TAVOR_WQE_MLXHDR_SRATE_SHIFT 44
2286 #define TAVOR_WQE_MLXHDR_SL_SHIFT 40
2287 #define TAVOR_WQE_MLXHDR_SIGNALED_MASK 0x0000000800000000ull
2288 #define TAVOR_WQE_MLXHDR_RLID_SHIFT 16
2291 * Tavor Receive Work Queue Element (WQE)
2292 * Like the Send WQE, the Receive WQE is built of 16-byte segments. The
2293 * segment is the "Next/Ctrl" segment (defined below). It is followed by
2294 * some number of scatter list entries for the incoming message.
2296 * The format of the scatter-gather list entries is also shown below. For
2297 * Receive WQEs the "inline_data" field must be cleared (i.e. data segments
2298 * cannot contain inline data).
2300 struct tavor_hw_rcv_wqe_nextctrl_s {
2301 uint32_t next_wqe_addr :26;
2302 uint32_t :5;
2303 uint32_t one :1;
2304 uint32_t :24;
2305 uint32_t dbd :1;
2306 uint32_t :1;
2307 uint32_t nds :6;
2309 uint32_t :28;
2310 uint32_t c :1;
2311 uint32_t e :1;
2312 uint32_t :2;
2313 uint32_t :32;
2317 * This bit must be set in the next/ctrl field of all Receive WQEs
2318 * as a workaround to a Tavor hardware erratum related to having
2319 * the first 32-bits in the WQE set to zero.
2321 #define TAVOR_RCV_WQE_NDA0_WA_MASK 0x0000000100000000ull
2323 struct tavor_hw_wqe_sgl_s {
2324 uint32_t inline_data :1;
2325 uint32_t byte_cnt :31;
2326 uint32_t lkey;
2327 uint64_t addr;
2329 #define TAVOR_WQE_SGL_BYTE_CNT_MASK 0x7FFFFFFF
2330 #define TAVOR_WQE_SGL_INLINE_MASK 0x80000000
2333 * The following defines are used when building descriptors for special QP
2334 * work requests (i.e. MLX transport WQEs). Note: Because Tavor MLX transport
2335 * requires the driver to build actual IB packet headers, we use these defines
2336 * for the most common fields in those headers.
2338 #define TAVOR_MLX_VL15_LVER 0xF0000000
2339 #define TAVOR_MLX_VL0_LVER 0x00000000
2340 #define TAVOR_MLX_IPVER_TC_FLOW 0x60000000
2341 #define TAVOR_MLX_TC_SHIFT 20
2342 #define TAVOR_MLX_DEF_PKEY 0xFFFF
2343 #define TAVOR_MLX_GSI_QKEY 0x80010000
2344 #define TAVOR_MLX_UDSEND_OPCODE 0x64000000
2345 #define TAVOR_MLX_DQPN_MASK 0xFFFFFF
2348 * The following macros are used for building each of the individual
2349 * segments that can make up a Tavor WQE. Note: We try not to use the
2350 * structures (with their associated bitfields) here, instead opting to
2351 * build and put 64-bit or 32-bit chunks to the WQEs as appropriate,
2352 * primarily because using the bitfields appears to force more read-modify-
2353 * write operations.
2355 * TAVOR_WQE_BUILD_UD - Builds Unreliable Datagram Segment
2357 * TAVOR_WQE_BUILD_REMADDR - Builds Remote Address Segment using
2358 * RDMA info from the work request
2359 * TAVOR_WQE_BUILD_RC_ATOMIC_REMADDR - Builds Remote Address Segment
2360 * for RC Atomic work requests
2361 * TAVOR_WQE_BUILD_ATOMIC - Builds Atomic Segment using atomic
2362 * info from the work request
2363 * TAVOR_WQE_BUILD_BIND - Builds the Bind Memory Window
2364 * Segment using bind info from the
2365 * work request
2366 * TAVOR_WQE_BUILD_DATA_SEG - Builds the individual Data Segments
2367 * for Send, Receive, and MLX WQEs
2368 * TAVOR_WQE_BUILD_INLINE - Builds an "inline" Data Segment
2369 * (primarily for MLX transport)
2370 * TAVOR_WQE_BUILD_INLINE_ICRC - Also builds an "inline" Data Segment
2371 * (but used primarily in the ICRC
2372 * portion of MLX transport WQEs)
2373 * TAVOR_WQE_LINKNEXT - Links the current WQE to the
2374 * previous one
2375 * TAVOR_WQE_LINKFIRST - Links the first WQE on the current
2376 * chain to the previous WQE
2377 * TAVOR_WQE_BUILD_MLX_LRH - Builds the inline LRH header for
2378 * MLX transport MADs
2379 * TAVOR_WQE_BUILD_MLX_GRH - Builds the inline GRH header for
2380 * MLX transport MADs
2381 * TAVOR_WQE_BUILD_MLX_BTH - Builds the inline BTH header for
2382 * MLX transport MADs
2383 * TAVOR_WQE_BUILD_MLX_DETH - Builds the inline DETH header for
2384 * MLX transport MADs
2386 #define TAVOR_WQE_BUILD_UD(qp, ud, ah, wr) \
2388 uint64_t *tmp; \
2390 tmp = (uint64_t *)(ud); \
2391 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &tmp[0], \
2392 (uint64_t)(ah)->ah_mrhdl->mr_lkey); \
2393 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &tmp[1], \
2394 (ah)->ah_mrhdl->mr_bindinfo.bi_addr & \
2395 TAVOR_WQE_SENDHDR_UD_AV_MASK); \
2396 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &tmp[2], 0x0); \
2397 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &tmp[3], 0x0); \
2398 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &tmp[4], \
2399 (((uint64_t)((wr)->wr.ud.udwr_dest->ud_dst_qpn & \
2400 TAVOR_WQE_SENDHDR_UD_DQPN_MASK) << 32) | \
2401 (wr)->wr.ud.udwr_dest->ud_qkey)); \
2404 #define TAVOR_WQE_BUILD_REMADDR(qp, ra, wr_rdma) \
2406 uint64_t *tmp; \
2408 tmp = (uint64_t *)(ra); \
2409 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &tmp[0], \
2410 (wr_rdma)->rdma_raddr); \
2411 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &tmp[1], \
2412 (uint64_t)(wr_rdma)->rdma_rkey << 32); \
2415 #define TAVOR_WQE_BUILD_RC_ATOMIC_REMADDR(qp, rc, wr) \
2417 uint64_t *tmp; \
2419 tmp = (uint64_t *)(rc); \
2420 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &tmp[0], \
2421 (wr)->wr.rc.rcwr.atomic->atom_raddr); \
2422 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &tmp[1], \
2423 (uint64_t)(wr)->wr.rc.rcwr.atomic->atom_rkey << 32); \
2426 #define TAVOR_WQE_BUILD_ATOMIC(qp, at, wr_atom) \
2428 uint64_t *tmp; \
2430 tmp = (uint64_t *)(at); \
2431 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &tmp[0], \
2432 (wr_atom)->atom_arg2); \
2433 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &tmp[1], \
2434 (wr_atom)->atom_arg1); \
2437 #define TAVOR_WQE_BUILD_BIND(qp, bn, wr_bind) \
2439 uint64_t *tmp; \
2440 uint64_t bn0_tmp; \
2441 ibt_bind_flags_t bind_flags; \
2443 tmp = (uint64_t *)(bn); \
2444 bind_flags = (wr_bind)->bind_flags; \
2445 bn0_tmp = (bind_flags & IBT_WR_BIND_ATOMIC) ? \
2446 TAVOR_WQE_SENDHDR_BIND_ATOM : 0; \
2447 bn0_tmp |= (bind_flags & IBT_WR_BIND_WRITE) ? \
2448 TAVOR_WQE_SENDHDR_BIND_WR : 0; \
2449 bn0_tmp |= (bind_flags & IBT_WR_BIND_READ) ? \
2450 TAVOR_WQE_SENDHDR_BIND_RD : 0; \
2451 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &tmp[0], bn0_tmp); \
2452 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &tmp[1], \
2453 (((uint64_t)(wr_bind)->bind_rkey_out << 32) | \
2454 (wr_bind)->bind_lkey)); \
2455 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &tmp[2], \
2456 (wr_bind)->bind_va); \
2457 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &tmp[3], \
2458 (wr_bind)->bind_len); \
2461 #define TAVOR_WQE_BUILD_DATA_SEG(qp, ds, sgl) \
2463 uint64_t *tmp; \
2465 tmp = (uint64_t *)(ds); \
2466 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &tmp[0], \
2467 (((uint64_t)((sgl)->ds_len & \
2468 TAVOR_WQE_SGL_BYTE_CNT_MASK) << 32) | (sgl)->ds_key)); \
2469 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &tmp[1], (sgl)->ds_va); \
2472 #define TAVOR_WQE_BUILD_DATA_SEG_SRQ(srq, ds, sgl) \
2474 uint64_t *tmp; \
2476 tmp = (uint64_t *)(ds); \
2477 ddi_put64((srq)->srq_wqinfo.qa_acchdl, &tmp[0], \
2478 (((uint64_t)((sgl)->ds_len & \
2479 TAVOR_WQE_SGL_BYTE_CNT_MASK) << 32) | (sgl)->ds_key)); \
2480 ddi_put64((srq)->srq_wqinfo.qa_acchdl, &tmp[1], (sgl)->ds_va); \
2483 #define TAVOR_WQE_BUILD_INLINE(qp, ds, sz) \
2485 uint32_t *tmp; \
2486 uint32_t inline_tmp; \
2488 tmp = (uint32_t *)(ds); \
2489 inline_tmp = TAVOR_WQE_SGL_INLINE_MASK | sz; \
2490 ddi_put32((qp)->qp_wqinfo.qa_acchdl, &tmp[0], inline_tmp); \
2493 #define TAVOR_WQE_BUILD_INLINE_ICRC(qp, ds, sz, icrc) \
2495 uint32_t *tmp; \
2496 uint32_t inline_tmp; \
2498 tmp = (uint32_t *)(ds); \
2499 inline_tmp = TAVOR_WQE_SGL_INLINE_MASK | sz; \
2500 ddi_put32((qp)->qp_wqinfo.qa_acchdl, &tmp[0], inline_tmp); \
2501 ddi_put32((qp)->qp_wqinfo.qa_acchdl, &tmp[1], icrc); \
2504 #define TAVOR_WQE_LINKNEXT(qp, prev, ctrl, next) \
2506 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &((uint64_t *)(prev))[1], \
2507 (ctrl)); \
2508 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &((uint64_t *)(prev))[0], \
2509 (next)); \
2512 #define TAVOR_WQE_LINKNEXT_SRQ(srq, prev, ctrl, next) \
2514 ddi_put64((srq)->srq_wqinfo.qa_acchdl, &((uint64_t *)(prev))[1],\
2515 (ctrl)); \
2516 ddi_put64((srq)->srq_wqinfo.qa_acchdl, &((uint64_t *)(prev))[0],\
2517 (next)); \
2520 #define TAVOR_WQE_LINKFIRST(qp, prev, next) \
2522 ddi_put64((qp)->qp_wqinfo.qa_acchdl, &((uint64_t *)(prev))[0], \
2523 (next)); \
2526 #define TAVOR_WQE_BUILD_MLX_LRH(lrh, qp, udav, pktlen) \
2528 uint32_t *tmp; \
2529 uint32_t lrh_tmp; \
2531 tmp = (uint32_t *)(lrh); \
2533 if ((qp)->qp_is_special == TAVOR_QP_SMI) { \
2534 lrh_tmp = TAVOR_MLX_VL15_LVER; \
2535 } else { \
2536 lrh_tmp = TAVOR_MLX_VL0_LVER | ((udav).sl << 20); \
2538 if ((udav).grh) { \
2539 lrh_tmp |= (IB_LRH_NEXT_HDR_GRH << 16); \
2540 } else { \
2541 lrh_tmp |= (IB_LRH_NEXT_HDR_BTH << 16); \
2543 lrh_tmp |= (udav).rlid; \
2544 ddi_put32((qp)->qp_wqinfo.qa_acchdl, &tmp[0], lrh_tmp); \
2546 lrh_tmp = (pktlen) << 16; \
2547 if ((udav).rlid == IB_LID_PERMISSIVE) { \
2548 lrh_tmp |= IB_LID_PERMISSIVE; \
2549 } else { \
2550 lrh_tmp |= (udav).ml_path; \
2552 ddi_put32((qp)->qp_wqinfo.qa_acchdl, &tmp[1], lrh_tmp); \
2556 * Note: The GRH payload length, calculated below, is the overall packet
2557 * length (in bytes) minus LRH header and GRH headers.
2559 * Also note: Filling in the GIDs in the way we do below is helpful because
2560 * it avoids potential alignment restrictions and/or conflicts.
2562 #define TAVOR_WQE_BUILD_MLX_GRH(state, grh, qp, udav, pktlen) \
2564 uint32_t *tmp; \
2565 uint32_t grh_tmp; \
2566 ib_gid_t sgid; \
2568 tmp = (uint32_t *)(grh); \
2570 grh_tmp = TAVOR_MLX_IPVER_TC_FLOW; \
2571 grh_tmp |= (udav).tclass << TAVOR_MLX_TC_SHIFT; \
2572 grh_tmp |= (udav).flow_label; \
2573 ddi_put32((qp)->qp_wqinfo.qa_acchdl, &tmp[0], grh_tmp); \
2575 grh_tmp = (((pktlen) << 2) - (sizeof (ib_lrh_hdr_t) + \
2576 sizeof (ib_grh_t))) << 16; \
2577 grh_tmp |= (IB_GRH_NEXT_HDR_BTH << 8); \
2578 grh_tmp |= (udav).hop_limit; \
2579 ddi_put32((qp)->qp_wqinfo.qa_acchdl, &tmp[1], grh_tmp); \
2581 TAVOR_SGID_FROM_INDX_GET((state), (qp)->qp_portnum, \
2582 (udav).mgid_index, &sgid); \
2583 bcopy(&sgid, &tmp[2], sizeof (ib_gid_t)); \
2584 bcopy(&(udav).rgid_h, &tmp[6], sizeof (ib_gid_t)); \
2587 #define TAVOR_WQE_BUILD_MLX_BTH(state, bth, qp, wr) \
2589 uint32_t *tmp; \
2590 uint32_t bth_tmp; \
2592 tmp = (uint32_t *)(bth); \
2594 bth_tmp = TAVOR_MLX_UDSEND_OPCODE; \
2595 if ((wr)->wr_flags & IBT_WR_SEND_SOLICIT) { \
2596 bth_tmp |= (IB_BTH_SOLICITED_EVENT_MASK << 16); \
2598 if (qp->qp_is_special == TAVOR_QP_SMI) { \
2599 bth_tmp |= TAVOR_MLX_DEF_PKEY; \
2600 } else { \
2601 bth_tmp |= TAVOR_PKEY_FROM_INDX_GET((state), \
2602 (qp)->qp_portnum, (qp)->qp_pkeyindx); \
2604 ddi_put32((qp)->qp_wqinfo.qa_acchdl, &tmp[0], bth_tmp); \
2605 ddi_put32((qp)->qp_wqinfo.qa_acchdl, &tmp[1], \
2606 (wr)->wr.ud.udwr_dest->ud_dst_qpn & \
2607 TAVOR_MLX_DQPN_MASK); \
2608 ddi_put32((qp)->qp_wqinfo.qa_acchdl, &tmp[2], 0x0); \
2611 #define TAVOR_WQE_BUILD_MLX_DETH(deth, qp) \
2613 uint32_t *tmp; \
2615 tmp = (uint32_t *)(deth); \
2617 if ((qp)->qp_is_special == TAVOR_QP_SMI) { \
2618 ddi_put32((qp)->qp_wqinfo.qa_acchdl, &tmp[0], 0x0); \
2619 ddi_put32((qp)->qp_wqinfo.qa_acchdl, &tmp[1], 0x0); \
2620 } else { \
2621 ddi_put32((qp)->qp_wqinfo.qa_acchdl, &tmp[0], \
2622 TAVOR_MLX_GSI_QKEY); \
2623 ddi_put32((qp)->qp_wqinfo.qa_acchdl, &tmp[1], 0x1); \
2629 * Undocumented:
2630 * The following registers (and the macros to access them) are not defined
2631 * in the Tavor PRM. But we have high confidence that these offsets are
2632 * unlikely to change in the lifetime of the Tavor hardware.
2634 #define TAVOR_HW_PORTINFO_LMC_OFFSET 0x10020
2635 #define TAVOR_HW_PORTINFO_BASELID_OFFSET 0x10010
2636 #define TAVOR_HW_PORTINFO_MASTERSMLID_OFFSET 0x10010
2637 #define TAVOR_HW_PORTINFO_LINKWIDTH_OFFSET 0x1001C
2638 #define TAVOR_HW_PORT_SIZE 0x800
2640 #define TAVOR_HW_PMEG_PORTXMITDATA_OFFSET 0x10120
2641 #define TAVOR_HW_PMEG_PORTRECVDATA_OFFSET 0x10124
2642 #define TAVOR_HW_PMEG_PORTXMITPKTS_OFFSET 0x10128
2643 #define TAVOR_HW_PMEG_PORTRECVPKTS_OFFSET 0x1012C
2644 #define TAVOR_HW_PMEG_PORTRECVERR_OFFSET 0x10130
2645 #define TAVOR_HW_PMEG_PORTXMITDISCARD_OFFSET 0x10134
2646 #define TAVOR_HW_PMEG_VL15DROPPED_OFFSET 0x10138
2647 #define TAVOR_HW_PMEG_PORTXMITWAIT_OFFSET 0x1013C
2648 #define TAVOR_HW_PMEG_PORTRECVREMPHYSERR_OFFSET 0x10144
2649 #define TAVOR_HW_PMEG_PORTXMITCONSTERR_OFFSET 0x10148
2650 #define TAVOR_HW_PMEG_PORTRECVCONSTERR_OFFSET 0x1014C
2651 #define TAVOR_HW_PMEG_SYMBOLERRCNT_OFFSET 0x10150
2652 #define TAVOR_HW_PMEG_LINKERRRECOVERCNT_OFFSET 0x10154
2653 #define TAVOR_HW_PMEG_LINKDOWNEDCNT_OFFSET 0x10154
2654 #define TAVOR_HW_PMEG_EXCESSBUFOVERRUN_OFFSET 0x10164
2655 #define TAVOR_HW_PMEG_LOCALLINKINTERR_OFFSET 0x10164
2657 #define TAVOR_HW_GUIDTABLE_OFFSET 0x4C800
2658 #define TAVOR_HW_GUIDTABLE_PORT_SIZE 0x200
2659 #define TAVOR_HW_GUIDTABLE_GID_SIZE 0x10
2660 #define TAVOR_HW_GUIDTABLE_GIDPREFIX_SIZE 0x8
2662 #define TAVOR_HW_PKEYTABLE_OFFSET 0x4D800
2663 #define TAVOR_HW_PKEYTABLE_PORT_SIZE 0x100
2664 #define TAVOR_HW_PKEYTABLE_PKEY_SIZE 0x4
2666 #define TAVOR_PORT_LMC_GET(state, port) \
2667 ((ddi_get32((state)->ts_reg_cmdhdl, \
2668 (uint32_t *)((uintptr_t)(state)->ts_reg_cmd_baseaddr + \
2669 TAVOR_HW_PORTINFO_LMC_OFFSET + \
2670 (TAVOR_HW_PORT_SIZE * (port)))) >> 8) & 0x7);
2672 #define TAVOR_PORT_BASELID_GET(state, port) \
2673 (ddi_get32((state)->ts_reg_cmdhdl, \
2674 (uint32_t *)((uintptr_t)(state)->ts_reg_cmd_baseaddr + \
2675 TAVOR_HW_PORTINFO_BASELID_OFFSET + \
2676 (TAVOR_HW_PORT_SIZE * (port)))) >> 16);
2678 #define TAVOR_PORT_MASTERSMLID_GET(state, port) \
2679 (ddi_get32((state)->ts_reg_cmdhdl, \
2680 (uint32_t *)((uintptr_t)(state)->ts_reg_cmd_baseaddr + \
2681 TAVOR_HW_PORTINFO_MASTERSMLID_OFFSET + \
2682 (TAVOR_HW_PORT_SIZE * (port)))) & 0xFFFF);
2684 #define TAVOR_PORT_LINKWIDTH_ACTIVE_GET(state, port) \
2685 (ddi_get32((state)->ts_reg_cmdhdl, \
2686 (uint32_t *)((uintptr_t)(state)->ts_reg_cmd_baseaddr + \
2687 TAVOR_HW_PORTINFO_LINKWIDTH_OFFSET + \
2688 (TAVOR_HW_PORT_SIZE * (port)))) & 0xF);
2690 #define TAVOR_SGID_FROM_INDX_GET(state, port, sgid_ix, sgid) \
2691 (sgid)->gid_prefix = ddi_get64((state)->ts_reg_cmdhdl, \
2692 (uint64_t *)((uintptr_t)(state)->ts_reg_cmd_baseaddr + \
2693 TAVOR_HW_GUIDTABLE_OFFSET + \
2694 ((port) * TAVOR_HW_GUIDTABLE_PORT_SIZE) + \
2695 ((sgid_ix) * TAVOR_HW_GUIDTABLE_GID_SIZE))); \
2696 (sgid)->gid_guid = ddi_get64((state)->ts_reg_cmdhdl, \
2697 (uint64_t *)((uintptr_t)(state)->ts_reg_cmd_baseaddr + \
2698 TAVOR_HW_GUIDTABLE_OFFSET + \
2699 ((port) * TAVOR_HW_GUIDTABLE_PORT_SIZE) + \
2700 ((sgid_ix) * TAVOR_HW_GUIDTABLE_GID_SIZE) + \
2701 TAVOR_HW_GUIDTABLE_GIDPREFIX_SIZE));
2703 #define TAVOR_PKEY_FROM_INDX_GET(state, port, pkey_ix) \
2704 (ddi_get32((state)->ts_reg_cmdhdl, \
2705 (uint32_t *)((uintptr_t)(state)->ts_reg_cmd_baseaddr + \
2706 TAVOR_HW_PKEYTABLE_OFFSET + \
2707 ((port) * TAVOR_HW_PKEYTABLE_PORT_SIZE) + \
2708 ((pkey_ix) * TAVOR_HW_PKEYTABLE_PKEY_SIZE))) & 0xFFFF)
2712 * Flash interface:
2713 * Below we have PCI config space space offsets for flash interface
2714 * access, offsets within Tavor CR space for accessing flash-specific
2715 * information or settings, masks used for flash settings, and
2716 * timeout values for flash operations.
2718 #define TAVOR_HW_FLASH_CFG_HWREV 8
2719 #define TAVOR_HW_FLASH_CFG_ADDR 88
2720 #define TAVOR_HW_FLASH_CFG_DATA 92
2722 #define TAVOR_HW_FLASH_RESET_AMD 0xF0
2723 #define TAVOR_HW_FLASH_RESET_INTEL 0xFF
2724 #define TAVOR_HW_FLASH_CPUMODE 0xF0150
2725 #define TAVOR_HW_FLASH_ADDR 0xF01A4
2726 #define TAVOR_HW_FLASH_DATA 0xF01A8
2727 #define TAVOR_HW_FLASH_GPIO_SEMA 0xF03FC
2728 #define TAVOR_HW_FLASH_GPIO_DIR 0xF008C
2729 #define TAVOR_HW_FLASH_GPIO_POL 0xF0094
2730 #define TAVOR_HW_FLASH_GPIO_MOD 0xF009C
2731 #define TAVOR_HW_FLASH_GPIO_DAT 0xF0084
2732 #define TAVOR_HW_FLASH_GPIO_DATACLEAR 0xF00D4
2733 #define TAVOR_HW_FLASH_GPIO_DATASET 0xF00DC
2735 #define TAVOR_HW_FLASH_CPU_MASK 0xC0000000
2736 #define TAVOR_HW_FLASH_CPU_SHIFT 30
2737 #define TAVOR_HW_FLASH_ADDR_MASK 0x0007FFFC
2738 #define TAVOR_HW_FLASH_CMD_MASK 0xE0000000
2739 #define TAVOR_HW_FLASH_BANK_MASK 0xFFF80000
2741 #define TAVOR_HW_FLASH_TIMEOUT_WRITE 300
2742 #define TAVOR_HW_FLASH_TIMEOUT_ERASE 1000000
2743 #define TAVOR_HW_FLASH_TIMEOUT_GPIO_SEMA 1000
2744 #define TAVOR_HW_FLASH_TIMEOUT_CONFIG 50
2746 /* Intel Command Set */
2747 #define TAVOR_HW_FLASH_ICS_ERASE 0x20
2748 #define TAVOR_HW_FLASH_ICS_ERROR 0x3E
2749 #define TAVOR_HW_FLASH_ICS_WRITE 0x40
2750 #define TAVOR_HW_FLASH_ICS_STATUS 0x70
2751 #define TAVOR_HW_FLASH_ICS_READY 0x80
2752 #define TAVOR_HW_FLASH_ICS_CONFIRM 0xD0
2753 #define TAVOR_HW_FLASH_ICS_READ 0xFF
2755 #ifdef __cplusplus
2757 #endif
2759 #endif /* _SYS_IB_ADAPTERS_TAVOR_HW_H */