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 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * tavor_event.c 29 * Tavor Interrupt and Event Processing Routines 30 * 31 * Implements all the routines necessary for allocating, freeing, and 32 * handling all of the various event types that the Tavor hardware can 33 * generate. 34 * These routines include the main Tavor interrupt service routine 35 * (tavor_isr()) as well as all the code necessary to setup and handle 36 * events from each of the many event queues used by the Tavor device. 37 */ 38 39 #include <sys/types.h> 40 #include <sys/conf.h> 41 #include <sys/ddi.h> 42 #include <sys/sunddi.h> 43 #include <sys/modctl.h> 44 45 #include <sys/ib/adapters/tavor/tavor.h> 46 47 static void tavor_eq_poll(tavor_state_t *state, tavor_eqhdl_t eq); 48 static void tavor_eq_catastrophic(tavor_state_t *state); 49 static int tavor_eq_alloc(tavor_state_t *state, uint32_t log_eq_size, 50 uint_t intr, tavor_eqhdl_t *eqhdl); 51 static int tavor_eq_free(tavor_state_t *state, tavor_eqhdl_t *eqhdl); 52 static int tavor_eq_handler_init(tavor_state_t *state, tavor_eqhdl_t eq, 53 uint_t evt_type_mask, int (*eqfunc)(tavor_state_t *state, 54 tavor_eqhdl_t eq, tavor_hw_eqe_t *eqe)); 55 static int tavor_eq_handler_fini(tavor_state_t *state, tavor_eqhdl_t eq); 56 static void tavor_eqe_sync(tavor_eqhdl_t eq, tavor_hw_eqe_t *eqe, uint_t flag, 57 uint_t force_sync); 58 static int tavor_port_state_change_handler(tavor_state_t *state, 59 tavor_eqhdl_t eq, tavor_hw_eqe_t *eqe); 60 static int tavor_comm_estbl_handler(tavor_state_t *state, 61 tavor_eqhdl_t eq, tavor_hw_eqe_t *eqe); 62 static int tavor_local_wq_cat_err_handler(tavor_state_t *state, 63 tavor_eqhdl_t eq, tavor_hw_eqe_t *eqe); 64 static int tavor_invreq_local_wq_err_handler(tavor_state_t *state, 65 tavor_eqhdl_t eq, tavor_hw_eqe_t *eqe); 66 static int tavor_local_acc_vio_wq_err_handler(tavor_state_t *state, 67 tavor_eqhdl_t eq, tavor_hw_eqe_t *eqe); 68 static int tavor_sendq_drained_handler(tavor_state_t *state, 69 tavor_eqhdl_t eq, tavor_hw_eqe_t *eqe); 70 static int tavor_path_mig_handler(tavor_state_t *state, 71 tavor_eqhdl_t eq, tavor_hw_eqe_t *eqe); 72 static int tavor_path_mig_err_handler(tavor_state_t *state, 73 tavor_eqhdl_t eq, tavor_hw_eqe_t *eqe); 74 static int tavor_srq_catastrophic_handler(tavor_state_t *state, 75 tavor_eqhdl_t eq, tavor_hw_eqe_t *eqe); 76 static int tavor_srq_last_wqe_reached_handler(tavor_state_t *state, 77 tavor_eqhdl_t eq, tavor_hw_eqe_t *eqe); 78 static int tavor_ecc_detection_handler(tavor_state_t *state, 79 tavor_eqhdl_t eq, tavor_hw_eqe_t *eqe); 80 static int tavor_no_eqhandler(tavor_state_t *state, tavor_eqhdl_t eq, 81 tavor_hw_eqe_t *eqe); 82 83 84 /* 85 * tavor_eq_init_all 86 * Context: Only called from attach() path context 87 */ 88 int 89 tavor_eq_init_all(tavor_state_t *state) 90 { 91 uint_t log_eq_size, intr_num; 92 uint_t num_eq, num_eq_init, num_eq_unmap; 93 int status, i; 94 char *errormsg; 95 96 TAVOR_TNF_ENTER(tavor_eq_init_all); 97 98 /* 99 * For now, all Event Queues default to the same size (pulled from 100 * the current configuration profile) and are all assigned to the 101 * same interrupt or MSI. In the future we may support assigning 102 * EQs to specific interrupts or MSIs XXX 103 */ 104 log_eq_size = state->ts_cfg_profile->cp_log_default_eq_sz; 105 106 /* 107 * If MSI is to be used, then set intr_num to the MSI number 108 * (currently zero because we're using only one) or'd with the 109 * MSI enable flag. Otherwise, for regular (i.e. 'legacy') interrupt, 110 * use the 'inta_pin' value returned by QUERY_ADAPTER. 111 */ 112 if (state->ts_intr_type_chosen == DDI_INTR_TYPE_MSI) { 113 intr_num = TAVOR_EQ_MSI_ENABLE_FLAG | 0; 114 } else { 115 intr_num = state->ts_adapter.inta_pin; 116 } 117 118 /* 119 * Total number of supported EQs is hardcoded. Tavor hardware 120 * supports up to 64 EQs. We are currently using only 45 of them 121 * We will set aside the first 32 for use with Completion Queues (CQ) 122 * and reserve a few of the other 32 for each specific class of event 123 * (see below for more details). 124 */ 125 num_eq = TAVOR_NUM_EQ_USED; 126 127 /* 128 * The "num_eq_unmap" variable is used in any possible failure 129 * cleanup (below) to indicate which events queues might require 130 * possible event class unmapping. 131 */ 132 num_eq_unmap = 0; 133 134 /* 135 * Allocate and initialize all the Event Queues. If any of these 136 * EQ allocations fail then jump to the end, cleanup what had been 137 * successfully initialized, and return an error. 138 */ 139 for (i = 0; i < num_eq; i++) { 140 status = tavor_eq_alloc(state, log_eq_size, intr_num, 141 &state->ts_eqhdl[i]); 142 if (status != DDI_SUCCESS) { 143 /* Set "status" and "errormsg" and goto failure */ 144 TAVOR_TNF_FAIL(status, "failed EQ alloc"); 145 num_eq_init = i; 146 goto all_eq_init_fail; 147 } 148 } 149 num_eq_init = num_eq; 150 151 /* 152 * Setup EQ0-EQ31 for use with Completion Queues. Note: We can 153 * cast the return value to void here because, when we use the 154 * TAVOR_EVT_NO_MASK flag, it is not possible for 155 * tavor_eq_handler_init() to return an error. 156 */ 157 for (i = 0; i < 32; i++) { 158 (void) tavor_eq_handler_init(state, state->ts_eqhdl[i], 159 TAVOR_EVT_NO_MASK, tavor_cq_handler); 160 } 161 num_eq_unmap = 32; 162 163 /* 164 * Setup EQ32 for handling Completion Queue Error Events. 165 * 166 * These events include things like CQ overflow or CQ access 167 * violation errors. If this setup fails for any reason (which, in 168 * general, it really never should), then jump to the end, cleanup 169 * everything that has been successfully initialized, and return an 170 * error. 171 */ 172 status = tavor_eq_handler_init(state, state->ts_eqhdl[32], 173 TAVOR_EVT_MSK_CQ_ERRORS, tavor_cq_err_handler); 174 if (status != DDI_SUCCESS) { 175 /* Set "status" and "errormsg" and goto failure */ 176 TAVOR_TNF_FAIL(status, "completion queue error event"); 177 goto all_eq_init_fail; 178 } 179 num_eq_unmap = 33; 180 181 /* 182 * Setup EQ33 for handling Port State Change Events 183 * 184 * These events include things like Port Up and Port Down events. 185 * If this setup fails for any reason (which, in general, it really 186 * never should), then undo all previous EQ mapping, jump to the end, 187 * cleanup everything that has been successfully initialized, and 188 * return an error. 189 */ 190 status = tavor_eq_handler_init(state, state->ts_eqhdl[33], 191 TAVOR_EVT_MSK_PORT_STATE_CHANGE, tavor_port_state_change_handler); 192 if (status != DDI_SUCCESS) { 193 /* Set "status" and "errormsg" and goto failure */ 194 TAVOR_TNF_FAIL(status, "port state change event"); 195 goto all_eq_init_fail; 196 } 197 num_eq_unmap = 34; 198 199 /* 200 * Setup EQ34 for handling Communication Established Events 201 * 202 * These events correspond to the IB affiliated asynchronous events 203 * that are used for connection management. If this setup fails for 204 * any reason (which, in general, it really never should), then undo 205 * all previous EQ mapping, jump to the end, cleanup everything that 206 * has been successfully initialized, and return an error. 207 */ 208 status = tavor_eq_handler_init(state, state->ts_eqhdl[34], 209 TAVOR_EVT_MSK_COMM_ESTABLISHED, tavor_comm_estbl_handler); 210 if (status != DDI_SUCCESS) { 211 /* Set "status" and "errormsg" and goto failure */ 212 TAVOR_TNF_FAIL(status, "communication established event"); 213 goto all_eq_init_fail; 214 } 215 num_eq_unmap = 35; 216 217 /* 218 * Setup EQ35 for handling Command Completion Events 219 * 220 * These events correspond to the Tavor generated events that are used 221 * to indicate Tavor firmware command completion. These events are 222 * only generated when Tavor firmware commands are posted using the 223 * asynchronous completion mechanism. If this setup fails for any 224 * reason (which, in general, it really never should), then undo all 225 * previous EQ mapping, jump to the end, cleanup everything that has 226 * been successfully initialized, and return an error. 227 */ 228 status = tavor_eq_handler_init(state, state->ts_eqhdl[35], 229 TAVOR_EVT_MSK_COMMAND_INTF_COMP, tavor_cmd_complete_handler); 230 if (status != DDI_SUCCESS) { 231 /* Set "status" and "errormsg" and goto failure */ 232 TAVOR_TNF_FAIL(status, "command completion event"); 233 goto all_eq_init_fail; 234 } 235 num_eq_unmap = 36; 236 237 /* 238 * Setup EQ36 for handling Local WQ Catastrophic Error Events 239 * 240 * These events correspond to the similarly-named IB affiliated 241 * asynchronous error type. If this setup fails for any reason 242 * (which, in general, it really never should), then undo all previous 243 * EQ mapping, jump to the end, cleanup everything that has been 244 * successfully initialized, and return an error. 245 */ 246 status = tavor_eq_handler_init(state, state->ts_eqhdl[36], 247 TAVOR_EVT_MSK_LOCAL_WQ_CAT_ERROR, tavor_local_wq_cat_err_handler); 248 if (status != DDI_SUCCESS) { 249 /* Set "status" and "errormsg" and goto failure */ 250 TAVOR_TNF_FAIL(status, "local WQ catastrophic error event"); 251 goto all_eq_init_fail; 252 } 253 num_eq_unmap = 37; 254 255 /* 256 * Setup EQ37 for handling Invalid Req Local WQ Error Events 257 * 258 * These events also correspond to the similarly-named IB affiliated 259 * asynchronous error type. If this setup fails for any reason 260 * (which, in general, it really never should), then undo all previous 261 * EQ mapping, jump to the end, cleanup everything that has been 262 * successfully initialized, and return an error. 263 */ 264 status = tavor_eq_handler_init(state, state->ts_eqhdl[37], 265 TAVOR_EVT_MSK_INV_REQ_LOCAL_WQ_ERROR, 266 tavor_invreq_local_wq_err_handler); 267 if (status != DDI_SUCCESS) { 268 /* Set "status" and "errormsg" and goto failure */ 269 TAVOR_TNF_FAIL(status, "invalid req local WQ error event"); 270 goto all_eq_init_fail; 271 } 272 num_eq_unmap = 38; 273 274 /* 275 * Setup EQ38 for handling Local Access Violation WQ Error Events 276 * 277 * These events also correspond to the similarly-named IB affiliated 278 * asynchronous error type. If this setup fails for any reason 279 * (which, in general, it really never should), then undo all previous 280 * EQ mapping, jump to the end, cleanup everything that has been 281 * successfully initialized, and return an error. 282 */ 283 status = tavor_eq_handler_init(state, state->ts_eqhdl[38], 284 TAVOR_EVT_MSK_LOCAL_ACC_VIO_WQ_ERROR, 285 tavor_local_acc_vio_wq_err_handler); 286 if (status != DDI_SUCCESS) { 287 /* Set "status" and "errormsg" and goto failure */ 288 TAVOR_TNF_FAIL(status, "local access violation WQ error event"); 289 goto all_eq_init_fail; 290 } 291 num_eq_unmap = 39; 292 293 /* 294 * Setup EQ39 for handling Send Queue Drained Events 295 * 296 * These events correspond to the IB affiliated asynchronous events 297 * that are used to indicate completion of a Send Queue Drained QP 298 * state transition. If this setup fails for any reason (which, in 299 * general, it really never should), then undo all previous EQ 300 * mapping, jump to the end, cleanup everything that has been 301 * successfully initialized, and return an error. 302 */ 303 status = tavor_eq_handler_init(state, state->ts_eqhdl[39], 304 TAVOR_EVT_MSK_SEND_QUEUE_DRAINED, tavor_sendq_drained_handler); 305 if (status != DDI_SUCCESS) { 306 /* Set "status" and "errormsg" and goto failure */ 307 TAVOR_TNF_FAIL(status, "send queue drained event"); 308 goto all_eq_init_fail; 309 } 310 num_eq_unmap = 40; 311 312 /* 313 * Setup EQ40 for handling Path Migration Succeeded Events 314 * 315 * These events correspond to the IB affiliated asynchronous events 316 * that are used to indicate successful completion of a path 317 * migration. If this setup fails for any reason (which, in general, 318 * it really never should), then undo all previous EQ mapping, jump 319 * to the end, cleanup everything that has been successfully 320 * initialized, and return an error. 321 */ 322 status = tavor_eq_handler_init(state, state->ts_eqhdl[40], 323 TAVOR_EVT_MSK_PATH_MIGRATED, tavor_path_mig_handler); 324 if (status != DDI_SUCCESS) { 325 /* Set "status" and "errormsg" and goto failure */ 326 TAVOR_TNF_FAIL(status, "path migration succeeded event"); 327 goto all_eq_init_fail; 328 } 329 num_eq_unmap = 41; 330 331 /* 332 * Setup EQ41 for handling Path Migration Failed Events 333 * 334 * These events correspond to the IB affiliated asynchronous events 335 * that are used to indicate that path migration was not successful. 336 * If this setup fails for any reason (which, in general, it really 337 * never should), then undo all previous EQ mapping, jump to the end, 338 * cleanup everything that has been successfully initialized, and 339 * return an error. 340 */ 341 status = tavor_eq_handler_init(state, state->ts_eqhdl[41], 342 TAVOR_EVT_MSK_PATH_MIGRATE_FAILED, tavor_path_mig_err_handler); 343 if (status != DDI_SUCCESS) { 344 /* Set "status" and "errormsg" and goto failure */ 345 TAVOR_TNF_FAIL(status, "path migration failed event"); 346 goto all_eq_init_fail; 347 } 348 num_eq_unmap = 42; 349 350 /* 351 * Setup EQ42 for handling Local Catastrophic Error Events 352 * 353 * These events correspond to the similarly-named IB unaffiliated 354 * asynchronous error type. If this setup fails for any reason 355 * (which, in general, it really never should), then undo all previous 356 * EQ mapping, jump to the end, cleanup everything that has been 357 * successfully initialized, and return an error. 358 * 359 * This error is unique, in that an EQE is not generated if this event 360 * occurs. Instead, an interrupt is called and we must poll the 361 * Catastrophic Error buffer in CR-Space. This mapping is setup simply 362 * to enable this error reporting. We pass in a NULL handler since it 363 * will never be called. 364 */ 365 status = tavor_eq_handler_init(state, state->ts_eqhdl[42], 366 TAVOR_EVT_MSK_LOCAL_CAT_ERROR, NULL); 367 if (status != DDI_SUCCESS) { 368 /* Set "status" and "errormsg" and goto failure */ 369 TAVOR_TNF_FAIL(status, "local catastrophic error event"); 370 goto all_eq_init_fail; 371 } 372 num_eq_unmap = 43; 373 374 /* 375 * Setup EQ43 for handling SRQ Catastrophic Error Events 376 * 377 * These events correspond to the similarly-named IB affiliated 378 * asynchronous error type. If this setup fails for any reason 379 * (which, in general, it really never should), then undo all previous 380 * EQ mapping, jump to the end, cleanup everything that has been 381 * successfully initialized, and return an error. 382 */ 383 status = tavor_eq_handler_init(state, state->ts_eqhdl[43], 384 TAVOR_EVT_MSK_SRQ_CATASTROPHIC_ERROR, 385 tavor_srq_catastrophic_handler); 386 if (status != DDI_SUCCESS) { 387 /* Set "status" and "errormsg" and goto failure */ 388 TAVOR_TNF_FAIL(status, "srq catastrophic error event"); 389 goto all_eq_init_fail; 390 } 391 num_eq_unmap = 44; 392 393 /* 394 * Setup EQ44 for handling SRQ Last WQE Reached Events 395 * 396 * These events correspond to the similarly-named IB affiliated 397 * asynchronous event type. If this setup fails for any reason 398 * (which, in general, it really never should), then undo all previous 399 * EQ mapping, jump to the end, cleanup everything that has been 400 * successfully initialized, and return an error. 401 */ 402 status = tavor_eq_handler_init(state, state->ts_eqhdl[44], 403 TAVOR_EVT_MSK_SRQ_LAST_WQE_REACHED, 404 tavor_srq_last_wqe_reached_handler); 405 if (status != DDI_SUCCESS) { 406 /* Set "status" and "errormsg" and goto failure */ 407 TAVOR_TNF_FAIL(status, "srq last wqe reached event"); 408 goto all_eq_init_fail; 409 } 410 num_eq_unmap = 45; 411 412 /* 413 * Setup EQ45 for handling ECC error detection events 414 * 415 * These events correspond to the similarly-named IB affiliated 416 * asynchronous event type. If this setup fails for any reason 417 * (which, in general, it really never should), then undo all previous 418 * EQ mapping, jump to the end, cleanup everything that has been 419 * successfully initialized, and return an error. 420 */ 421 status = tavor_eq_handler_init(state, state->ts_eqhdl[45], 422 TAVOR_EVT_MSK_ECC_DETECTION, 423 tavor_ecc_detection_handler); 424 if (status != DDI_SUCCESS) { 425 /* Set "status" and "errormsg" and goto failure */ 426 TAVOR_TNF_FAIL(status, "ecc detection event"); 427 goto all_eq_init_fail; 428 } 429 num_eq_unmap = 46; 430 431 /* 432 * Setup EQ46 to catch all other types of events. Specifically, we 433 * do not catch the "Local EEC Catastrophic Error Event" because we 434 * should have no EEC (the Tavor driver does not support RD). We also 435 * choose not to handle any of the address translation page fault 436 * event types. Since we are not doing any page fault handling (and 437 * since the Tavor firmware does not currently support any such 438 * handling), we allow these events to go to the catch-all handler. 439 */ 440 status = tavor_eq_handler_init(state, state->ts_eqhdl[46], 441 TAVOR_EVT_CATCHALL_MASK, tavor_no_eqhandler); 442 if (status != DDI_SUCCESS) { 443 /* Set "status" and "errormsg" and goto failure */ 444 TAVOR_TNF_FAIL(status, "all other events"); 445 TNF_PROBE_0(tavor_eq_init_all_allothershdlr_fail, 446 TAVOR_TNF_ERROR, ""); 447 goto all_eq_init_fail; 448 } 449 450 TAVOR_TNF_EXIT(tavor_eq_init_all); 451 return (DDI_SUCCESS); 452 453 all_eq_init_fail: 454 /* Unmap any of the partially mapped EQs from above */ 455 for (i = 0; i < num_eq_unmap; i++) { 456 (void) tavor_eq_handler_fini(state, state->ts_eqhdl[i]); 457 } 458 459 /* Free up any of the partially allocated EQs from above */ 460 for (i = 0; i < num_eq_init; i++) { 461 (void) tavor_eq_free(state, &state->ts_eqhdl[i]); 462 } 463 TNF_PROBE_1(tavor_eq_init_all_fail, TAVOR_TNF_ERROR, "", 464 tnf_string, msg, errormsg); 465 TAVOR_TNF_EXIT(tavor_eq_init_all); 466 return (status); 467 } 468 469 470 /* 471 * tavor_eq_fini_all 472 * Context: Only called from attach() and/or detach() path contexts 473 */ 474 int 475 tavor_eq_fini_all(tavor_state_t *state) 476 { 477 uint_t num_eq; 478 int status, i; 479 480 TAVOR_TNF_ENTER(tavor_eq_fini_all); 481 482 /* 483 * Grab the total number of supported EQs again. This is the same 484 * hardcoded value that was used above (during the event queue 485 * initialization.) 486 */ 487 num_eq = TAVOR_NUM_EQ_USED; 488 489 /* 490 * For each of the event queues that we initialized and mapped 491 * earlier, attempt to unmap the events from the EQ. 492 */ 493 for (i = 0; i < num_eq; i++) { 494 status = tavor_eq_handler_fini(state, state->ts_eqhdl[i]); 495 if (status != DDI_SUCCESS) { 496 TNF_PROBE_0(tavor_eq_fini_all_eqhdlfini_fail, 497 TAVOR_TNF_ERROR, ""); 498 TAVOR_TNF_EXIT(tavor_eq_fini_all); 499 return (DDI_FAILURE); 500 } 501 } 502 503 /* 504 * Teardown and free up all the Event Queues that were allocated 505 * earlier. 506 */ 507 for (i = 0; i < num_eq; i++) { 508 status = tavor_eq_free(state, &state->ts_eqhdl[i]); 509 if (status != DDI_SUCCESS) { 510 TNF_PROBE_0(tavor_eq_fini_all_eqfree_fail, 511 TAVOR_TNF_ERROR, ""); 512 TAVOR_TNF_EXIT(tavor_eq_fini_all); 513 return (DDI_FAILURE); 514 } 515 } 516 517 TAVOR_TNF_EXIT(tavor_eq_fini_all); 518 return (DDI_SUCCESS); 519 } 520 521 522 /* 523 * tavor_eq_arm_all 524 * Context: Only called from attach() and/or detach() path contexts 525 */ 526 void 527 tavor_eq_arm_all(tavor_state_t *state) 528 { 529 uint_t num_eq; 530 int i; 531 532 TAVOR_TNF_ENTER(tavor_eq_arm_all); 533 534 /* 535 * Grab the total number of supported EQs again. This is the same 536 * hardcoded value that was used above (during the event queue 537 * initialization.) 538 */ 539 num_eq = TAVOR_NUM_EQ_USED; 540 541 /* 542 * For each of the event queues that we initialized and mapped 543 * earlier, attempt to arm it for event generation. 544 */ 545 for (i = 0; i < num_eq; i++) { 546 tavor_eq_doorbell(state, TAVOR_EQDB_REARM_EQ, i, 0); 547 } 548 549 TAVOR_TNF_EXIT(tavor_eq_arm_all); 550 } 551 552 553 /* 554 * tavor_isr() 555 * Context: Only called from interrupt context (and during panic) 556 */ 557 /* ARGSUSED */ 558 uint_t 559 tavor_isr(caddr_t arg1, caddr_t arg2) 560 { 561 tavor_state_t *state; 562 uint64_t *ecr, *clr_int; 563 uint64_t ecrreg, int_mask; 564 uint_t status; 565 int i; 566 567 TAVOR_TNF_ENTER(tavor_isr); 568 569 /* 570 * Grab the Tavor softstate pointer from the input parameter 571 */ 572 state = (tavor_state_t *)arg1; 573 574 /* 575 * Find the pointers to the ECR and clr_INT registers 576 */ 577 ecr = state->ts_cmd_regs.ecr; 578 clr_int = state->ts_cmd_regs.clr_int; 579 580 /* 581 * Read the ECR register. Each of the 64 bits in the ECR register 582 * corresponds to an event queue. If a bit is set, then the 583 * corresponding event queue has fired. 584 */ 585 ecrreg = ddi_get64(state->ts_reg_cmdhdl, ecr); 586 587 /* 588 * As long as there are bits set (i.e. as long as there are still 589 * EQs in the "fired" state), call tavor_eq_poll() to process each 590 * fired EQ. If no ECR bits are set, do not claim the interrupt. 591 */ 592 status = DDI_INTR_UNCLAIMED; 593 do { 594 i = 0; 595 while (ecrreg != 0x0) { 596 if (ecrreg & 0x1) { 597 tavor_eq_poll(state, state->ts_eqhdl[i]); 598 status = DDI_INTR_CLAIMED; 599 } 600 ecrreg = ecrreg >> 1; 601 i++; 602 } 603 604 /* 605 * Clear the interrupt. Note: Depending on the type of 606 * event (interrupt or MSI), we need to use a different 607 * mask to clear the event. In the case of MSI, the bit 608 * to clear corresponds to the MSI number, and for legacy 609 * interrupts the bit corresponds to the value in 'inta_pin'. 610 */ 611 if (state->ts_intr_type_chosen == DDI_INTR_TYPE_MSI) { 612 int_mask = ((uint64_t)1 << 0); 613 } else { 614 int_mask = ((uint64_t)1 << state->ts_adapter.inta_pin); 615 } 616 ddi_put64(state->ts_reg_cmdhdl, clr_int, int_mask); 617 618 /* Reread the ECR register */ 619 ecrreg = ddi_get64(state->ts_reg_cmdhdl, ecr); 620 621 } while (ecrreg != 0x0); 622 623 TAVOR_TNF_EXIT(tavor_isr); 624 return (status); 625 } 626 627 628 /* 629 * tavor_eq_doorbell 630 * Context: Only called from interrupt context 631 */ 632 void 633 tavor_eq_doorbell(tavor_state_t *state, uint32_t eq_cmd, uint32_t eqn, 634 uint32_t eq_param) 635 { 636 uint64_t doorbell = 0; 637 638 /* Build the doorbell from the parameters */ 639 doorbell = ((uint64_t)eq_cmd << TAVOR_EQDB_CMD_SHIFT) | 640 ((uint64_t)eqn << TAVOR_EQDB_EQN_SHIFT) | eq_param; 641 642 TNF_PROBE_1_DEBUG(tavor_eq_doorbell, TAVOR_TNF_TRACE, "", 643 tnf_ulong, doorbell, doorbell); 644 645 /* Write the doorbell to UAR */ 646 TAVOR_UAR_DOORBELL(state, (uint64_t *)&state->ts_uar->eq, 647 doorbell); 648 } 649 650 /* 651 * tavor_eq_poll 652 * Context: Only called from interrupt context (and during panic) 653 */ 654 static void 655 tavor_eq_poll(tavor_state_t *state, tavor_eqhdl_t eq) 656 { 657 uint64_t *clr_ecr; 658 tavor_hw_eqe_t *eqe; 659 uint64_t ecr_mask; 660 uint32_t cons_indx, wrap_around_mask; 661 int (*eqfunction)(tavor_state_t *state, tavor_eqhdl_t eq, 662 tavor_hw_eqe_t *eqe); 663 664 TAVOR_TNF_ENTER(tavor_eq_poll); 665 666 /* Find the pointer to the clr_ECR register */ 667 clr_ecr = state->ts_cmd_regs.clr_ecr; 668 669 /* 670 * Check for Local Catastrophic Error If we have this kind of error, 671 * then we don't need to do anything else here, as this kind of 672 * catastrophic error is handled separately. So we call the 673 * catastrophic handler, clear the ECR and then return. 674 */ 675 if (eq->eq_evttypemask == TAVOR_EVT_MSK_LOCAL_CAT_ERROR) { 676 /* 677 * Call Catastrophic Error handler 678 */ 679 tavor_eq_catastrophic(state); 680 681 /* 682 * Clear the ECR. Specifically, clear the bit corresponding 683 * to the event queue just processed. 684 */ 685 ecr_mask = ((uint64_t)1 << eq->eq_eqnum); 686 ddi_put64(state->ts_reg_cmdhdl, clr_ecr, ecr_mask); 687 688 TAVOR_TNF_EXIT(tavor_eq_poll); 689 return; 690 } 691 692 /* Get the consumer pointer index */ 693 cons_indx = eq->eq_consindx; 694 695 /* 696 * Calculate the wrap around mask. Note: This operation only works 697 * because all Tavor event queues have power-of-2 sizes 698 */ 699 wrap_around_mask = (eq->eq_bufsz - 1); 700 701 /* Calculate the pointer to the first EQ entry */ 702 eqe = &eq->eq_buf[cons_indx]; 703 704 /* 705 * Sync the current EQE to read 706 * We need to force a ddi_dma_sync() here (independent of how the 707 * EQ was mapped) because it is possible for us to receive the 708 * interrupt, do a read of the ECR, and have each of these 709 * operations complete successfully even though the hardware's DMA 710 * to the EQ has not yet completed. 711 */ 712 tavor_eqe_sync(eq, eqe, DDI_DMA_SYNC_FORCPU, TAVOR_EQ_SYNC_FORCE); 713 714 /* 715 * Pull the handler function for this EQ from the Tavor Event Queue 716 * handle 717 */ 718 eqfunction = eq->eq_func; 719 720 /* 721 * Keep pulling entries from the EQ until we find an entry owner by 722 * the hardware. As long as there the EQE's owned by SW, process 723 * each entry by calling its handler function and updating the EQ 724 * consumer index. 725 */ 726 do { 727 while (TAVOR_EQE_OWNER_IS_SW(eq, eqe)) { 728 /* 729 * Call the EQ handler function. But only call if we 730 * are not in polled I/O mode (i.e. not processing 731 * because of a system panic). Note: We don't call 732 * the EQ handling functions from a system panic 733 * because we are primarily concerned only with 734 * ensuring that the event queues do not overflow (or, 735 * more specifically, the event queue associated with 736 * the CQ that is being used in the sync/dump process). 737 * Also, we don't want to make any upcalls (to the 738 * IBTF) because we can't guarantee when/if those 739 * calls would ever return. And, if we're in panic, 740 * then we reached here through a PollCQ() call (from 741 * tavor_cq_poll()), and we need to ensure that we 742 * successfully return any work completions to the 743 * caller. 744 */ 745 if (ddi_in_panic() == 0) { 746 eqfunction(state, eq, eqe); 747 } 748 749 /* Reset entry to hardware ownership */ 750 TAVOR_EQE_OWNER_SET_HW(eq, eqe); 751 752 /* Sync the current EQE for device */ 753 tavor_eqe_sync(eq, eqe, DDI_DMA_SYNC_FORDEV, 754 TAVOR_EQ_SYNC_NORMAL); 755 756 /* Increment the consumer index */ 757 cons_indx = (cons_indx + 1) & wrap_around_mask; 758 759 /* Update the pointer to the next EQ entry */ 760 eqe = &eq->eq_buf[cons_indx]; 761 762 /* Sync the next EQE to read */ 763 tavor_eqe_sync(eq, eqe, DDI_DMA_SYNC_FORCPU, 764 TAVOR_EQ_SYNC_NORMAL); 765 } 766 767 /* 768 * Clear the ECR. Specifically, clear the bit corresponding 769 * to the event queue just processed. 770 */ 771 ecr_mask = ((uint64_t)1 << eq->eq_eqnum); 772 ddi_put64(state->ts_reg_cmdhdl, clr_ecr, ecr_mask); 773 774 /* Write an EQ doorbell to update the consumer index */ 775 eq->eq_consindx = cons_indx; 776 tavor_eq_doorbell(state, TAVOR_EQDB_SET_CONSINDX, eq->eq_eqnum, 777 cons_indx); 778 779 /* Write another EQ doorbell to rearm */ 780 tavor_eq_doorbell(state, TAVOR_EQDB_REARM_EQ, eq->eq_eqnum, 0); 781 782 /* 783 * NOTE: Due to the nature of Mellanox hardware, we do not have 784 * to do an explicit PIO read to ensure that the doorbell write 785 * has been flushed to the hardware. There is state encoded in 786 * the doorbell information we write which makes this 787 * unnecessary. We can be assured that if an event needs to be 788 * generated, the hardware will make sure that it is, solving 789 * the possible race condition. 790 */ 791 792 /* Sync the next EQE to read */ 793 tavor_eqe_sync(eq, eqe, DDI_DMA_SYNC_FORCPU, 794 TAVOR_EQ_SYNC_NORMAL); 795 796 } while (TAVOR_EQE_OWNER_IS_SW(eq, eqe)); 797 798 TAVOR_TNF_EXIT(tavor_eq_poll); 799 } 800 801 802 /* 803 * tavor_eq_catastrophic 804 * Context: Only called from interrupt context (and during panic) 805 */ 806 static void 807 tavor_eq_catastrophic(tavor_state_t *state) 808 { 809 ibt_async_code_t type; 810 ibc_async_event_t event; 811 uint32_t *base_addr; 812 uint32_t buf_size; 813 uint32_t word; 814 uint8_t err_type; 815 uint32_t err_buf; 816 int i; 817 818 TAVOR_TNF_ENTER(tavor_eq_catastrophic); 819 820 bzero(&event, sizeof (ibc_async_event_t)); 821 822 base_addr = (uint32_t *)(uintptr_t)( 823 (uintptr_t)state->ts_reg_cmd_baseaddr + 824 state->ts_fw.error_buf_addr); 825 buf_size = state->ts_fw.error_buf_sz; 826 827 word = ddi_get32(state->ts_reg_cmdhdl, base_addr); 828 829 err_type = (word & 0xFF000000) >> 24; 830 type = IBT_ERROR_LOCAL_CATASTROPHIC; 831 832 switch (err_type) { 833 case TAVOR_CATASTROPHIC_INTERNAL_ERROR: 834 cmn_err(CE_WARN, "Catastrophic Internal Error: 0x%02x", 835 err_type); 836 837 break; 838 839 case TAVOR_CATASTROPHIC_UPLINK_BUS_ERROR: 840 cmn_err(CE_WARN, "Catastrophic Uplink Bus Error: 0x%02x", 841 err_type); 842 843 break; 844 845 case TAVOR_CATASTROPHIC_DDR_DATA_ERROR: 846 cmn_err(CE_WARN, "Catastrophic DDR Data Error: 0x%02x", 847 err_type); 848 849 break; 850 851 case TAVOR_CATASTROPHIC_INTERNAL_PARITY_ERROR: 852 cmn_err(CE_WARN, "Catastrophic Internal Parity Error: 0x%02x", 853 err_type); 854 855 break; 856 857 default: 858 /* Unknown type of Catastrophic error */ 859 cmn_err(CE_WARN, "Catastrophic Unknown Error: 0x%02x", 860 err_type); 861 862 break; 863 } 864 865 /* 866 * Read in the catastrophic error buffer from the hardware, printing 867 * only to the log file only 868 */ 869 for (i = 0; i < buf_size; i += 4) { 870 base_addr = (uint32_t *)((uintptr_t)(state->ts_reg_cmd_baseaddr 871 + state->ts_fw.error_buf_addr + (i * 4))); 872 err_buf = ddi_get32(state->ts_reg_cmdhdl, base_addr); 873 cmn_err(CE_WARN, "catastrophic_error[%02x]: %08X", i, err_buf); 874 } 875 876 /* 877 * We also call the IBTF here to inform it of the catastrophic error. 878 * Note: Since no event information (i.e. QP handles, CQ handles, 879 * etc.) is necessary, we pass a NULL pointer instead of a pointer to 880 * an empty ibc_async_event_t struct. 881 * 882 * But we also check if "ts_ibtfpriv" is NULL. If it is then it 883 * means that we've have either received this event before we 884 * finished attaching to the IBTF or we've received it while we 885 * are in the process of detaching. 886 */ 887 if (state->ts_ibtfpriv != NULL) { 888 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event); 889 } 890 891 TAVOR_TNF_EXIT(tavor_eq_catastrophic); 892 } 893 894 895 /* 896 * tavor_eq_alloc() 897 * Context: Only called from attach() path context 898 */ 899 static int 900 tavor_eq_alloc(tavor_state_t *state, uint32_t log_eq_size, uint_t intr, 901 tavor_eqhdl_t *eqhdl) 902 { 903 tavor_rsrc_t *eqc, *rsrc; 904 tavor_hw_eqc_t eqc_entry; 905 tavor_eqhdl_t eq; 906 ibt_mr_attr_t mr_attr; 907 tavor_mr_options_t op; 908 tavor_pdhdl_t pd; 909 tavor_mrhdl_t mr; 910 tavor_hw_eqe_t *buf; 911 uint64_t addr; 912 uint32_t lkey; 913 uint_t dma_xfer_mode; 914 int status, i; 915 char *errormsg; 916 917 TAVOR_TNF_ENTER(tavor_eq_alloc); 918 919 /* Use the internal protection domain (PD) for setting up EQs */ 920 pd = state->ts_pdhdl_internal; 921 922 /* Increment the reference count on the protection domain (PD) */ 923 tavor_pd_refcnt_inc(pd); 924 925 /* 926 * Allocate an EQ context entry. This will be filled in with all 927 * the necessary parameters to define the Event Queue. And then 928 * ownership will be passed to the hardware in the final step 929 * below. If we fail here, we must undo the protection domain 930 * reference count. 931 */ 932 status = tavor_rsrc_alloc(state, TAVOR_EQC, 1, TAVOR_SLEEP, &eqc); 933 if (status != DDI_SUCCESS) { 934 /* Set "status" and "errormsg" and goto failure */ 935 TAVOR_TNF_FAIL(DDI_FAILURE, "failed EQ context"); 936 goto eqalloc_fail1; 937 } 938 939 /* 940 * Allocate the software structure for tracking the event queue (i.e. 941 * the Tavor Event Queue handle). If we fail here, we must undo the 942 * protection domain reference count and the previous resource 943 * allocation. 944 */ 945 status = tavor_rsrc_alloc(state, TAVOR_EQHDL, 1, TAVOR_SLEEP, &rsrc); 946 if (status != DDI_SUCCESS) { 947 /* Set "status" and "errormsg" and goto failure */ 948 TAVOR_TNF_FAIL(DDI_FAILURE, "failed EQ handler"); 949 goto eqalloc_fail2; 950 } 951 eq = (tavor_eqhdl_t)rsrc->tr_addr; 952 953 /* 954 * Allocate the memory for Event Queue. Note: Although we use the 955 * common queue allocation routine, we always specify 956 * TAVOR_QUEUE_LOCATION_NORMAL (i.e. EQ located in system memory) 957 * because it would be inefficient to have EQs located in DDR memory. 958 * This is primarily because EQs are read from (by software) more 959 * than they are written to. Also note that, unlike Tavor QP work 960 * queues, event queues do not have the same strict alignment 961 * requirements. It is sufficient for the EQ memory to be both 962 * aligned to and bound to addresses which are a multiple of EQE size. 963 */ 964 eq->eq_eqinfo.qa_size = (1 << log_eq_size) * sizeof (tavor_hw_eqe_t); 965 eq->eq_eqinfo.qa_alloc_align = sizeof (tavor_hw_eqe_t); 966 eq->eq_eqinfo.qa_bind_align = sizeof (tavor_hw_eqe_t); 967 eq->eq_eqinfo.qa_location = TAVOR_QUEUE_LOCATION_NORMAL; 968 status = tavor_queue_alloc(state, &eq->eq_eqinfo, TAVOR_SLEEP); 969 if (status != DDI_SUCCESS) { 970 /* Set "status" and "errormsg" and goto failure */ 971 TAVOR_TNF_FAIL(DDI_FAILURE, "failed event queue"); 972 goto eqalloc_fail3; 973 } 974 buf = (tavor_hw_eqe_t *)eq->eq_eqinfo.qa_buf_aligned; 975 976 /* 977 * Initialize each of the Event Queue Entries (EQE) by setting their 978 * ownership to hardware ("owner" bit set to HW). This is in 979 * preparation for the final transfer of ownership (below) of the 980 * EQ context itself. 981 */ 982 for (i = 0; i < (1 << log_eq_size); i++) { 983 TAVOR_EQE_OWNER_SET_HW(eq, &buf[i]); 984 } 985 986 /* 987 * Register the memory for the EQ. The memory for the EQ must 988 * be registered in the Tavor TPT tables. This gives us the LKey 989 * to specify in the EQ context below. 990 * 991 * Because we are in the attach path we use NOSLEEP here so that we 992 * SPIN in the HCR since the event queues are not setup yet, and we 993 * cannot NOSPIN at this point in time. 994 */ 995 mr_attr.mr_vaddr = (uint64_t)(uintptr_t)buf; 996 mr_attr.mr_len = eq->eq_eqinfo.qa_size; 997 mr_attr.mr_as = NULL; 998 mr_attr.mr_flags = IBT_MR_NOSLEEP | IBT_MR_ENABLE_LOCAL_WRITE; 999 dma_xfer_mode = state->ts_cfg_profile->cp_streaming_consistent; 1000 if (dma_xfer_mode == DDI_DMA_STREAMING) { 1001 mr_attr.mr_flags |= IBT_MR_NONCOHERENT; 1002 } 1003 op.mro_bind_type = state->ts_cfg_profile->cp_iommu_bypass; 1004 op.mro_bind_dmahdl = eq->eq_eqinfo.qa_dmahdl; 1005 op.mro_bind_override_addr = 0; 1006 status = tavor_mr_register(state, pd, &mr_attr, &mr, &op); 1007 if (status != DDI_SUCCESS) { 1008 /* Set "status" and "errormsg" and goto failure */ 1009 TAVOR_TNF_FAIL(DDI_FAILURE, "failed register mr"); 1010 goto eqalloc_fail4; 1011 } 1012 addr = mr->mr_bindinfo.bi_addr; 1013 lkey = mr->mr_lkey; 1014 1015 /* Determine if later ddi_dma_sync will be necessary */ 1016 eq->eq_sync = TAVOR_EQ_IS_SYNC_REQ(state, eq->eq_eqinfo); 1017 1018 /* Sync entire EQ for use by the hardware (if necessary) */ 1019 if (eq->eq_sync) { 1020 (void) ddi_dma_sync(mr->mr_bindinfo.bi_dmahdl, 0, 1021 eq->eq_eqinfo.qa_size, DDI_DMA_SYNC_FORDEV); 1022 } 1023 1024 /* 1025 * Fill in the EQC entry. This is the final step before passing 1026 * ownership of the EQC entry to the Tavor hardware. We use all of 1027 * the information collected/calculated above to fill in the 1028 * requisite portions of the EQC. Note: We create all EQs in the 1029 * "fired" state. We will arm them later (after our interrupt 1030 * routine had been registered.) 1031 */ 1032 bzero(&eqc_entry, sizeof (tavor_hw_eqc_t)); 1033 eqc_entry.owner = TAVOR_HW_OWNER; 1034 eqc_entry.xlat = TAVOR_VA2PA_XLAT_ENABLED; 1035 eqc_entry.state = TAVOR_EQ_FIRED; 1036 eqc_entry.start_addr_h = (addr >> 32); 1037 eqc_entry.start_addr_l = (addr & 0xFFFFFFFF); 1038 eqc_entry.log_eq_sz = log_eq_size; 1039 eqc_entry.usr_page = 0; 1040 eqc_entry.pd = pd->pd_pdnum; 1041 eqc_entry.intr = intr; 1042 eqc_entry.lkey = lkey; 1043 1044 /* 1045 * Write the EQC entry to hardware. Lastly, we pass ownership of 1046 * the entry to the hardware (using the Tavor SW2HW_EQ firmware 1047 * command). Note: in general, this operation shouldn't fail. But 1048 * if it does, we have to undo everything we've done above before 1049 * returning error. 1050 */ 1051 status = tavor_cmn_ownership_cmd_post(state, SW2HW_EQ, &eqc_entry, 1052 sizeof (tavor_hw_eqc_t), eqc->tr_indx, TAVOR_CMD_NOSLEEP_SPIN); 1053 if (status != TAVOR_CMD_SUCCESS) { 1054 cmn_err(CE_CONT, "Tavor: SW2HW_EQ command failed: %08x\n", 1055 status); 1056 TNF_PROBE_1(tavor_eq_alloc_sw2hw_eq_cmd_fail, 1057 TAVOR_TNF_ERROR, "", tnf_uint, status, status); 1058 /* Set "status" and "errormsg" and goto failure */ 1059 TAVOR_TNF_FAIL(ibc_get_ci_failure(0), "tavor SW2HW_EQ command"); 1060 goto eqalloc_fail5; 1061 } 1062 1063 /* 1064 * Fill in the rest of the Tavor Event Queue handle. Having 1065 * successfully transferred ownership of the EQC, we can update the 1066 * following fields for use in further operations on the EQ. 1067 */ 1068 eq->eq_eqcrsrcp = eqc; 1069 eq->eq_rsrcp = rsrc; 1070 eq->eq_consindx = 0; 1071 eq->eq_eqnum = eqc->tr_indx; 1072 eq->eq_buf = buf; 1073 eq->eq_bufsz = (1 << log_eq_size); 1074 eq->eq_mrhdl = mr; 1075 *eqhdl = eq; 1076 1077 TAVOR_TNF_EXIT(tavor_eq_alloc); 1078 return (DDI_SUCCESS); 1079 1080 /* 1081 * The following is cleanup for all possible failure cases in this routine 1082 */ 1083 eqalloc_fail5: 1084 if (tavor_mr_deregister(state, &mr, TAVOR_MR_DEREG_ALL, 1085 TAVOR_NOSLEEP) != DDI_SUCCESS) { 1086 TAVOR_WARNING(state, "failed to deregister EQ memory"); 1087 } 1088 eqalloc_fail4: 1089 tavor_queue_free(state, &eq->eq_eqinfo); 1090 eqalloc_fail3: 1091 tavor_rsrc_free(state, &rsrc); 1092 eqalloc_fail2: 1093 tavor_rsrc_free(state, &eqc); 1094 eqalloc_fail1: 1095 tavor_pd_refcnt_dec(pd); 1096 eqalloc_fail: 1097 TNF_PROBE_1(tavor_eq_alloc_fail, TAVOR_TNF_ERROR, "", 1098 tnf_string, msg, errormsg); 1099 TAVOR_TNF_EXIT(tavor_eq_alloc); 1100 return (status); 1101 } 1102 1103 1104 /* 1105 * tavor_eq_free() 1106 * Context: Only called from attach() and/or detach() path contexts 1107 */ 1108 static int 1109 tavor_eq_free(tavor_state_t *state, tavor_eqhdl_t *eqhdl) 1110 { 1111 tavor_rsrc_t *eqc, *rsrc; 1112 tavor_hw_eqc_t eqc_entry; 1113 tavor_pdhdl_t pd; 1114 tavor_mrhdl_t mr; 1115 tavor_eqhdl_t eq; 1116 uint32_t eqnum; 1117 int status; 1118 1119 TAVOR_TNF_ENTER(tavor_eq_free); 1120 1121 /* 1122 * Pull all the necessary information from the Tavor Event Queue 1123 * handle. This is necessary here because the resource for the 1124 * EQ handle is going to be freed up as part of this operation. 1125 */ 1126 eq = *eqhdl; 1127 eqc = eq->eq_eqcrsrcp; 1128 rsrc = eq->eq_rsrcp; 1129 pd = state->ts_pdhdl_internal; 1130 mr = eq->eq_mrhdl; 1131 eqnum = eq->eq_eqnum; 1132 1133 /* 1134 * Reclaim EQC entry from hardware (using the Tavor HW2SW_EQ 1135 * firmware command). If the ownership transfer fails for any reason, 1136 * then it is an indication that something (either in HW or SW) has 1137 * gone seriously wrong. 1138 */ 1139 status = tavor_cmn_ownership_cmd_post(state, HW2SW_EQ, &eqc_entry, 1140 sizeof (tavor_hw_eqc_t), eqnum, TAVOR_CMD_NOSLEEP_SPIN); 1141 if (status != TAVOR_CMD_SUCCESS) { 1142 TAVOR_WARNING(state, "failed to reclaim EQC ownership"); 1143 cmn_err(CE_CONT, "Tavor: HW2SW_EQ command failed: %08x\n", 1144 status); 1145 TNF_PROBE_1(tavor_eq_free_hw2sw_eq_cmd_fail, 1146 TAVOR_TNF_ERROR, "", tnf_uint, status, status); 1147 TAVOR_TNF_EXIT(tavor_eq_free); 1148 return (DDI_FAILURE); 1149 } 1150 1151 /* 1152 * Deregister the memory for the Event Queue. If this fails 1153 * for any reason, then it is an indication that something (either 1154 * in HW or SW) has gone seriously wrong. So we print a warning 1155 * message and continue. 1156 */ 1157 status = tavor_mr_deregister(state, &mr, TAVOR_MR_DEREG_ALL, 1158 TAVOR_NOSLEEP); 1159 if (status != DDI_SUCCESS) { 1160 TAVOR_WARNING(state, "failed to deregister EQ memory"); 1161 TNF_PROBE_0(tavor_eq_free_dereg_mr_fail, TAVOR_TNF_ERROR, ""); 1162 TAVOR_TNF_EXIT(tavor_eq_free); 1163 } 1164 1165 /* Free the memory for the EQ */ 1166 tavor_queue_free(state, &eq->eq_eqinfo); 1167 1168 /* Free the Tavor Event Queue handle */ 1169 tavor_rsrc_free(state, &rsrc); 1170 1171 /* Free up the EQC entry resource */ 1172 tavor_rsrc_free(state, &eqc); 1173 1174 /* Decrement the reference count on the protection domain (PD) */ 1175 tavor_pd_refcnt_dec(pd); 1176 1177 /* Set the eqhdl pointer to NULL and return success */ 1178 *eqhdl = NULL; 1179 1180 TAVOR_TNF_EXIT(tavor_eq_free); 1181 return (DDI_SUCCESS); 1182 } 1183 1184 1185 /* 1186 * tavor_eq_handler_init 1187 * Context: Only called from attach() path context 1188 */ 1189 static int 1190 tavor_eq_handler_init(tavor_state_t *state, tavor_eqhdl_t eq, 1191 uint_t evt_type_mask, int (*eq_func)(tavor_state_t *state, 1192 tavor_eqhdl_t eq, tavor_hw_eqe_t *eqe)) 1193 { 1194 int status; 1195 1196 TAVOR_TNF_ENTER(tavor_eq_handler_init); 1197 1198 /* 1199 * Save away the EQ handler function and the event type mask. These 1200 * will be used later during interrupt and event queue processing. 1201 */ 1202 eq->eq_func = eq_func; 1203 eq->eq_evttypemask = evt_type_mask; 1204 1205 /* 1206 * Map the EQ to a specific class of event (or events) depending 1207 * on the mask value passed in. The TAVOR_EVT_NO_MASK means not 1208 * to attempt associating the EQ with any specific class of event. 1209 * This is particularly useful when initializing the events queues 1210 * used for CQ events. The mapping is done using the Tavor MAP_EQ 1211 * firmware command. Note: This command should not, in general, fail. 1212 * If it does, then something (probably HW related) has gone seriously 1213 * wrong. 1214 */ 1215 if (evt_type_mask != TAVOR_EVT_NO_MASK) { 1216 status = tavor_map_eq_cmd_post(state, 1217 TAVOR_CMD_MAP_EQ_EVT_MAP, eq->eq_eqnum, evt_type_mask, 1218 TAVOR_CMD_NOSLEEP_SPIN); 1219 if (status != TAVOR_CMD_SUCCESS) { 1220 cmn_err(CE_CONT, "Tavor: MAP_EQ command failed: " 1221 "%08x\n", status); 1222 TNF_PROBE_1(tavor_eq_handler_init_map_eq_cmd_fail, 1223 TAVOR_TNF_ERROR, "", tnf_uint, status, status); 1224 TAVOR_TNF_EXIT(tavor_eq_handler_init); 1225 return (DDI_FAILURE); 1226 } 1227 } 1228 1229 TAVOR_TNF_EXIT(tavor_eq_handler_init); 1230 return (DDI_SUCCESS); 1231 } 1232 1233 1234 /* 1235 * tavor_eq_handler_fini 1236 * Context: Only called from attach() and/or detach() path contexts 1237 */ 1238 static int 1239 tavor_eq_handler_fini(tavor_state_t *state, tavor_eqhdl_t eq) 1240 { 1241 int status; 1242 1243 TAVOR_TNF_ENTER(tavor_eq_handler_fini); 1244 1245 /* 1246 * Unmap the EQ from the event class to which it had been previously 1247 * mapped. The unmapping is done using the Tavor MAP_EQ (in much 1248 * the same way that the initial mapping was done). The difference, 1249 * however, is in the TAVOR_EQ_EVT_UNMAP flag that is passed to the 1250 * MAP_EQ firmware command. The TAVOR_EVT_NO_MASK (which may have 1251 * been passed in at init time) still means that no association has 1252 * been made between the EQ and any specific class of event (and, 1253 * hence, no unmapping is necessary). Note: This command should not, 1254 * in general, fail. If it does, then something (probably HW related) 1255 * has gone seriously wrong. 1256 */ 1257 if (eq->eq_evttypemask != TAVOR_EVT_NO_MASK) { 1258 status = tavor_map_eq_cmd_post(state, 1259 TAVOR_CMD_MAP_EQ_EVT_UNMAP, eq->eq_eqnum, 1260 eq->eq_evttypemask, TAVOR_CMD_NOSLEEP_SPIN); 1261 if (status != TAVOR_CMD_SUCCESS) { 1262 cmn_err(CE_CONT, "Tavor: MAP_EQ command failed: " 1263 "%08x\n", status); 1264 TNF_PROBE_1(tavor_eq_handler_fini_map_eq_cmd_fail, 1265 TAVOR_TNF_ERROR, "", tnf_uint, status, status); 1266 TAVOR_TNF_EXIT(tavor_eq_handler_fini); 1267 return (DDI_FAILURE); 1268 } 1269 } 1270 1271 TAVOR_TNF_EXIT(tavor_eq_handler_fini); 1272 return (DDI_SUCCESS); 1273 } 1274 1275 1276 /* 1277 * tavor_eqe_sync() 1278 * Context: Can be called from interrupt or base context. 1279 * 1280 * Typically, this routine does nothing unless the EQ memory is 1281 * mapped as DDI_DMA_STREAMING. However, there is a condition where 1282 * ddi_dma_sync() is necessary even if the memory was mapped in 1283 * consistent mode. The "force_sync" parameter is used here to force 1284 * the call to ddi_dma_sync() independent of how the EQ memory was 1285 * mapped. 1286 */ 1287 static void 1288 tavor_eqe_sync(tavor_eqhdl_t eq, tavor_hw_eqe_t *eqe, uint_t flag, 1289 uint_t force_sync) 1290 { 1291 ddi_dma_handle_t dmahdl; 1292 off_t offset; 1293 int status; 1294 1295 TAVOR_TNF_ENTER(tavor_eqe_sync); 1296 1297 /* Determine if EQ needs to be synced or not */ 1298 if ((eq->eq_sync == 0) && (force_sync == TAVOR_EQ_SYNC_NORMAL)) { 1299 TAVOR_TNF_EXIT(tavor_eqe_sync); 1300 return; 1301 } 1302 1303 /* Get the DMA handle from EQ context */ 1304 dmahdl = eq->eq_mrhdl->mr_bindinfo.bi_dmahdl; 1305 1306 /* Calculate offset of next EQE */ 1307 offset = (off_t)((uintptr_t)eqe - (uintptr_t)&eq->eq_buf[0]); 1308 status = ddi_dma_sync(dmahdl, offset, sizeof (tavor_hw_eqe_t), flag); 1309 if (status != DDI_SUCCESS) { 1310 TNF_PROBE_0(tavor_eqe_sync_getnextentry_fail, 1311 TAVOR_TNF_ERROR, ""); 1312 TAVOR_TNF_EXIT(tavor_eqe_sync); 1313 return; 1314 } 1315 1316 TAVOR_TNF_EXIT(tavor_eqe_sync); 1317 } 1318 1319 1320 /* 1321 * tavor_port_state_change_handler() 1322 * Context: Only called from interrupt context 1323 */ 1324 static int 1325 tavor_port_state_change_handler(tavor_state_t *state, tavor_eqhdl_t eq, 1326 tavor_hw_eqe_t *eqe) 1327 { 1328 ibc_async_event_t event; 1329 ibt_async_code_t type; 1330 uint_t port, subtype; 1331 uint_t eqe_evttype; 1332 char link_msg[24]; 1333 1334 TAVOR_TNF_ENTER(tavor_port_state_change_handler); 1335 1336 eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe); 1337 1338 ASSERT(eqe_evttype == TAVOR_EVT_PORT_STATE_CHANGE || 1339 eqe_evttype == TAVOR_EVT_EQ_OVERFLOW); 1340 1341 if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) { 1342 TNF_PROBE_0(tavor_port_state_change_eq_overflow_condition, 1343 TAVOR_TNF_ERROR, ""); 1344 tavor_eq_overflow_handler(state, eq, eqe); 1345 1346 TAVOR_TNF_EXIT(tavor_port_state_change_handler); 1347 return (DDI_FAILURE); 1348 } 1349 1350 /* 1351 * Depending on the type of Port State Change event, pass the 1352 * appropriate asynch event to the IBTF. 1353 */ 1354 port = TAVOR_EQE_PORTNUM_GET(eq, eqe); 1355 1356 /* Check for valid port number in event */ 1357 if ((port == 0) || (port > state->ts_cfg_profile->cp_num_ports)) { 1358 TAVOR_WARNING(state, "Unexpected port number in port state " 1359 "change event"); 1360 cmn_err(CE_CONT, " Port number: %02x\n", port); 1361 TAVOR_TNF_EXIT(tavor_port_state_change_handler); 1362 return (DDI_FAILURE); 1363 } 1364 1365 subtype = TAVOR_EQE_EVTSUBTYPE_GET(eq, eqe); 1366 if (subtype == TAVOR_PORT_LINK_ACTIVE) { 1367 event.ev_port = port; 1368 type = IBT_EVENT_PORT_UP; 1369 1370 (void) snprintf(link_msg, 23, "port %d up", port); 1371 ddi_dev_report_fault(state->ts_dip, DDI_SERVICE_RESTORED, 1372 DDI_EXTERNAL_FAULT, link_msg); 1373 } else if (subtype == TAVOR_PORT_LINK_DOWN) { 1374 event.ev_port = port; 1375 type = IBT_ERROR_PORT_DOWN; 1376 1377 (void) snprintf(link_msg, 23, "port %d down", port); 1378 ddi_dev_report_fault(state->ts_dip, DDI_SERVICE_LOST, 1379 DDI_EXTERNAL_FAULT, link_msg); 1380 } else { 1381 TAVOR_WARNING(state, "Unexpected subtype in port state change " 1382 "event"); 1383 cmn_err(CE_CONT, " Event type: %02x, subtype: %02x\n", 1384 TAVOR_EQE_EVTTYPE_GET(eq, eqe), subtype); 1385 TAVOR_TNF_EXIT(tavor_port_state_change_handler); 1386 return (DDI_FAILURE); 1387 } 1388 1389 /* 1390 * Deliver the event to the IBTF. Note: If "ts_ibtfpriv" is NULL, 1391 * then we have either received this event before we finished 1392 * attaching to the IBTF or we've received it while we are in the 1393 * process of detaching. 1394 */ 1395 if (state->ts_ibtfpriv != NULL) { 1396 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event); 1397 } 1398 1399 TAVOR_TNF_EXIT(tavor_port_state_change_handler); 1400 return (DDI_SUCCESS); 1401 } 1402 1403 1404 /* 1405 * tavor_comm_estbl_handler() 1406 * Context: Only called from interrupt context 1407 */ 1408 static int 1409 tavor_comm_estbl_handler(tavor_state_t *state, tavor_eqhdl_t eq, 1410 tavor_hw_eqe_t *eqe) 1411 { 1412 tavor_qphdl_t qp; 1413 uint_t qpnum; 1414 ibc_async_event_t event; 1415 ibt_async_code_t type; 1416 uint_t eqe_evttype; 1417 1418 TAVOR_TNF_ENTER(tavor_comm_estbl_handler); 1419 1420 eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe); 1421 1422 ASSERT(eqe_evttype == TAVOR_EVT_COMM_ESTABLISHED || 1423 eqe_evttype == TAVOR_EVT_EQ_OVERFLOW); 1424 1425 if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) { 1426 TNF_PROBE_0(tavor_comm_estbl_eq_overflow_condition, 1427 TAVOR_TNF_ERROR, ""); 1428 tavor_eq_overflow_handler(state, eq, eqe); 1429 1430 TAVOR_TNF_EXIT(tavor_comm_estbl_handler); 1431 return (DDI_FAILURE); 1432 } 1433 1434 /* Get the QP handle from QP number in event descriptor */ 1435 qpnum = TAVOR_EQE_QPNUM_GET(eq, eqe); 1436 qp = tavor_qphdl_from_qpnum(state, qpnum); 1437 1438 /* 1439 * If the QP handle is NULL, this is probably an indication 1440 * that the QP has been freed already. In which case, we 1441 * should not deliver this event. 1442 * 1443 * We also check that the QP number in the handle is the 1444 * same as the QP number in the event queue entry. This 1445 * extra check allows us to handle the case where a QP was 1446 * freed and then allocated again in the time it took to 1447 * handle the event queue processing. By constantly incrementing 1448 * the non-constrained portion of the QP number every time 1449 * a new QP is allocated, we mitigate (somewhat) the chance 1450 * that a stale event could be passed to the client's QP 1451 * handler. 1452 * 1453 * Lastly, we check if "ts_ibtfpriv" is NULL. If it is then it 1454 * means that we've have either received this event before we 1455 * finished attaching to the IBTF or we've received it while we 1456 * are in the process of detaching. 1457 */ 1458 if ((qp != NULL) && (qp->qp_qpnum == qpnum) && 1459 (state->ts_ibtfpriv != NULL)) { 1460 event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg; 1461 type = IBT_EVENT_COM_EST_QP; 1462 1463 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event); 1464 } else { 1465 TNF_PROBE_2(tavor_comm_estbl_handler_dropped_event, 1466 TAVOR_TNF_ERROR, "", tnf_uint, ev_qpnum, qpnum, 1467 tnf_uint, hdl_qpnum, qpnum); 1468 } 1469 1470 TAVOR_TNF_EXIT(tavor_comm_estbl_handler); 1471 return (DDI_SUCCESS); 1472 } 1473 1474 1475 /* 1476 * tavor_local_wq_cat_err_handler() 1477 * Context: Only called from interrupt context 1478 */ 1479 static int 1480 tavor_local_wq_cat_err_handler(tavor_state_t *state, tavor_eqhdl_t eq, 1481 tavor_hw_eqe_t *eqe) 1482 { 1483 tavor_qphdl_t qp; 1484 uint_t qpnum; 1485 ibc_async_event_t event; 1486 ibt_async_code_t type; 1487 uint_t eqe_evttype; 1488 1489 TAVOR_TNF_ENTER(tavor_local_wq_cat_err_handler); 1490 1491 eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe); 1492 1493 ASSERT(eqe_evttype == TAVOR_EVT_LOCAL_WQ_CAT_ERROR || 1494 eqe_evttype == TAVOR_EVT_EQ_OVERFLOW); 1495 1496 if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) { 1497 TNF_PROBE_0(tavor_local_wq_cat_err_eq_overflow_condition, 1498 TAVOR_TNF_ERROR, ""); 1499 tavor_eq_overflow_handler(state, eq, eqe); 1500 1501 TAVOR_TNF_EXIT(tavor_local_wq_cat_err_handler); 1502 return (DDI_FAILURE); 1503 } 1504 1505 /* Get the QP handle from QP number in event descriptor */ 1506 qpnum = TAVOR_EQE_QPNUM_GET(eq, eqe); 1507 qp = tavor_qphdl_from_qpnum(state, qpnum); 1508 1509 /* 1510 * If the QP handle is NULL, this is probably an indication 1511 * that the QP has been freed already. In which case, we 1512 * should not deliver this event. 1513 * 1514 * We also check that the QP number in the handle is the 1515 * same as the QP number in the event queue entry. This 1516 * extra check allows us to handle the case where a QP was 1517 * freed and then allocated again in the time it took to 1518 * handle the event queue processing. By constantly incrementing 1519 * the non-constrained portion of the QP number every time 1520 * a new QP is allocated, we mitigate (somewhat) the chance 1521 * that a stale event could be passed to the client's QP 1522 * handler. 1523 * 1524 * Lastly, we check if "ts_ibtfpriv" is NULL. If it is then it 1525 * means that we've have either received this event before we 1526 * finished attaching to the IBTF or we've received it while we 1527 * are in the process of detaching. 1528 */ 1529 if ((qp != NULL) && (qp->qp_qpnum == qpnum) && 1530 (state->ts_ibtfpriv != NULL)) { 1531 event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg; 1532 type = IBT_ERROR_CATASTROPHIC_QP; 1533 1534 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event); 1535 } else { 1536 TNF_PROBE_2(tavor_local_wq_cat_err_handler_dropped_event, 1537 TAVOR_TNF_ERROR, "", tnf_uint, ev_qpnum, qpnum, 1538 tnf_uint, hdl_qpnum, qpnum); 1539 } 1540 1541 TAVOR_TNF_EXIT(tavor_local_wq_cat_err_handler); 1542 return (DDI_SUCCESS); 1543 } 1544 1545 1546 /* 1547 * tavor_invreq_local_wq_err_handler() 1548 * Context: Only called from interrupt context 1549 */ 1550 static int 1551 tavor_invreq_local_wq_err_handler(tavor_state_t *state, tavor_eqhdl_t eq, 1552 tavor_hw_eqe_t *eqe) 1553 { 1554 tavor_qphdl_t qp; 1555 uint_t qpnum; 1556 ibc_async_event_t event; 1557 ibt_async_code_t type; 1558 uint_t eqe_evttype; 1559 1560 TAVOR_TNF_ENTER(tavor_invreq_local_wq_err_handler); 1561 1562 eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe); 1563 1564 ASSERT(eqe_evttype == TAVOR_EVT_INV_REQ_LOCAL_WQ_ERROR || 1565 eqe_evttype == TAVOR_EVT_EQ_OVERFLOW); 1566 1567 if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) { 1568 TNF_PROBE_0(tavor_invreq_local_wq_err_eq_overflow_condition, 1569 TAVOR_TNF_ERROR, ""); 1570 tavor_eq_overflow_handler(state, eq, eqe); 1571 1572 TAVOR_TNF_EXIT(tavor_port_state_change_handler); 1573 return (DDI_FAILURE); 1574 } 1575 1576 /* Get the QP handle from QP number in event descriptor */ 1577 qpnum = TAVOR_EQE_QPNUM_GET(eq, eqe); 1578 qp = tavor_qphdl_from_qpnum(state, qpnum); 1579 1580 /* 1581 * If the QP handle is NULL, this is probably an indication 1582 * that the QP has been freed already. In which case, we 1583 * should not deliver this event. 1584 * 1585 * We also check that the QP number in the handle is the 1586 * same as the QP number in the event queue entry. This 1587 * extra check allows us to handle the case where a QP was 1588 * freed and then allocated again in the time it took to 1589 * handle the event queue processing. By constantly incrementing 1590 * the non-constrained portion of the QP number every time 1591 * a new QP is allocated, we mitigate (somewhat) the chance 1592 * that a stale event could be passed to the client's QP 1593 * handler. 1594 * 1595 * Lastly, we check if "ts_ibtfpriv" is NULL. If it is then it 1596 * means that we've have either received this event before we 1597 * finished attaching to the IBTF or we've received it while we 1598 * are in the process of detaching. 1599 */ 1600 if ((qp != NULL) && (qp->qp_qpnum == qpnum) && 1601 (state->ts_ibtfpriv != NULL)) { 1602 event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg; 1603 type = IBT_ERROR_INVALID_REQUEST_QP; 1604 1605 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event); 1606 } else { 1607 TNF_PROBE_2(tavor_invreq_local_wq_err_handler_dropped_event, 1608 TAVOR_TNF_ERROR, "", tnf_uint, ev_qpnum, qpnum, 1609 tnf_uint, hdl_qpnum, qpnum); 1610 } 1611 1612 TAVOR_TNF_EXIT(tavor_invreq_local_wq_err_handler); 1613 return (DDI_SUCCESS); 1614 } 1615 1616 1617 /* 1618 * tavor_local_acc_vio_wq_err_handler() 1619 * Context: Only called from interrupt context 1620 */ 1621 static int 1622 tavor_local_acc_vio_wq_err_handler(tavor_state_t *state, tavor_eqhdl_t eq, 1623 tavor_hw_eqe_t *eqe) 1624 { 1625 tavor_qphdl_t qp; 1626 uint_t qpnum; 1627 ibc_async_event_t event; 1628 ibt_async_code_t type; 1629 uint_t eqe_evttype; 1630 1631 TAVOR_TNF_ENTER(tavor_local_acc_vio_wq_err_handler); 1632 1633 eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe); 1634 1635 ASSERT(eqe_evttype == TAVOR_EVT_LOCAL_ACC_VIO_WQ_ERROR || 1636 eqe_evttype == TAVOR_EVT_EQ_OVERFLOW); 1637 1638 if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) { 1639 TNF_PROBE_0(tavor_local_acc_vio_wq_err_eq_overflow_condition, 1640 TAVOR_TNF_ERROR, ""); 1641 tavor_eq_overflow_handler(state, eq, eqe); 1642 1643 TAVOR_TNF_EXIT(tavor_local_acc_vio_wq_err_handler); 1644 return (DDI_FAILURE); 1645 } 1646 1647 /* Get the QP handle from QP number in event descriptor */ 1648 qpnum = TAVOR_EQE_QPNUM_GET(eq, eqe); 1649 qp = tavor_qphdl_from_qpnum(state, qpnum); 1650 1651 /* 1652 * If the QP handle is NULL, this is probably an indication 1653 * that the QP has been freed already. In which case, we 1654 * should not deliver this event. 1655 * 1656 * We also check that the QP number in the handle is the 1657 * same as the QP number in the event queue entry. This 1658 * extra check allows us to handle the case where a QP was 1659 * freed and then allocated again in the time it took to 1660 * handle the event queue processing. By constantly incrementing 1661 * the non-constrained portion of the QP number every time 1662 * a new QP is allocated, we mitigate (somewhat) the chance 1663 * that a stale event could be passed to the client's QP 1664 * handler. 1665 * 1666 * Lastly, we check if "ts_ibtfpriv" is NULL. If it is then it 1667 * means that we've have either received this event before we 1668 * finished attaching to the IBTF or we've received it while we 1669 * are in the process of detaching. 1670 */ 1671 if ((qp != NULL) && (qp->qp_qpnum == qpnum) && 1672 (state->ts_ibtfpriv != NULL)) { 1673 event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg; 1674 type = IBT_ERROR_ACCESS_VIOLATION_QP; 1675 1676 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event); 1677 } else { 1678 TNF_PROBE_2(tavor_local_acc_vio_wq_err_handler_dropped_event, 1679 TAVOR_TNF_ERROR, "", tnf_uint, ev_qpnum, qpnum, 1680 tnf_uint, hdl_qpnum, qpnum); 1681 } 1682 1683 TAVOR_TNF_EXIT(tavor_local_acc_vio_wq_err_handler); 1684 return (DDI_SUCCESS); 1685 } 1686 1687 1688 /* 1689 * tavor_sendq_drained_handler() 1690 * Context: Only called from interrupt context 1691 */ 1692 static int 1693 tavor_sendq_drained_handler(tavor_state_t *state, tavor_eqhdl_t eq, 1694 tavor_hw_eqe_t *eqe) 1695 { 1696 tavor_qphdl_t qp; 1697 uint_t qpnum; 1698 ibc_async_event_t event; 1699 uint_t forward_sqd_event; 1700 ibt_async_code_t type; 1701 uint_t eqe_evttype; 1702 1703 TAVOR_TNF_ENTER(tavor_sendq_drained_handler); 1704 1705 eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe); 1706 1707 ASSERT(eqe_evttype == TAVOR_EVT_SEND_QUEUE_DRAINED || 1708 eqe_evttype == TAVOR_EVT_EQ_OVERFLOW); 1709 1710 if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) { 1711 TNF_PROBE_0(tavor_sendq_drained_eq_overflow_condition, 1712 TAVOR_TNF_ERROR, ""); 1713 tavor_eq_overflow_handler(state, eq, eqe); 1714 1715 TAVOR_TNF_EXIT(tavor_sendq_drained_handler); 1716 return (DDI_FAILURE); 1717 } 1718 1719 /* Get the QP handle from QP number in event descriptor */ 1720 qpnum = TAVOR_EQE_QPNUM_GET(eq, eqe); 1721 qp = tavor_qphdl_from_qpnum(state, qpnum); 1722 1723 /* 1724 * If the QP handle is NULL, this is probably an indication 1725 * that the QP has been freed already. In which case, we 1726 * should not deliver this event. 1727 * 1728 * We also check that the QP number in the handle is the 1729 * same as the QP number in the event queue entry. This 1730 * extra check allows us to handle the case where a QP was 1731 * freed and then allocated again in the time it took to 1732 * handle the event queue processing. By constantly incrementing 1733 * the non-constrained portion of the QP number every time 1734 * a new QP is allocated, we mitigate (somewhat) the chance 1735 * that a stale event could be passed to the client's QP 1736 * handler. 1737 * 1738 * And then we check if "ts_ibtfpriv" is NULL. If it is then it 1739 * means that we've have either received this event before we 1740 * finished attaching to the IBTF or we've received it while we 1741 * are in the process of detaching. 1742 */ 1743 if ((qp != NULL) && (qp->qp_qpnum == qpnum) && 1744 (state->ts_ibtfpriv != NULL)) { 1745 event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg; 1746 type = IBT_EVENT_SQD; 1747 1748 /* 1749 * Grab the QP lock and update the QP state to reflect that 1750 * the Send Queue Drained event has arrived. Also determine 1751 * whether the event is intended to be forwarded on to the 1752 * consumer or not. This information is used below in 1753 * determining whether or not to call the IBTF. 1754 */ 1755 mutex_enter(&qp->qp_lock); 1756 forward_sqd_event = qp->qp_forward_sqd_event; 1757 qp->qp_forward_sqd_event = 0; 1758 qp->qp_sqd_still_draining = 0; 1759 mutex_exit(&qp->qp_lock); 1760 1761 if (forward_sqd_event != 0) { 1762 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event); 1763 } 1764 } else { 1765 TNF_PROBE_2(tavor_sendq_drained_handler_dropped_event, 1766 TAVOR_TNF_ERROR, "", tnf_uint, ev_qpnum, qpnum, 1767 tnf_uint, hdl_qpnum, qpnum); 1768 } 1769 1770 TAVOR_TNF_EXIT(tavor_sendq_drained_handler); 1771 return (DDI_SUCCESS); 1772 } 1773 1774 1775 /* 1776 * tavor_path_mig_handler() 1777 * Context: Only called from interrupt context 1778 */ 1779 static int 1780 tavor_path_mig_handler(tavor_state_t *state, tavor_eqhdl_t eq, 1781 tavor_hw_eqe_t *eqe) 1782 { 1783 tavor_qphdl_t qp; 1784 uint_t qpnum; 1785 ibc_async_event_t event; 1786 ibt_async_code_t type; 1787 uint_t eqe_evttype; 1788 1789 TAVOR_TNF_ENTER(tavor_path_mig_handler); 1790 1791 eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe); 1792 1793 ASSERT(eqe_evttype == TAVOR_EVT_PATH_MIGRATED || 1794 eqe_evttype == TAVOR_EVT_EQ_OVERFLOW); 1795 1796 if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) { 1797 TNF_PROBE_0(tavor_path_mig_eq_overflow_condition, 1798 TAVOR_TNF_ERROR, ""); 1799 tavor_eq_overflow_handler(state, eq, eqe); 1800 1801 TAVOR_TNF_EXIT(tavor_path_mig_handler); 1802 return (DDI_FAILURE); 1803 } 1804 1805 /* Get the QP handle from QP number in event descriptor */ 1806 qpnum = TAVOR_EQE_QPNUM_GET(eq, eqe); 1807 qp = tavor_qphdl_from_qpnum(state, qpnum); 1808 1809 /* 1810 * If the QP handle is NULL, this is probably an indication 1811 * that the QP has been freed already. In which case, we 1812 * should not deliver this event. 1813 * 1814 * We also check that the QP number in the handle is the 1815 * same as the QP number in the event queue entry. This 1816 * extra check allows us to handle the case where a QP was 1817 * freed and then allocated again in the time it took to 1818 * handle the event queue processing. By constantly incrementing 1819 * the non-constrained portion of the QP number every time 1820 * a new QP is allocated, we mitigate (somewhat) the chance 1821 * that a stale event could be passed to the client's QP 1822 * handler. 1823 * 1824 * Lastly, we check if "ts_ibtfpriv" is NULL. If it is then it 1825 * means that we've have either received this event before we 1826 * finished attaching to the IBTF or we've received it while we 1827 * are in the process of detaching. 1828 */ 1829 if ((qp != NULL) && (qp->qp_qpnum == qpnum) && 1830 (state->ts_ibtfpriv != NULL)) { 1831 event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg; 1832 type = IBT_EVENT_PATH_MIGRATED_QP; 1833 1834 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event); 1835 } else { 1836 TNF_PROBE_2(tavor_path_mig_handler_dropped_event, 1837 TAVOR_TNF_ERROR, "", tnf_uint, ev_qpnum, qpnum, 1838 tnf_uint, hdl_qpnum, qpnum); 1839 } 1840 1841 TAVOR_TNF_EXIT(tavor_path_mig_handler); 1842 return (DDI_SUCCESS); 1843 } 1844 1845 1846 /* 1847 * tavor_path_mig_err_handler() 1848 * Context: Only called from interrupt context 1849 */ 1850 static int 1851 tavor_path_mig_err_handler(tavor_state_t *state, tavor_eqhdl_t eq, 1852 tavor_hw_eqe_t *eqe) 1853 { 1854 tavor_qphdl_t qp; 1855 uint_t qpnum; 1856 ibc_async_event_t event; 1857 ibt_async_code_t type; 1858 uint_t eqe_evttype; 1859 1860 TAVOR_TNF_ENTER(tavor_path_mig_err_handler); 1861 1862 eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe); 1863 1864 ASSERT(eqe_evttype == TAVOR_EVT_PATH_MIGRATE_FAILED || 1865 eqe_evttype == TAVOR_EVT_EQ_OVERFLOW); 1866 1867 if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) { 1868 TNF_PROBE_0(tavor_path_mig_err_eq_overflow_condition, 1869 TAVOR_TNF_ERROR, ""); 1870 tavor_eq_overflow_handler(state, eq, eqe); 1871 1872 TAVOR_TNF_EXIT(tavor_path_mig_err_handler); 1873 return (DDI_FAILURE); 1874 } 1875 1876 /* Get the QP handle from QP number in event descriptor */ 1877 qpnum = TAVOR_EQE_QPNUM_GET(eq, eqe); 1878 qp = tavor_qphdl_from_qpnum(state, qpnum); 1879 1880 /* 1881 * If the QP handle is NULL, this is probably an indication 1882 * that the QP has been freed already. In which case, we 1883 * should not deliver this event. 1884 * 1885 * We also check that the QP number in the handle is the 1886 * same as the QP number in the event queue entry. This 1887 * extra check allows us to handle the case where a QP was 1888 * freed and then allocated again in the time it took to 1889 * handle the event queue processing. By constantly incrementing 1890 * the non-constrained portion of the QP number every time 1891 * a new QP is allocated, we mitigate (somewhat) the chance 1892 * that a stale event could be passed to the client's QP 1893 * handler. 1894 * 1895 * Lastly, we check if "ts_ibtfpriv" is NULL. If it is then it 1896 * means that we've have either received this event before we 1897 * finished attaching to the IBTF or we've received it while we 1898 * are in the process of detaching. 1899 */ 1900 if ((qp != NULL) && (qp->qp_qpnum == qpnum) && 1901 (state->ts_ibtfpriv != NULL)) { 1902 event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg; 1903 type = IBT_ERROR_PATH_MIGRATE_REQ_QP; 1904 1905 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event); 1906 } else { 1907 TNF_PROBE_2(tavor_path_mig_err_handler_dropped_event, 1908 TAVOR_TNF_ERROR, "", tnf_uint, ev_qpnum, qpnum, 1909 tnf_uint, hdl_qpnum, qpnum); 1910 } 1911 1912 TAVOR_TNF_EXIT(tavor_path_mig_err_handler); 1913 return (DDI_SUCCESS); 1914 } 1915 1916 1917 /* 1918 * tavor_srq_catastrophic_handler() 1919 * Context: Only called from interrupt context 1920 */ 1921 static int 1922 tavor_srq_catastrophic_handler(tavor_state_t *state, tavor_eqhdl_t eq, 1923 tavor_hw_eqe_t *eqe) 1924 { 1925 tavor_qphdl_t qp; 1926 uint_t qpnum; 1927 ibc_async_event_t event; 1928 ibt_async_code_t type; 1929 uint_t eqe_evttype; 1930 1931 TAVOR_TNF_ENTER(tavor_srq_catastrophic_handler); 1932 1933 eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe); 1934 1935 ASSERT(eqe_evttype == TAVOR_EVT_SRQ_CATASTROPHIC_ERROR || 1936 eqe_evttype == TAVOR_EVT_EQ_OVERFLOW); 1937 1938 if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) { 1939 TNF_PROBE_0(tavor_srq_catastrophic_overflow_condition, 1940 TAVOR_TNF_ERROR, ""); 1941 tavor_eq_overflow_handler(state, eq, eqe); 1942 1943 TAVOR_TNF_EXIT(tavor_srq_catastrophic_handler); 1944 return (DDI_FAILURE); 1945 } 1946 1947 /* Get the QP handle from QP number in event descriptor */ 1948 qpnum = TAVOR_EQE_QPNUM_GET(eq, eqe); 1949 qp = tavor_qphdl_from_qpnum(state, qpnum); 1950 1951 /* 1952 * If the QP handle is NULL, this is probably an indication 1953 * that the QP has been freed already. In which case, we 1954 * should not deliver this event. 1955 * 1956 * We also check that the QP number in the handle is the 1957 * same as the QP number in the event queue entry. This 1958 * extra check allows us to handle the case where a QP was 1959 * freed and then allocated again in the time it took to 1960 * handle the event queue processing. By constantly incrementing 1961 * the non-constrained portion of the QP number every time 1962 * a new QP is allocated, we mitigate (somewhat) the chance 1963 * that a stale event could be passed to the client's QP 1964 * handler. 1965 * 1966 * Lastly, we check if "ts_ibtfpriv" is NULL. If it is then it 1967 * means that we've have either received this event before we 1968 * finished attaching to the IBTF or we've received it while we 1969 * are in the process of detaching. 1970 */ 1971 if ((qp != NULL) && (qp->qp_qpnum == qpnum) && 1972 (state->ts_ibtfpriv != NULL)) { 1973 event.ev_srq_hdl = (ibt_srq_hdl_t)qp->qp_srqhdl->srq_hdlrarg; 1974 type = IBT_ERROR_CATASTROPHIC_SRQ; 1975 1976 mutex_enter(&qp->qp_srqhdl->srq_lock); 1977 qp->qp_srqhdl->srq_state = TAVOR_SRQ_STATE_ERROR; 1978 mutex_exit(&qp->qp_srqhdl->srq_lock); 1979 1980 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event); 1981 } else { 1982 TNF_PROBE_2(tavor_srq_catastrophic_handler_dropped_event, 1983 TAVOR_TNF_ERROR, "", tnf_uint, ev_qpnum, qpnum, 1984 tnf_uint, hdl_qpnum, qpnum); 1985 } 1986 1987 TAVOR_TNF_EXIT(tavor_srq_catastrophic_handler); 1988 return (DDI_SUCCESS); 1989 } 1990 1991 1992 /* 1993 * tavor_srq_last_wqe_reached_handler() 1994 * Context: Only called from interrupt context 1995 */ 1996 static int 1997 tavor_srq_last_wqe_reached_handler(tavor_state_t *state, tavor_eqhdl_t eq, 1998 tavor_hw_eqe_t *eqe) 1999 { 2000 tavor_qphdl_t qp; 2001 uint_t qpnum; 2002 ibc_async_event_t event; 2003 ibt_async_code_t type; 2004 uint_t eqe_evttype; 2005 2006 TAVOR_TNF_ENTER(tavor_srq_last_wqe_reached_handler); 2007 2008 eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe); 2009 2010 ASSERT(eqe_evttype == TAVOR_EVT_SRQ_LAST_WQE_REACHED || 2011 eqe_evttype == TAVOR_EVT_EQ_OVERFLOW); 2012 2013 if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) { 2014 TNF_PROBE_0(tavor_srq_last_wqe_reached_over_condition, 2015 TAVOR_TNF_ERROR, ""); 2016 tavor_eq_overflow_handler(state, eq, eqe); 2017 2018 TAVOR_TNF_EXIT(tavor_srq_last_wqe_reached_handler); 2019 return (DDI_FAILURE); 2020 } 2021 2022 /* Get the QP handle from QP number in event descriptor */ 2023 qpnum = TAVOR_EQE_QPNUM_GET(eq, eqe); 2024 qp = tavor_qphdl_from_qpnum(state, qpnum); 2025 2026 /* 2027 * If the QP handle is NULL, this is probably an indication 2028 * that the QP has been freed already. In which case, we 2029 * should not deliver this event. 2030 * 2031 * We also check that the QP number in the handle is the 2032 * same as the QP number in the event queue entry. This 2033 * extra check allows us to handle the case where a QP was 2034 * freed and then allocated again in the time it took to 2035 * handle the event queue processing. By constantly incrementing 2036 * the non-constrained portion of the QP number every time 2037 * a new QP is allocated, we mitigate (somewhat) the chance 2038 * that a stale event could be passed to the client's QP 2039 * handler. 2040 * 2041 * Lastly, we check if "ts_ibtfpriv" is NULL. If it is then it 2042 * means that we've have either received this event before we 2043 * finished attaching to the IBTF or we've received it while we 2044 * are in the process of detaching. 2045 */ 2046 if ((qp != NULL) && (qp->qp_qpnum == qpnum) && 2047 (state->ts_ibtfpriv != NULL)) { 2048 event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg; 2049 type = IBT_EVENT_EMPTY_CHAN; 2050 2051 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event); 2052 } else { 2053 TNF_PROBE_2(tavor_srq_last_wqe_reached_dropped_event, 2054 TAVOR_TNF_ERROR, "", tnf_uint, ev_qpnum, qpnum, 2055 tnf_uint, hdl_qpnum, qpnum); 2056 } 2057 2058 TAVOR_TNF_EXIT(tavor_srq_last_wqe_reached_handler); 2059 return (DDI_SUCCESS); 2060 } 2061 2062 2063 /* 2064 * tavor_ecc_detection_handler() 2065 * Context: Only called from interrupt context 2066 */ 2067 static int 2068 tavor_ecc_detection_handler(tavor_state_t *state, tavor_eqhdl_t eq, 2069 tavor_hw_eqe_t *eqe) 2070 { 2071 uint_t eqe_evttype; 2072 uint_t data; 2073 int i; 2074 2075 TAVOR_TNF_ENTER(tavor_ecc_detection_handler); 2076 2077 eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe); 2078 2079 ASSERT(eqe_evttype == TAVOR_EVT_ECC_DETECTION || 2080 eqe_evttype == TAVOR_EVT_EQ_OVERFLOW); 2081 2082 if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) { 2083 TNF_PROBE_0(tavor_ecc_detection_eq_overflow_condition, 2084 TAVOR_TNF_ERROR, ""); 2085 tavor_eq_overflow_handler(state, eq, eqe); 2086 2087 TAVOR_TNF_EXIT(tavor_ecc_detection_handler); 2088 return (DDI_FAILURE); 2089 } 2090 2091 /* 2092 * The "ECC Detection Event" indicates that a correctable single-bit 2093 * has occurred with the attached DDR. The EQE provides some 2094 * additional information about the errored EQ. So we print a warning 2095 * message here along with that additional information. 2096 */ 2097 TAVOR_WARNING(state, "ECC Correctable Error Event Detected"); 2098 for (i = 0; i < sizeof (tavor_hw_eqe_t) >> 2; i++) { 2099 data = ((uint_t *)eqe)[i]; 2100 cmn_err(CE_CONT, "! EQE[%02x]: %08x\n", i, data); 2101 } 2102 2103 TAVOR_TNF_EXIT(tavor_ecc_detection_handler); 2104 return (DDI_SUCCESS); 2105 } 2106 2107 2108 /* 2109 * tavor_eq_overflow_handler() 2110 * Context: Only called from interrupt context 2111 */ 2112 void 2113 tavor_eq_overflow_handler(tavor_state_t *state, tavor_eqhdl_t eq, 2114 tavor_hw_eqe_t *eqe) 2115 { 2116 uint_t error_type, data; 2117 2118 TAVOR_TNF_ENTER(tavor_eq_overflow_handler); 2119 2120 ASSERT(TAVOR_EQE_EVTTYPE_GET(eq, eqe) == TAVOR_EVT_EQ_OVERFLOW); 2121 2122 /* 2123 * The "Event Queue Overflow Event" indicates that something has 2124 * probably gone seriously wrong with some hardware (or, perhaps, 2125 * with the software... though it's unlikely in this case). The EQE 2126 * provides some additional information about the errored EQ. So we 2127 * print a warning message here along with that additional information. 2128 */ 2129 error_type = TAVOR_EQE_OPERRTYPE_GET(eq, eqe); 2130 data = TAVOR_EQE_OPERRDATA_GET(eq, eqe); 2131 2132 TAVOR_WARNING(state, "Event Queue overflow"); 2133 cmn_err(CE_CONT, " Error type: %02x, data: %08x\n", error_type, data); 2134 2135 TAVOR_TNF_EXIT(tavor_eq_overflow_handler); 2136 } 2137 2138 2139 /* 2140 * tavor_no_eqhandler 2141 * Context: Only called from interrupt context 2142 */ 2143 /* ARGSUSED */ 2144 static int 2145 tavor_no_eqhandler(tavor_state_t *state, tavor_eqhdl_t eq, 2146 tavor_hw_eqe_t *eqe) 2147 { 2148 uint_t data; 2149 int i; 2150 2151 TAVOR_TNF_ENTER(tavor_no_eqhandler); 2152 2153 /* 2154 * This "unexpected event" handler (or "catch-all" handler) will 2155 * receive all events for which no other handler has been registered. 2156 * If we end up here, then something has probably gone seriously wrong 2157 * with the Tavor hardware (or, perhaps, with the software... though 2158 * it's unlikely in this case). The EQE provides all the information 2159 * about the event. So we print a warning message here along with 2160 * the contents of the EQE. 2161 */ 2162 TAVOR_WARNING(state, "Unexpected Event handler"); 2163 cmn_err(CE_CONT, " Event type: %02x, subtype: %02x\n", 2164 TAVOR_EQE_EVTTYPE_GET(eq, eqe), TAVOR_EQE_EVTSUBTYPE_GET(eq, eqe)); 2165 for (i = 0; i < sizeof (tavor_hw_eqe_t) >> 2; i++) { 2166 data = ((uint_t *)eqe)[i]; 2167 cmn_err(CE_CONT, " EQE[%02x]: %08x\n", i, data); 2168 } 2169 2170 TAVOR_TNF_EXIT(tavor_no_eqhandler); 2171 return (DDI_SUCCESS); 2172 }