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