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