xref: /illumos-gate/usr/src/uts/common/sys/ib/adapters/hermon/hermon_event.h (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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_HERMON_EVENT_H
28 #define	_SYS_IB_ADAPTERS_HERMON_EVENT_H
29 
30 /*
31  * hermon_event.h
32  *    Contains all of the prototypes, #defines, and structures necessary
33  *    for the Interrupt and Event Processing routines
34  *    Specifically it contains the various event types, event flags,
35  *    structures used for managing Hermon event queues, and prototypes for
36  *    many of the functions consumed by other parts of the Hermon driver.
37  */
38 
39 #include <sys/types.h>
40 #include <sys/conf.h>
41 #include <sys/ddi.h>
42 #include <sys/sunddi.h>
43 
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47 
48 /*
49  * Hermon UAR Doorbell Write Macro - writes UAR registers
50  *
51  * If on a 32-bit system, we must hold a lock around the ddi_put64() to
52  * ensure that the 64-bit write is an atomic operation.  This is a
53  * requirement of the Hermon hardware and is to protect from the race
54  * condition present when more than one kernel thread attempts to do each
55  * of their two 32-bit accesses (for 64-bit doorbell) simultaneously.
56  *
57  * If we are on a 64-bit system then the ddi_put64() is completed as one
58  * 64-bit instruction, and the lock is not needed.
59  *
60  * This is done as a preprocessor #if to speed up execution at run-time
61  * since doorbell ringing is a "fast-path" operation.
62  */
63 #if (DATAMODEL_NATIVE == DATAMODEL_ILP32)
64 #define	HERMON_UAR_DOORBELL(state, uarhdl, hs_uar, doorbell)	{	\
65 	mutex_enter(&state->hs_uar_lock);				\
66 	ddi_put64(uarhdl, hs_uar, doorbell);				\
67 	mutex_exit(&state->hs_uar_lock);				\
68 }
69 #else
70 #define	HERMON_UAR_DOORBELL(state, uarhdl, hs_uar, doorbell)	{	\
71 	ddi_put64(uarhdl, hs_uar, doorbell);				\
72 }
73 #endif
74 
75 /*
76  * HERMON Doorbell Record (DBr) Write Macro - writes doorbell record in memory
77  *
78  * Since the DBr is only 32 bits at a time, this can be just a put32, not
79  * put64.
80  */
81 
82 #define	HERMON_UAR_DB_RECORD_WRITE(db_addr, dbr)			\
83 	*(uint32_t *)(db_addr) = htonl(dbr)
84 
85 /*
86  * The following defines specify the default number of Event Queues (EQ) and
87  * their default size.  By default the size of each EQ is set to 8K entries,
88  * but this value is controllable through the "cp_log_eq_sz" configuration
89  * variable.  We also specify the number of EQs which the Arbel driver
90  * currently uses (HERMON_NUM_EQ_USED).  Note: this value should be less than
91  * or equal to HERMON_NUM_EQ.
92  * HERMON:  will limit to 4 total - in anticipation of VMM implementation
93  *    logical Eq (0)-catastrophic,
94  *		 (1)-error completions,
95  *		 (2)-misc events and
96  *		 (3)-completions
97  */
98 
99 #define	HERMON_NUM_EQ_SHIFT		0x9 /* hermon has 512 EQs available */
100 #define	HERMON_NUM_EQ			(1 << HERMON_NUM_EQ_SHIFT)
101 
102 #define	HERMON_NUM_EQ_USED		4  		/* four per domain */
103 #define	HERMON_DEFAULT_EQ_SZ_SHIFT	0xd		/* 8192 entries/EQ */
104 #define	HERMON_EQ_CI_MASK		0xFFFFFF 	/* low 24 bits */
105 
106 /*
107  * These are the defines for the Hermon event types.  They are specified by
108  * the Hermon PRM.  Below are the "event type masks" in
109  * which each event type corresponds to one of the 64-bits in the mask.
110  */
111 
112 /* Note:  In order per PRM listing */
113 /* Completion Events */
114 #define	HERMON_EVT_COMPLETION			0x00
115 /* IB Affiliated Asynch Events */
116 #define	HERMON_EVT_PATH_MIGRATED		0x01
117 #define	HERMON_EVT_COMM_ESTABLISHED		0x02
118 #define	HERMON_EVT_SEND_QUEUE_DRAINED		0x03
119 #define	HERMON_EVT_SRQ_LAST_WQE_REACHED	0x13
120 #define	HERMON_EVT_SRQ_LIMIT			0x14
121 /* QP Affiliated Asynch Event */
122 #define	HERMON_EVT_CQ_ERRORS			0x04 /* overrun, protection */
123 #define	HERMON_EVT_LOCAL_WQ_CAT_ERROR		0x05
124 #define	HERMON_EVT_LOCAL_QPC_CAT_ERROR		0x06
125 #define	HERMON_EVT_PATH_MIGRATE_FAILED		0x07
126 #define	HERMON_EVT_INV_REQ_LOCAL_WQ_ERROR	0x10
127 #define	HERMON_EVT_LOCAL_ACC_VIO_WQ_ERROR	0x11
128 #define	HERMON_EVT_SRQ_CATASTROPHIC_ERROR	0x12
129 #define	HERMON_EVT_SPOOF_FAIL			0x16	/* enet only */
130 /* Unaffiliated Asynch Events/Errors */
131 #define	HERMON_EVT_PORT_STATE_CHANGE		0x09
132 #define	HERMON_EVT_GPIO				0x15
133 /* Command Interface */
134 #define	HERMON_EVT_COMMAND_INTF_COMP		0x0A
135 /* Miscellaneous */
136 #define	HERMON_EVT_LOCAL_CAT_ERROR		0x08
137 /* LEGACY - no longer supported */
138 #define	HERMON_EVT_WQE_PG_FAULT			0x0B
139 #define	HERMON_EVT_UNSUPPORTED_PG_FAULT		0x0C
140 #define	HERMON_EVT_ECC_DETECTION		0x0E
141 #define	HERMON_EVT_EQ_OVERFLOW			0x0F
142 
143 
144 #define	HERMON_EVT_MSK_COMPLETION		\
145 	(1 << HERMON_EVT_COMPLETION)
146 
147 #define	HERMON_EVT_MSK_PATH_MIGRATED		\
148 	(1 << HERMON_EVT_PATH_MIGRATED)
149 #define	HERMON_EVT_MSK_COMM_ESTABLISHED		\
150 	(1 << HERMON_EVT_COMM_ESTABLISHED)
151 #define	HERMON_EVT_MSK_SEND_QUEUE_DRAINED	\
152 	(1 << HERMON_EVT_SEND_QUEUE_DRAINED)
153 #define	HERMON_EVT_MSK_SRQ_LAST_WQE_REACHED	\
154 	(1 << HERMON_EVT_SRQ_LAST_WQE_REACHED)
155 #define	HERMON_EVT_MSK_SRQ_LIMIT	\
156 	(1 << HERMON_EVT_SRQ_LIMIT)
157 
158 #define	HERMON_EVT_MSK_CQ_ERRORS			\
159 	(1 << HERMON_EVT_CQ_ERRORS)
160 #define	HERMON_EVT_MSK_LOCAL_WQ_CAT_ERROR	\
161 	(1 << HERMON_EVT_LOCAL_WQ_CAT_ERROR)
162 #define	HERMON_EVT_MSK_LOCAL_QPC_CAT_ERROR	\
163 	(1 << HERMON_EVT_LOCAL_QPC_CAT_ERROR)
164 #define	HERMON_EVT_MSK_PATH_MIGRATE_FAILED	\
165 	(1 << HERMON_EVT_PATH_MIGRATE_FAILED)
166 #define	HERMON_EVT_MSK_INV_REQ_LOCAL_WQ_ERROR	\
167 	(1 << HERMON_EVT_INV_REQ_LOCAL_WQ_ERROR)
168 #define	HERMON_EVT_MSK_LOCAL_ACC_VIO_WQ_ERROR	\
169 	(1 << HERMON_EVT_LOCAL_ACC_VIO_WQ_ERROR)
170 #define	HERMON_EVT_MSK_SRQ_CATASTROPHIC_ERROR	\
171 	(1 << HERMON_EVT_SRQ_CATASTROPHIC_ERROR)
172 #define	HERMON_EVT_MSK_SPOOF_FAIL	\
173 	(1 << HERMON_EVT_SPOOF_FAIL)
174 
175 #define	HERMON_EVT_MSK_PORT_STATE_CHANGE		\
176 	(1 << HERMON_EVT_PORT_STATE_CHANGE)
177 #define	HERMON_EVT_MSK_GPIO		\
178 	(1 << HERMON_EVT_GPIO)
179 
180 #define	HERMON_EVT_MSK_COMMAND_INTF_COMP		\
181 	(1 << HERMON_EVT_COMMAND_INTF_COMP)
182 
183 #define	HERMON_EVT_MSK_LOCAL_CAT_ERROR		\
184 	(1 << HERMON_EVT_LOCAL_CAT_ERROR)
185 
186 #define	HERMON_EVT_MSK_WQE_PG_FAULT		\
187 	(1 << HERMON_EVT_WQE_PG_FAULT)
188 #define	HERMON_EVT_MSK_UNSUPPORTED_PG_FAULT	\
189 	(1 << HERMON_EVT_UNSUPPORTED_PG_FAULT)
190 #define	HERMON_EVT_MSK_ECC_DETECTION		\
191 	(1 << HERMON_EVT_ECC_DETECTION)
192 
193 
194 #define	HERMON_EVT_NO_MASK			0
195 /*
196  *  WAS in Tavor & Arbel, but now two bits - 0x1000 and 0x0800 (0x0B & 0x00C)
197  *  are no longer supported, so the catchall will be just 0x0040 (0x06)
198  *  Loc QPC cat
199  *	#define	HERMON_EVT_CATCHALL_MASK		0x1840
200  */
201 
202 #define	HERMON_EVT_CATCHALL_MASK		0x0040
203 /*
204  * The last defines are used by hermon_eqe_sync() to indicate whether or not
205  * to force a DMA sync.  The case for forcing a DMA sync on a EQE comes from
206  * the possibility that we could receive an interrupt, read of the ECR, and
207  * have each of these operations complete successfully _before_ the hardware
208  * has finished its DMA to the event queue.
209  */
210 #define	HERMON_EQ_SYNC_NORMAL			0x0
211 #define	HERMON_EQ_SYNC_FORCE			0x1
212 
213 /*
214  * Catastrophic error values.  In case of a catastrophic error, the following
215  * errors are reported in a special buffer space.  The buffer location is
216  * returned from a QUERY_FW command.  We check that buffer against these error
217  * values to determine what kind of error occurred.
218  */
219 #define	HERMON_CATASTROPHIC_INTERNAL_ERROR		0x0
220 #define	HERMON_CATASTROPHIC_UPLINK_BUS_ERROR	0x3
221 #define	HERMON_CATASTROPHIC_INTERNAL_PARITY_ERROR	0x5
222 /* Presumably, this is no longer supported */
223 #define	HERMON_CATASTROPHIC_DDR_DATA_ERROR		0x4
224 
225 /*
226  * This define is the 'enable' flag used when programming the MSI number
227  * into event queues.  It is or'd with the MSI number and the result is
228  * written into the EX context.
229  */
230 
231 #define	HERMON_EQ_MSI_ENABLE_FLAG	0x200  /* bit 9 of 0x14 in EQC */
232 
233 /*
234  * The following#defines are for the EQ's in the UAR pages.  In Hermon, the
235  * arm mechanism is new - in the first 128 (that is, 0 - 127) UAR pages, which
236  * are reserved, the only useful thing is the EQ registers.  In turn those
237  * locations are ignored in any other UAR page.
238  *
239  * The driver writes to the with the MSB bit set to arm it, and the current
240  * CI (consumer index).
241  */
242 #define	G_EQ0		0x0800
243 #define	G_EQ1		0x0808
244 #define	G_EQ2		0x0810
245 #define	G_EQ3		0x0818
246 
247 /*
248  * They should be written as a 32-bit entity:
249  * bit 31:  Arm (if set)
250  * bit 23:0 Consumer Index
251  */
252 #define	EQ_ARM_BIT	0x80000000
253 
254 /*
255  * The register to be written is:
256  * 	(EQ_num / 4) == UAR page
257  *	(EQ_NUM % 4) == G_EQx
258  */
259 
260 #define	ARM_EQ_INDEX(eq) \
261 	(((eq >> 2) * PAGESIZE) + (0x0800 + ((eq & 0x03) * 0x08)))
262 
263 
264 /*
265  * The hermon_sw_eq_s structure is also referred to using the "hermon_eqhdl_t"
266  * typedef (see hermon_typedef.h).  It encodes all the information necessary
267  * to track the various resources needed to allocate, initialize, poll, and
268  * (later) free an event queue (EQ).
269  *
270  * Specifically, it has a consumer index and a lock to ensure single threaded
271  * access to it.  It has pointers to the various resources allocated for the
272  * event queue, i.e. an EQC resource and the memory for the event queue
273  * itself.  It has flags to indicate whether the EQ requires ddi_dma_sync()
274  * ("eq_sync") or to indicate which type of event class(es) the EQ has been
275  * mapped to (eq_evttypemask).
276  *
277  * It also has a pointer to the associated MR handle (for the mapped queue
278  * memory) and a function pointer that points to the handler that should
279  * be called when the corresponding EQ has fired.  Note: the "eq_func"
280  * handler takes a Hermon softstate pointer, a pointer to the EQ handle, and a
281  * pointer to a generic hermon_hw_eqe_t structure.  It is up to the "eq_func"
282  * handler function to determine what specific type of event is being passed.
283  *
284  * Lastly, we have the always necessary backpointer to the resource for the
285  * EQ handle structure itself.
286  */
287 struct hermon_sw_eq_s {
288 	uint32_t		eq_consindx;
289 	uint32_t		eq_eqnum;
290 	hermon_hw_eqe_t		*eq_buf;
291 	hermon_mrhdl_t		eq_mrhdl;
292 	uint32_t		eq_bufsz;
293 	uint32_t		eq_log_eqsz;
294 	uint32_t		eq_nexteqe;
295 	uint_t			eq_sync;
296 	uint_t			eq_evttypemask;
297 	hermon_rsrc_t		*eq_eqcrsrcp;
298 	hermon_rsrc_t		*eq_rsrcp;
299 	int (*eq_func)(hermon_state_t *state, hermon_eqhdl_t eq,
300 	    hermon_hw_eqe_t *eqe);
301 
302 	struct hermon_qalloc_info_s eq_eqinfo;
303 };
304 
305 int hermon_eq_init_all(hermon_state_t *state);
306 int hermon_eq_fini_all(hermon_state_t *state);
307 int hermon_eq_arm_all(hermon_state_t *state);
308 uint_t hermon_isr(caddr_t arg1, caddr_t arg2);
309 void hermon_eq_doorbell(hermon_state_t *state, uint32_t eq_cmd, uint32_t eqn,
310     uint32_t eq_param);
311 void hermon_eq_overflow_handler(hermon_state_t *state, hermon_eqhdl_t eq,
312     hermon_hw_eqe_t *eqe);
313 
314 #ifdef __cplusplus
315 }
316 #endif
317 
318 #endif	/* _SYS_IB_ADAPTERS_HERMON_EVENT_H */
319