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