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
44extern "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 */
88struct 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
119struct 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
229struct 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
350struct 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
369struct 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
409typedef 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
428typedef 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
460struct 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
473struct 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
505struct 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
516struct 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
550typedef 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
583typedef 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
618typedef 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
626typedef 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
636typedef 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
650typedef 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
667typedef 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
681typedef 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
697typedef 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
708typedef 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
721struct 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
751struct 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
797struct 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
817struct 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
865struct 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
897struct 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
955struct 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
962struct 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
998struct 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
1024struct 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 */
1088typedef 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
1094typedef 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
1105typedef 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
1115typedef 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
1126typedef 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
1136typedef 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
1149typedef 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
1174typedef 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
1192struct 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
1312struct 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
1342struct 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 */
1390struct 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
1515struct 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
1531struct 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
1552struct 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
1562struct 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
1585struct 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
1607struct 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
1657struct 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
1680struct 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
1705struct 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
1787struct 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
1926struct 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
1936struct 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
1949struct tavor_hw_mcg_qp_list_s {
1950	uint32_t	qpn		:24;
1951	uint32_t			:7;
1952	uint32_t	q		:1;
1953};
1954#else
1955struct 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
1969struct 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 */
2006struct 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 */
2077typedef 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
2091typedef 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
2104typedef 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
2119typedef 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
2134struct 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 */
2173struct 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
2207struct 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
2223struct 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
2238struct tavor_hw_snd_wqe_remaddr_s {
2239	uint64_t	vaddr;
2240	uint32_t	rkey;
2241	uint32_t			:32;
2242};
2243
2244struct 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 */
2261struct 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 */
2300struct 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
2323struct 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