docs/how-to-build.md: use proper markup for directory names
[unleashed/tickless.git] / include / sys / ib / adapters / hermon / hermon_event.h
blob450395796ba2393a13d1eea4a3f59fff984b5341
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
26 #ifndef _SYS_IB_ADAPTERS_HERMON_EVENT_H
27 #define _SYS_IB_ADAPTERS_HERMON_EVENT_H
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.
38 #include <sys/types.h>
39 #include <sys/conf.h>
40 #include <sys/ddi.h>
41 #include <sys/sunddi.h>
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
48 * Hermon UAR Doorbell Write Macro - writes UAR registers
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.
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.
59 * This is done as a preprocessor #if to speed up execution at run-time
60 * since doorbell ringing is a "fast-path" operation.
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); \
68 #else
69 #define HERMON_UAR_DOORBELL(state, uarhdl, hs_uar, doorbell) { \
70 ddi_put64(uarhdl, hs_uar, doorbell); \
72 #endif
75 * HERMON Doorbell Record (DBr) Write Macro - writes doorbell record in memory
77 * Since the DBr is only 32 bits at a time, this can be just a put32, not
78 * put64.
81 #define HERMON_UAR_DB_RECORD_WRITE(db_addr, dbr) \
82 *(uint32_t *)(db_addr) = htonl(dbr)
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
98 #define HERMON_NUM_EQ_SHIFT 0x9 /* hermon has 512 EQs available */
99 #define HERMON_NUM_EQ (1 << HERMON_NUM_EQ_SHIFT)
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 */
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.
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
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
141 #define HERMON_EVT_MSK_COMPLETION \
142 (1 << HERMON_EVT_COMPLETION)
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)
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)
172 #define HERMON_EVT_MSK_FEXCH_ERROR \
173 (1 << HERMON_EVT_FEXCH_ERROR)
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)
180 #define HERMON_EVT_MSK_COMMAND_INTF_COMP \
181 (1 << HERMON_EVT_COMMAND_INTF_COMP)
183 #define HERMON_EVT_MSK_LOCAL_CAT_ERROR \
184 (1 << HERMON_EVT_LOCAL_CAT_ERROR)
187 #define HERMON_EVT_NO_MASK 0
189 /* For now, "catchall" is just HERMON_EVT_LOCAL_QPC_CAT_ERROR. */
190 #define HERMON_EVT_CATCHALL_MASK 0x0040
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.
199 #define HERMON_EQ_SYNC_NORMAL 0x0
200 #define HERMON_EQ_SYNC_FORCE 0x1
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.
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
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.
220 #define HERMON_EQ_MSI_ENABLE_FLAG 0x200 /* bit 9 of 0x14 in EQC */
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.
228 * The driver writes to the with the MSB bit set to arm it, and the current
229 * CI (consumer index).
231 #define G_EQ0 0x0800
232 #define G_EQ1 0x0808
233 #define G_EQ2 0x0810
234 #define G_EQ3 0x0818
237 * They should be written as a 32-bit entity:
238 * bit 31: Arm (if set)
239 * bit 23:0 Consumer Index
241 #define EQ_ARM_BIT 0x80000000
244 * The register to be written is:
245 * (EQ_num / 4) == UAR page
246 * (EQ_NUM % 4) == G_EQx
249 #define ARM_EQ_INDEX(eq) \
250 (((eq >> 2) * PAGESIZE) + (0x0800 + ((eq & 0x03) * 0x08)))
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).
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).
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.
272 * Lastly, we have the always necessary backpointer to the resource for the
273 * EQ handle structure itself.
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);
289 struct hermon_qalloc_info_s eq_eqinfo;
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);
302 #ifdef __cplusplus
304 #endif
306 #endif /* _SYS_IB_ADAPTERS_HERMON_EVENT_H */