xref: /illumos-gate/usr/src/uts/common/sys/ib/adapters/tavor/tavor_hw.h (revision e9dc6bff6e018821c8c8ac7fe3e3b42e621e93ae)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_SYS_IB_ADAPTERS_TAVOR_HW_H
28 #define	_SYS_IB_ADAPTERS_TAVOR_HW_H
29 
30 /*
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.
36  */
37 
38 #include <sys/types.h>
39 #include <sys/conf.h>
40 #include <sys/ddi.h>
41 #include <sys/sunddi.h>
42 
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46 
47 
48 /*
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).
53  */
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
59 
60 /*
61  * Ownership flags used to define hardware or software ownership for
62  * various Tavor resources
63  */
64 #define	TAVOR_HW_OWNER			0x1
65 #define	TAVOR_SW_OWNER			0x0
66 
67 /*
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.
72  */
73 #define	TAVOR_VA2PA_XLAT_ENABLED	0x1
74 #define	TAVOR_VA2PA_XLAT_DISABLED	0x0
75 
76 /*
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.
87  */
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;
96 };
97 #define	TAVOR_HCR_TOKEN_MASK		0xFFFF0000
98 #define	TAVOR_HCR_TOKEN_SHIFT		16
99 
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
109 
110 
111 /*
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.
117  */
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];
227 };
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];
337 };
338 #endif
339 
340 
341 /*
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).
348  */
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];
367 };
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];
385 };
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
393 
394 
395 /*
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).
403  *
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.
407  */
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
449 
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
455 
456 #define	TAVOR_DIMM_SPD_FROM_DIMM	0x0
457 #define	TAVOR_DIMM_SPD_FROM_NVMEM	0x1
458 
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];
471 };
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];
484 };
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
489 
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
494 
495 
496 /*
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.
503  */
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];
514 };
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];
525 };
526 #endif
527 #define	TAVOR_REV_A0	0xA0
528 #define	TAVOR_REV_A1	0xA1
529 
530 
531 /*
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.
540  *
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".
548  */
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
616 
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
634 
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
665 
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
695 
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
719 
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];
749 };
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];
779 };
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
785 
786 
787 /*
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.
795  */
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];
815 };
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];
835 };
836 #endif
837 
838 /*
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.
845  *
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.
863  */
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];
895 };
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];
927 };
928 #endif
929 #define	TAVOR_MEM_CYCLE_GENERATE	0x1
930 #define	TAVOR_IO_CYCLE_GENERATE		0x0
931 
932 #define	TAVOR_MPT_IS_WINDOW		0x0
933 #define	TAVOR_MPT_IS_REGION		0x1
934 
935 #define	TAVOR_MPT_DEFAULT_VERSION	0x0
936 
937 #define	TAVOR_UNLIMITED_WIN_BIND	0x0
938 
939 #define	TAVOR_PHYSADDR_ENABLED		0x1
940 #define	TAVOR_PHYSADDR_DISABLED		0x0
941 
942 
943 /*
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.
953  */
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;
960 };
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;
967 };
968 #endif
969 #define	TAVOR_MTT_ENTRY_NOTPRESET	0x0
970 #define	TAVOR_MTT_ENTRY_PRESET		0x1
971 
972 
973 /*
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.
980  *
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.
996  */
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];
1022 };
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];
1048 };
1049 #endif
1050 #define	TAVOR_EQ_STATUS_OK		0x0
1051 #define	TAVOR_EQ_STATUS_OVERFLOW	0x9
1052 #define	TAVOR_EQ_STATUS_WRITE_FAILURE	0xA
1053 
1054 #define	TAVOR_EQ_ARMED			0x1
1055 #define	TAVOR_EQ_FIRED			0x2
1056 #define	TAVOR_EQ_ALWAYS_ARMED		0x3
1057 
1058 
1059 /*
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.
1066  *
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).
1082  *
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.
1087  */
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;
1093 
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
1104 
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
1114 
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;
1125 
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;
1135 
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
1148 
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
1173 
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;
1187 
1188 	uint32_t	err_ca		:16;
1189 	uint32_t	err_ra		:16;
1190 } tavor_hw_eqe_ecc_t;
1191 
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;
1210 };
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
1218 
1219 /*
1220  * The following macros are used for extracting (and in some cases filling in)
1221  * information from EQEs
1222  */
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
1241 
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)))
1288 
1289 
1290 /*
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).
1296  *
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.
1310  */
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];
1340 };
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];
1370 };
1371 #endif
1372 #define	TAVOR_CQ_STATUS_OK		0x0
1373 #define	TAVOR_CQ_STATUS_OVERFLOW	0x9
1374 #define	TAVOR_CQ_STATUS_WRITE_FAILURE	0xA
1375 
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
1380 
1381 /*
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.
1385  *
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.
1389  */
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;
1412 };
1413 #define	TAVOR_COMPLETION_RECV		0x0
1414 #define	TAVOR_COMPLETION_SEND		0x1
1415 
1416 #define	TAVOR_CQE_DEFAULT_VERSION	0x0
1417 
1418 /*
1419  * The following macros are used for extracting (and in some cases filling in)
1420  * information from CQEs
1421  */
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
1440 
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)					\
1491 	{								\
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);		\
1497 	    }								\
1498 	}
1499 #else
1500 #define	TAVOR_CQE_OWNER_SET_HW(cq, cqe)					\
1501 	{								\
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);		\
1507 	    }								\
1508 	}
1509 #endif
1510 
1511 /*
1512  * Tavor Shared Receive Queue (SRQ) Context Entry Format
1513  */
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;
1519 
1520 	uint32_t	lkey;
1521 	uint32_t	pd			:24;
1522 	uint32_t				:4;
1523 	uint32_t	state			:4;
1524 
1525 	uint32_t	wqe_cnt			:16;
1526 	uint32_t				:16;
1527 	uint32_t	uar			:24;
1528 	uint32_t				:8;
1529 };
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;
1535 
1536 	uint32_t	state			:4;
1537 	uint32_t				:4;
1538 	uint32_t	pd			:24;
1539 	uint32_t	lkey;
1540 
1541 	uint32_t				:8;
1542 	uint32_t	uar			:24;
1543 	uint32_t				:16;
1544 	uint32_t	wqe_cnt			:16;
1545 };
1546 #endif
1547 
1548 /*
1549  * Tavor MOD_STAT_CFG input mailbox structure
1550  */
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];
1560 };
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];
1570 };
1571 #endif
1572 
1573 /*
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.
1583  */
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;
1605 };
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;
1627 };
1628 #endif
1629 #define	TAVOR_UDAV_MODIFY_MASK0		0xFCFFFFFFFF000000ULL
1630 #define	TAVOR_UDAV_MODIFY_MASK1		0xFFC0F80000000000ULL
1631 
1632 
1633 /*
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.
1638  *
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.
1647  *
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.
1655  */
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;
1678 };
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;
1701 };
1702 #endif
1703 
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];
1785 };
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];
1867 };
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
1877 
1878 #define	TAVOR_QP_RC			0x0
1879 #define	TAVOR_QP_UC			0x1
1880 #define	TAVOR_QP_UD			0x3
1881 #define	TAVOR_QP_MLX			0x7
1882 
1883 #define	TAVOR_QP_PMSTATE_MIGRATED	0x3
1884 #define	TAVOR_QP_PMSTATE_ARMED		0x0
1885 #define	TAVOR_QP_PMSTATE_REARM		0x1
1886 
1887 #define	TAVOR_QP_DESC_EVT_DISABLED	0x0
1888 #define	TAVOR_QP_DESC_EVT_ENABLED	0x1
1889 
1890 #define	TAVOR_QP_FLIGHT_LIM_UNLIMITED	0xF
1891 
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
1896 
1897 #define	TAVOR_QP_SRQ_ENABLED	0x1
1898 #define	TAVOR_QP_SRQ_DISABLED	0x0
1899 
1900 
1901 /*
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).
1915  *
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.
1924  */
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;
1934 };
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;
1944 };
1945 #endif
1946 
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;
1953 };
1954 #else
1955 struct tavor_hw_mcg_qp_list_s {
1956 	uint32_t	q		:1;
1957 	uint32_t			:7;
1958 	uint32_t	qpn		:24;
1959 };
1960 #endif
1961 #define	TAVOR_MCG_QPN_INVALID		0x0
1962 #define	TAVOR_MCG_QPN_VALID		0x1
1963 
1964 /*
1965  * Structure for getting the peformance counters from the HCA
1966  */
1967 
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;
1973 
1974 	uint32_t	cntrsel		:16;
1975 	uint32_t	portsel		:8;
1976 	uint32_t			:8;
1977 
1978 	uint32_t	portxmdiscard	:16;
1979 	uint32_t	portrcvswrelay	:16;
1980 
1981 	uint32_t	portrcvrem	:16;
1982 	uint32_t	portrcv		:16;
1983 
1984 	uint32_t	vl15drop	:16;
1985 	uint32_t			:16;
1986 
1987 	uint32_t	xsbuffovrun	:4;
1988 	uint32_t	locallinkint	:4;
1989 	uint32_t			:8;
1990 	uint32_t	portrcconstr	:8;
1991 	uint32_t	portxmconstr	:8;
1992 
1993 	uint32_t	portrcdata;
1994 
1995 	uint32_t	portxmdata;
1996 
1997 	uint32_t	portrcpkts;
1998 
1999 	uint32_t	portxmpkts;
2000 
2001 	uint32_t	reserved;
2002 
2003 	uint32_t	portxmwait;
2004 };
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;
2010 
2011 	uint32_t	symerr		:16;
2012 	uint32_t	linkerrrec	:8;
2013 	uint32_t	linkdown	:8;
2014 
2015 	uint32_t	portrcv		:16;
2016 	uint32_t	portrcvrem	:16;
2017 
2018 	uint32_t	portrcvswrelay	:16;
2019 	uint32_t	portxmdiscard	:16;
2020 
2021 	uint32_t	portxmconstr	:8;
2022 	uint32_t	portrcconstr	:8;
2023 	uint32_t			:8;
2024 	uint32_t	locallinkint	:4;
2025 	uint32_t	xsbuffovrun	:4;
2026 
2027 	uint32_t			:16;
2028 	uint32_t	vl15drop	:16;
2029 
2030 	uint32_t	portxmdata;
2031 
2032 	uint32_t	portrcdata;
2033 
2034 	uint32_t	portxmpkts;
2035 
2036 	uint32_t	portrcpkts;
2037 
2038 	uint32_t	portxmwait;
2039 
2040 	uint32_t	reserved;
2041 };
2042 #endif
2043 
2044 
2045 /*
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.
2054  *
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.
2066  *
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.
2070  *
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)
2076  */
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
2090 
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
2103 
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
2111 
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
2118 
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
2127 
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
2133 
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 */
2142 };
2143 
2144 
2145 /*
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).
2151  *
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.
2168  *
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.
2172  */
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;
2181 
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;
2188 };
2189 #define	TAVOR_WQE_NDA_MASK		0x00000000FFFFFFC0ull
2190 #define	TAVOR_WQE_NDS_MASK		0x3F
2191 #define	TAVOR_WQE_DBD_MASK		0x80
2192 
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
2202 
2203 #define	TAVOR_WQE_SEND_SIGNALED_MASK	0x0000000800000000ull
2204 #define	TAVOR_WQE_SEND_SOLICIT_MASK	0x0000000200000000ull
2205 #define	TAVOR_WQE_SEND_IMMEDIATE_MASK	0x0000000100000000ull
2206 
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;
2219 };
2220 #define	TAVOR_WQE_SENDHDR_UD_AV_MASK	0xFFFFFFFFFFFFFFE0ull
2221 #define	TAVOR_WQE_SENDHDR_UD_DQPN_MASK	0xFFFFFF
2222 
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;
2233 };
2234 #define	TAVOR_WQE_SENDHDR_BIND_ATOM	0x8000000000000000ull
2235 #define	TAVOR_WQE_SENDHDR_BIND_WR	0x4000000000000000ull
2236 #define	TAVOR_WQE_SENDHDR_BIND_RD	0x2000000000000000ull
2237 
2238 struct tavor_hw_snd_wqe_remaddr_s {
2239 	uint64_t	vaddr;
2240 	uint32_t	rkey;
2241 	uint32_t			:32;
2242 };
2243 
2244 struct tavor_hw_snd_wqe_atomic_s {
2245 	uint64_t	swap_add;
2246 	uint64_t	compare;
2247 };
2248 
2249 
2250 /*
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.
2260  */
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;
2269 
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;
2282 };
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
2289 
2290 /*
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.
2295  *
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).
2299  */
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;
2308 
2309 	uint32_t			:28;
2310 	uint32_t	c		:1;
2311 	uint32_t	e		:1;
2312 	uint32_t			:2;
2313 	uint32_t			:32;
2314 };
2315 
2316 /*
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.
2320  */
2321 #define	TAVOR_RCV_WQE_NDA0_WA_MASK	0x0000000100000000ull
2322 
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;
2328 };
2329 #define	TAVOR_WQE_SGL_BYTE_CNT_MASK	0x7FFFFFFF
2330 #define	TAVOR_WQE_SGL_INLINE_MASK	0x80000000
2331 
2332 /*
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.
2337  */
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
2346 
2347 /*
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.
2354  *
2355  *    TAVOR_WQE_BUILD_UD		- Builds Unreliable Datagram Segment
2356  *
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
2385  */
2386 #define	TAVOR_WQE_BUILD_UD(qp, ud, ah, wr)				\
2387 {									\
2388 	uint64_t		*tmp;					\
2389 									\
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));				\
2402 }
2403 
2404 #define	TAVOR_WQE_BUILD_REMADDR(qp, ra, wr_rdma)			\
2405 {									\
2406 	uint64_t		*tmp;					\
2407 									\
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);			\
2413 }
2414 
2415 #define	TAVOR_WQE_BUILD_RC_ATOMIC_REMADDR(qp, rc, wr)			\
2416 {									\
2417 	uint64_t		*tmp;					\
2418 									\
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);	\
2424 }
2425 
2426 #define	TAVOR_WQE_BUILD_ATOMIC(qp, at, wr_atom)				\
2427 {									\
2428 	uint64_t		*tmp;					\
2429 									\
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);					\
2435 }
2436 
2437 #define	TAVOR_WQE_BUILD_BIND(qp, bn, wr_bind)				\
2438 {									\
2439 	uint64_t		*tmp;					\
2440 	uint64_t		bn0_tmp;				\
2441 	ibt_bind_flags_t	bind_flags;				\
2442 									\
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);					\
2459 }
2460 
2461 #define	TAVOR_WQE_BUILD_DATA_SEG(qp, ds, sgl)				\
2462 {									\
2463 	uint64_t		*tmp;					\
2464 									\
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);	\
2470 }
2471 
2472 #define	TAVOR_WQE_BUILD_DATA_SEG_SRQ(srq, ds, sgl)			\
2473 {									\
2474 	uint64_t		*tmp;					\
2475 									\
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);	\
2481 }
2482 
2483 #define	TAVOR_WQE_BUILD_INLINE(qp, ds, sz)				\
2484 {									\
2485 	uint32_t		*tmp;					\
2486 	uint32_t		inline_tmp;				\
2487 									\
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);	\
2491 }
2492 
2493 #define	TAVOR_WQE_BUILD_INLINE_ICRC(qp, ds, sz, icrc)			\
2494 {									\
2495 	uint32_t		*tmp;					\
2496 	uint32_t		inline_tmp;				\
2497 									\
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);		\
2502 }
2503 
2504 #define	TAVOR_WQE_LINKNEXT(qp, prev, ctrl, next)			\
2505 {									\
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));							\
2510 }
2511 
2512 #define	TAVOR_WQE_LINKNEXT_SRQ(srq, prev, ctrl, next)			\
2513 {									\
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));							\
2518 }
2519 
2520 #define	TAVOR_WQE_LINKFIRST(qp, prev, next)				\
2521 {									\
2522 	ddi_put64((qp)->qp_wqinfo.qa_acchdl, &((uint64_t *)(prev))[0],	\
2523 	    (next));							\
2524 }
2525 
2526 #define	TAVOR_WQE_BUILD_MLX_LRH(lrh, qp, udav, pktlen)			\
2527 {									\
2528 	uint32_t		*tmp;					\
2529 	uint32_t		lrh_tmp;				\
2530 									\
2531 	tmp	 = (uint32_t *)(lrh);					\
2532 									\
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);	\
2537 	}								\
2538 	if ((udav).grh) {						\
2539 		lrh_tmp |= (IB_LRH_NEXT_HDR_GRH << 16);			\
2540 	} else {							\
2541 		lrh_tmp |= (IB_LRH_NEXT_HDR_BTH << 16);			\
2542 	}								\
2543 	lrh_tmp |= (udav).rlid;						\
2544 	ddi_put32((qp)->qp_wqinfo.qa_acchdl, &tmp[0], lrh_tmp);		\
2545 									\
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;				\
2551 	}								\
2552 	ddi_put32((qp)->qp_wqinfo.qa_acchdl, &tmp[1], lrh_tmp);		\
2553 }
2554 
2555 /*
2556  * Note: The GRH payload length, calculated below, is the overall packet
2557  * length (in bytes) minus LRH header and GRH headers.
2558  *
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.
2561  */
2562 #define	TAVOR_WQE_BUILD_MLX_GRH(state, grh, qp, udav, pktlen)		\
2563 {									\
2564 	uint32_t		*tmp;					\
2565 	uint32_t		grh_tmp;				\
2566 	ib_gid_t		sgid;					\
2567 									\
2568 	tmp	 = (uint32_t *)(grh);					\
2569 									\
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);		\
2574 									\
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);		\
2580 									\
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));		\
2585 }
2586 
2587 #define	TAVOR_WQE_BUILD_MLX_BTH(state, bth, qp, wr)			\
2588 {									\
2589 	uint32_t		*tmp;					\
2590 	uint32_t		bth_tmp;				\
2591 									\
2592 	tmp	 = (uint32_t *)(bth);					\
2593 									\
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);		\
2597 	}								\
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);		\
2603 	}								\
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);		\
2609 }
2610 
2611 #define	TAVOR_WQE_BUILD_MLX_DETH(deth, qp)				\
2612 {									\
2613 	uint32_t		*tmp;					\
2614 									\
2615 	tmp	 = (uint32_t *)(deth);					\
2616 									\
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);	\
2624 	}								\
2625 }
2626 
2627 
2628 /*
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.
2633  */
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
2639 
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
2656 
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
2661 
2662 #define	TAVOR_HW_PKEYTABLE_OFFSET		0x4D800
2663 #define	TAVOR_HW_PKEYTABLE_PORT_SIZE		0x100
2664 #define	TAVOR_HW_PKEYTABLE_PKEY_SIZE		0x4
2665 
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);
2671 
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);
2677 
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);
2683 
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);
2689 
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));
2702 
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)
2709 
2710 
2711 /*
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.
2717  */
2718 #define	TAVOR_HW_FLASH_CFG_HWREV		8
2719 #define	TAVOR_HW_FLASH_CFG_ADDR			88
2720 #define	TAVOR_HW_FLASH_CFG_DATA			92
2721 
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
2734 
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
2740 
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
2745 
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
2754 
2755 #ifdef __cplusplus
2756 }
2757 #endif
2758 
2759 #endif	/* _SYS_IB_ADAPTERS_TAVOR_HW_H */
2760