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         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*eq))
 667 
 668         /* Find the pointer to the clr_ECR register */
 669         clr_ecr = state->ts_cmd_regs.clr_ecr;
 670 
 671         /*
 672          * Check for Local Catastrophic Error If we have this kind of error,
 673          * then we don't need to do anything else here, as this kind of
 674          * catastrophic error is handled separately.  So we call the
 675          * catastrophic handler, clear the ECR and then return.
 676          */
 677         if (eq->eq_evttypemask == TAVOR_EVT_MSK_LOCAL_CAT_ERROR) {
 678                 /*
 679                  * Call Catastrophic Error handler
 680                  */
 681                 tavor_eq_catastrophic(state);
 682 
 683                 /*
 684                  * Clear the ECR.  Specifically, clear the bit corresponding
 685                  * to the event queue just processed.
 686                  */
 687                 ecr_mask = ((uint64_t)1 << eq->eq_eqnum);
 688                 ddi_put64(state->ts_reg_cmdhdl, clr_ecr, ecr_mask);
 689 
 690                 TAVOR_TNF_EXIT(tavor_eq_poll);
 691                 return;
 692         }
 693 
 694         /* Get the consumer pointer index */
 695         cons_indx = eq->eq_consindx;
 696 
 697         /*
 698          * Calculate the wrap around mask.  Note: This operation only works
 699          * because all Tavor event queues have power-of-2 sizes
 700          */
 701         wrap_around_mask = (eq->eq_bufsz - 1);
 702 
 703         /* Calculate the pointer to the first EQ entry */
 704         eqe = &eq->eq_buf[cons_indx];
 705         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*eqe))
 706 
 707         /*
 708          * Sync the current EQE to read
 709          *    We need to force a ddi_dma_sync() here (independent of how the
 710          *    EQ was mapped) because it is possible for us to receive the
 711          *    interrupt, do a read of the ECR, and have each of these
 712          *    operations complete successfully even though the hardware's DMA
 713          *    to the EQ has not yet completed.
 714          */
 715         tavor_eqe_sync(eq, eqe, DDI_DMA_SYNC_FORCPU, TAVOR_EQ_SYNC_FORCE);
 716 
 717         /*
 718          * Pull the handler function for this EQ from the Tavor Event Queue
 719          * handle
 720          */
 721         eqfunction = eq->eq_func;
 722 
 723         /*
 724          * Keep pulling entries from the EQ until we find an entry owner by
 725          * the hardware.  As long as there the EQE's owned by SW, process
 726          * each entry by calling its handler function and updating the EQ
 727          * consumer index.
 728          */
 729         do {
 730                 while (TAVOR_EQE_OWNER_IS_SW(eq, eqe)) {
 731                         /*
 732                          * Call the EQ handler function.  But only call if we
 733                          * are not in polled I/O mode (i.e. not processing
 734                          * because of a system panic).  Note: We don't call
 735                          * the EQ handling functions from a system panic
 736                          * because we are primarily concerned only with
 737                          * ensuring that the event queues do not overflow (or,
 738                          * more specifically, the event queue associated with
 739                          * the CQ that is being used in the sync/dump process).
 740                          * Also, we don't want to make any upcalls (to the
 741                          * IBTF) because we can't guarantee when/if those
 742                          * calls would ever return.  And, if we're in panic,
 743                          * then we reached here through a PollCQ() call (from
 744                          * tavor_cq_poll()), and we need to ensure that we
 745                          * successfully return any work completions to the
 746                          * caller.
 747                          */
 748                         if (ddi_in_panic() == 0) {
 749                                 eqfunction(state, eq, eqe);
 750                         }
 751 
 752                         /* Reset entry to hardware ownership */
 753                         TAVOR_EQE_OWNER_SET_HW(eq, eqe);
 754 
 755                         /* Sync the current EQE for device */
 756                         tavor_eqe_sync(eq, eqe, DDI_DMA_SYNC_FORDEV,
 757                             TAVOR_EQ_SYNC_NORMAL);
 758 
 759                         /* Increment the consumer index */
 760                         cons_indx = (cons_indx + 1) & wrap_around_mask;
 761 
 762                         /* Update the pointer to the next EQ entry */
 763                         eqe = &eq->eq_buf[cons_indx];
 764 
 765                         /* Sync the next EQE to read */
 766                         tavor_eqe_sync(eq, eqe, DDI_DMA_SYNC_FORCPU,
 767                             TAVOR_EQ_SYNC_NORMAL);
 768                 }
 769 
 770                 /*
 771                  * Clear the ECR.  Specifically, clear the bit corresponding
 772                  * to the event queue just processed.
 773                  */
 774                 ecr_mask = ((uint64_t)1 << eq->eq_eqnum);
 775                 ddi_put64(state->ts_reg_cmdhdl, clr_ecr, ecr_mask);
 776 
 777                 /* Write an EQ doorbell to update the consumer index */
 778                 eq->eq_consindx = cons_indx;
 779                 tavor_eq_doorbell(state, TAVOR_EQDB_SET_CONSINDX, eq->eq_eqnum,
 780                     cons_indx);
 781 
 782                 /* Write another EQ doorbell to rearm */
 783                 tavor_eq_doorbell(state, TAVOR_EQDB_REARM_EQ, eq->eq_eqnum, 0);
 784 
 785                 /*
 786                  * NOTE: Due to the nature of Mellanox hardware, we do not have
 787                  * to do an explicit PIO read to ensure that the doorbell write
 788                  * has been flushed to the hardware.  There is state encoded in
 789                  * the doorbell information we write which makes this
 790                  * unnecessary.  We can be assured that if an event needs to be
 791                  * generated, the hardware will make sure that it is, solving
 792                  * the possible race condition.
 793                  */
 794 
 795                 /* Sync the next EQE to read */
 796                 tavor_eqe_sync(eq, eqe, DDI_DMA_SYNC_FORCPU,
 797                     TAVOR_EQ_SYNC_NORMAL);
 798 
 799         } while (TAVOR_EQE_OWNER_IS_SW(eq, eqe));
 800 
 801         TAVOR_TNF_EXIT(tavor_eq_poll);
 802 }
 803 
 804 
 805 /*
 806  * tavor_eq_catastrophic
 807  *    Context: Only called from interrupt context (and during panic)
 808  */
 809 static void
 810 tavor_eq_catastrophic(tavor_state_t *state)
 811 {
 812         ibt_async_code_t        type;
 813         ibc_async_event_t       event;
 814         uint32_t                *base_addr;
 815         uint32_t                buf_size;
 816         uint32_t                word;
 817         uint8_t                 err_type;
 818         uint32_t                err_buf;
 819         int                     i;
 820 
 821         TAVOR_TNF_ENTER(tavor_eq_catastrophic);
 822 
 823         bzero(&event, sizeof (ibc_async_event_t));
 824 
 825         base_addr = (uint32_t *)(uintptr_t)(
 826             (uintptr_t)state->ts_reg_cmd_baseaddr +
 827             state->ts_fw.error_buf_addr);
 828         buf_size = state->ts_fw.error_buf_sz;
 829 
 830         word = ddi_get32(state->ts_reg_cmdhdl, base_addr);
 831 
 832         err_type = (word & 0xFF000000) >> 24;
 833         type     = IBT_ERROR_LOCAL_CATASTROPHIC;
 834 
 835         switch (err_type) {
 836         case TAVOR_CATASTROPHIC_INTERNAL_ERROR:
 837                 cmn_err(CE_WARN, "Catastrophic Internal Error: 0x%02x",
 838                     err_type);
 839 
 840                 break;
 841 
 842         case TAVOR_CATASTROPHIC_UPLINK_BUS_ERROR:
 843                 cmn_err(CE_WARN, "Catastrophic Uplink Bus Error: 0x%02x",
 844                     err_type);
 845 
 846                 break;
 847 
 848         case TAVOR_CATASTROPHIC_DDR_DATA_ERROR:
 849                 cmn_err(CE_WARN, "Catastrophic DDR Data Error: 0x%02x",
 850                     err_type);
 851 
 852                 break;
 853 
 854         case TAVOR_CATASTROPHIC_INTERNAL_PARITY_ERROR:
 855                 cmn_err(CE_WARN, "Catastrophic Internal Parity Error: 0x%02x",
 856                     err_type);
 857 
 858                 break;
 859 
 860         default:
 861                 /* Unknown type of Catastrophic error */
 862                 cmn_err(CE_WARN, "Catastrophic Unknown Error: 0x%02x",
 863                     err_type);
 864 
 865                 break;
 866         }
 867 
 868         /*
 869          * Read in the catastrophic error buffer from the hardware, printing
 870          * only to the log file only
 871          */
 872         for (i = 0; i < buf_size; i += 4) {
 873                 base_addr = (uint32_t *)((uintptr_t)(state->ts_reg_cmd_baseaddr
 874                     + state->ts_fw.error_buf_addr + (i * 4)));
 875                 err_buf = ddi_get32(state->ts_reg_cmdhdl, base_addr);
 876                 cmn_err(CE_WARN, "catastrophic_error[%02x]: %08X", i, err_buf);
 877         }
 878 
 879         /*
 880          * We also call the IBTF here to inform it of the catastrophic error.
 881          * Note: Since no event information (i.e. QP handles, CQ handles,
 882          * etc.) is necessary, we pass a NULL pointer instead of a pointer to
 883          * an empty ibc_async_event_t struct.
 884          *
 885          * But we also check if "ts_ibtfpriv" is NULL.  If it is then it
 886          * means that we've have either received this event before we
 887          * finished attaching to the IBTF or we've received it while we
 888          * are in the process of detaching.
 889          */
 890         if (state->ts_ibtfpriv != NULL) {
 891                 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event);
 892         }
 893 
 894         TAVOR_TNF_EXIT(tavor_eq_catastrophic);
 895 }
 896 
 897 
 898 /*
 899  * tavor_eq_alloc()
 900  *    Context: Only called from attach() path context
 901  */
 902 static int
 903 tavor_eq_alloc(tavor_state_t *state, uint32_t log_eq_size, uint_t intr,
 904     tavor_eqhdl_t *eqhdl)
 905 {
 906         tavor_rsrc_t            *eqc, *rsrc;
 907         tavor_hw_eqc_t          eqc_entry;
 908         tavor_eqhdl_t           eq;
 909         ibt_mr_attr_t           mr_attr;
 910         tavor_mr_options_t      op;
 911         tavor_pdhdl_t           pd;
 912         tavor_mrhdl_t           mr;
 913         tavor_hw_eqe_t          *buf;
 914         uint64_t                addr;
 915         uint32_t                lkey;
 916         uint_t                  dma_xfer_mode;
 917         int                     status, i;
 918         char                    *errormsg;
 919 
 920         TAVOR_TNF_ENTER(tavor_eq_alloc);
 921 
 922         /* Use the internal protection domain (PD) for setting up EQs */
 923         pd = state->ts_pdhdl_internal;
 924 
 925         /* Increment the reference count on the protection domain (PD) */
 926         tavor_pd_refcnt_inc(pd);
 927 
 928         /*
 929          * Allocate an EQ context entry.  This will be filled in with all
 930          * the necessary parameters to define the Event Queue.  And then
 931          * ownership will be passed to the hardware in the final step
 932          * below.  If we fail here, we must undo the protection domain
 933          * reference count.
 934          */
 935         status = tavor_rsrc_alloc(state, TAVOR_EQC, 1, TAVOR_SLEEP, &eqc);
 936         if (status != DDI_SUCCESS) {
 937                 /* Set "status" and "errormsg" and goto failure */
 938                 TAVOR_TNF_FAIL(DDI_FAILURE, "failed EQ context");
 939                 goto eqalloc_fail1;
 940         }
 941 
 942         /*
 943          * Allocate the software structure for tracking the event queue (i.e.
 944          * the Tavor Event Queue handle).  If we fail here, we must undo the
 945          * protection domain reference count and the previous resource
 946          * allocation.
 947          */
 948         status = tavor_rsrc_alloc(state, TAVOR_EQHDL, 1, TAVOR_SLEEP, &rsrc);
 949         if (status != DDI_SUCCESS) {
 950                 /* Set "status" and "errormsg" and goto failure */
 951                 TAVOR_TNF_FAIL(DDI_FAILURE, "failed EQ handler");
 952                 goto eqalloc_fail2;
 953         }
 954         eq = (tavor_eqhdl_t)rsrc->tr_addr;
 955 
 956         /*
 957          * Allocate the memory for Event Queue.  Note: Although we use the
 958          * common queue allocation routine, we always specify
 959          * TAVOR_QUEUE_LOCATION_NORMAL (i.e. EQ located in system memory)
 960          * because it would be inefficient to have EQs located in DDR memory.
 961          * This is primarily because EQs are read from (by software) more
 962          * than they are written to.  Also note that, unlike Tavor QP work
 963          * queues, event queues do not have the same strict alignment
 964          * requirements.  It is sufficient for the EQ memory to be both
 965          * aligned to and bound to addresses which are a multiple of EQE size.
 966          */
 967         eq->eq_eqinfo.qa_size = (1 << log_eq_size) * sizeof (tavor_hw_eqe_t);
 968         eq->eq_eqinfo.qa_alloc_align = sizeof (tavor_hw_eqe_t);
 969         eq->eq_eqinfo.qa_bind_align  = sizeof (tavor_hw_eqe_t);
 970         eq->eq_eqinfo.qa_location = TAVOR_QUEUE_LOCATION_NORMAL;
 971         status = tavor_queue_alloc(state, &eq->eq_eqinfo, TAVOR_SLEEP);
 972         if (status != DDI_SUCCESS) {
 973                 /* Set "status" and "errormsg" and goto failure */
 974                 TAVOR_TNF_FAIL(DDI_FAILURE, "failed event queue");
 975                 goto eqalloc_fail3;
 976         }
 977         buf = (tavor_hw_eqe_t *)eq->eq_eqinfo.qa_buf_aligned;
 978 
 979         /*
 980          * Initialize each of the Event Queue Entries (EQE) by setting their
 981          * ownership to hardware ("owner" bit set to HW).  This is in
 982          * preparation for the final transfer of ownership (below) of the
 983          * EQ context itself.
 984          */
 985         for (i = 0; i < (1 << log_eq_size); i++) {
 986                 TAVOR_EQE_OWNER_SET_HW(eq, &buf[i]);
 987         }
 988 
 989         /*
 990          * Register the memory for the EQ.  The memory for the EQ must
 991          * be registered in the Tavor TPT tables.  This gives us the LKey
 992          * to specify in the EQ context below.
 993          *
 994          * Because we are in the attach path we use NOSLEEP here so that we
 995          * SPIN in the HCR since the event queues are not setup yet, and we
 996          * cannot NOSPIN at this point in time.
 997          */
 998         mr_attr.mr_vaddr = (uint64_t)(uintptr_t)buf;
 999         mr_attr.mr_len   = eq->eq_eqinfo.qa_size;
1000         mr_attr.mr_as    = NULL;
1001         mr_attr.mr_flags = IBT_MR_NOSLEEP | IBT_MR_ENABLE_LOCAL_WRITE;
1002         dma_xfer_mode    = state->ts_cfg_profile->cp_streaming_consistent;
1003         if (dma_xfer_mode == DDI_DMA_STREAMING) {
1004                 mr_attr.mr_flags |= IBT_MR_NONCOHERENT;
1005         }
1006         op.mro_bind_type   = state->ts_cfg_profile->cp_iommu_bypass;
1007         op.mro_bind_dmahdl = eq->eq_eqinfo.qa_dmahdl;
1008         op.mro_bind_override_addr = 0;
1009         status = tavor_mr_register(state, pd, &mr_attr, &mr, &op);
1010         if (status != DDI_SUCCESS) {
1011                 /* Set "status" and "errormsg" and goto failure */
1012                 TAVOR_TNF_FAIL(DDI_FAILURE, "failed register mr");
1013                 goto eqalloc_fail4;
1014         }
1015         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*mr))
1016         addr = mr->mr_bindinfo.bi_addr;
1017         lkey = mr->mr_lkey;
1018 
1019         /* Determine if later ddi_dma_sync will be necessary */
1020         eq->eq_sync = TAVOR_EQ_IS_SYNC_REQ(state, eq->eq_eqinfo);
1021 
1022         /* Sync entire EQ for use by the hardware (if necessary) */
1023         if (eq->eq_sync) {
1024                 (void) ddi_dma_sync(mr->mr_bindinfo.bi_dmahdl, 0,
1025                     eq->eq_eqinfo.qa_size, DDI_DMA_SYNC_FORDEV);
1026         }
1027 
1028         /*
1029          * Fill in the EQC entry.  This is the final step before passing
1030          * ownership of the EQC entry to the Tavor hardware.  We use all of
1031          * the information collected/calculated above to fill in the
1032          * requisite portions of the EQC.  Note:  We create all EQs in the
1033          * "fired" state.  We will arm them later (after our interrupt
1034          * routine had been registered.)
1035          */
1036         bzero(&eqc_entry, sizeof (tavor_hw_eqc_t));
1037         eqc_entry.owner         = TAVOR_HW_OWNER;
1038         eqc_entry.xlat          = TAVOR_VA2PA_XLAT_ENABLED;
1039         eqc_entry.state         = TAVOR_EQ_FIRED;
1040         eqc_entry.start_addr_h  = (addr >> 32);
1041         eqc_entry.start_addr_l  = (addr & 0xFFFFFFFF);
1042         eqc_entry.log_eq_sz     = log_eq_size;
1043         eqc_entry.usr_page      = 0;
1044         eqc_entry.pd            = pd->pd_pdnum;
1045         eqc_entry.intr          = intr;
1046         eqc_entry.lkey          = lkey;
1047 
1048         /*
1049          * Write the EQC entry to hardware.  Lastly, we pass ownership of
1050          * the entry to the hardware (using the Tavor SW2HW_EQ firmware
1051          * command).  Note: in general, this operation shouldn't fail.  But
1052          * if it does, we have to undo everything we've done above before
1053          * returning error.
1054          */
1055         status = tavor_cmn_ownership_cmd_post(state, SW2HW_EQ, &eqc_entry,
1056             sizeof (tavor_hw_eqc_t), eqc->tr_indx, TAVOR_CMD_NOSLEEP_SPIN);
1057         if (status != TAVOR_CMD_SUCCESS) {
1058                 cmn_err(CE_CONT, "Tavor: SW2HW_EQ command failed: %08x\n",
1059                     status);
1060                 TNF_PROBE_1(tavor_eq_alloc_sw2hw_eq_cmd_fail,
1061                     TAVOR_TNF_ERROR, "", tnf_uint, status, status);
1062                 /* Set "status" and "errormsg" and goto failure */
1063                 TAVOR_TNF_FAIL(ibc_get_ci_failure(0), "tavor SW2HW_EQ command");
1064                 goto eqalloc_fail5;
1065         }
1066 
1067         /*
1068          * Fill in the rest of the Tavor Event Queue handle.  Having
1069          * successfully transferred ownership of the EQC, we can update the
1070          * following fields for use in further operations on the EQ.
1071          */
1072         eq->eq_eqcrsrcp       = eqc;
1073         eq->eq_rsrcp  = rsrc;
1074         eq->eq_consindx       = 0;
1075         eq->eq_eqnum  = eqc->tr_indx;
1076         eq->eq_buf    = buf;
1077         eq->eq_bufsz  = (1 << log_eq_size);
1078         eq->eq_mrhdl  = mr;
1079         *eqhdl           = eq;
1080 
1081         TAVOR_TNF_EXIT(tavor_eq_alloc);
1082         return (DDI_SUCCESS);
1083 
1084 /*
1085  * The following is cleanup for all possible failure cases in this routine
1086  */
1087 eqalloc_fail5:
1088         if (tavor_mr_deregister(state, &mr, TAVOR_MR_DEREG_ALL,
1089             TAVOR_NOSLEEP) != DDI_SUCCESS) {
1090                 TAVOR_WARNING(state, "failed to deregister EQ memory");
1091         }
1092 eqalloc_fail4:
1093         tavor_queue_free(state, &eq->eq_eqinfo);
1094 eqalloc_fail3:
1095         tavor_rsrc_free(state, &rsrc);
1096 eqalloc_fail2:
1097         tavor_rsrc_free(state, &eqc);
1098 eqalloc_fail1:
1099         tavor_pd_refcnt_dec(pd);
1100 eqalloc_fail:
1101         TNF_PROBE_1(tavor_eq_alloc_fail, TAVOR_TNF_ERROR, "",
1102             tnf_string, msg, errormsg);
1103         TAVOR_TNF_EXIT(tavor_eq_alloc);
1104         return (status);
1105 }
1106 
1107 
1108 /*
1109  * tavor_eq_free()
1110  *    Context: Only called from attach() and/or detach() path contexts
1111  */
1112 static int
1113 tavor_eq_free(tavor_state_t *state, tavor_eqhdl_t *eqhdl)
1114 {
1115         tavor_rsrc_t            *eqc, *rsrc;
1116         tavor_hw_eqc_t          eqc_entry;
1117         tavor_pdhdl_t           pd;
1118         tavor_mrhdl_t           mr;
1119         tavor_eqhdl_t           eq;
1120         uint32_t                eqnum;
1121         int                     status;
1122 
1123         TAVOR_TNF_ENTER(tavor_eq_free);
1124 
1125         /*
1126          * Pull all the necessary information from the Tavor Event Queue
1127          * handle.  This is necessary here because the resource for the
1128          * EQ handle is going to be freed up as part of this operation.
1129          */
1130         eq      = *eqhdl;
1131         eqc     = eq->eq_eqcrsrcp;
1132         rsrc    = eq->eq_rsrcp;
1133         pd      = state->ts_pdhdl_internal;
1134         mr      = eq->eq_mrhdl;
1135         eqnum   = eq->eq_eqnum;
1136 
1137         /*
1138          * Reclaim EQC entry from hardware (using the Tavor HW2SW_EQ
1139          * firmware command).  If the ownership transfer fails for any reason,
1140          * then it is an indication that something (either in HW or SW) has
1141          * gone seriously wrong.
1142          */
1143         status = tavor_cmn_ownership_cmd_post(state, HW2SW_EQ, &eqc_entry,
1144             sizeof (tavor_hw_eqc_t), eqnum, TAVOR_CMD_NOSLEEP_SPIN);
1145         if (status != TAVOR_CMD_SUCCESS) {
1146                 TAVOR_WARNING(state, "failed to reclaim EQC ownership");
1147                 cmn_err(CE_CONT, "Tavor: HW2SW_EQ command failed: %08x\n",
1148                     status);
1149                 TNF_PROBE_1(tavor_eq_free_hw2sw_eq_cmd_fail,
1150                     TAVOR_TNF_ERROR, "", tnf_uint, status, status);
1151                 TAVOR_TNF_EXIT(tavor_eq_free);
1152                 return (DDI_FAILURE);
1153         }
1154 
1155         /*
1156          * Deregister the memory for the Event Queue.  If this fails
1157          * for any reason, then it is an indication that something (either
1158          * in HW or SW) has gone seriously wrong.  So we print a warning
1159          * message and continue.
1160          */
1161         status = tavor_mr_deregister(state, &mr, TAVOR_MR_DEREG_ALL,
1162             TAVOR_NOSLEEP);
1163         if (status != DDI_SUCCESS) {
1164                 TAVOR_WARNING(state, "failed to deregister EQ memory");
1165                 TNF_PROBE_0(tavor_eq_free_dereg_mr_fail, TAVOR_TNF_ERROR, "");
1166                 TAVOR_TNF_EXIT(tavor_eq_free);
1167         }
1168 
1169         /* Free the memory for the EQ */
1170         tavor_queue_free(state, &eq->eq_eqinfo);
1171 
1172         /* Free the Tavor Event Queue handle */
1173         tavor_rsrc_free(state, &rsrc);
1174 
1175         /* Free up the EQC entry resource */
1176         tavor_rsrc_free(state, &eqc);
1177 
1178         /* Decrement the reference count on the protection domain (PD) */
1179         tavor_pd_refcnt_dec(pd);
1180 
1181         /* Set the eqhdl pointer to NULL and return success */
1182         *eqhdl = NULL;
1183 
1184         TAVOR_TNF_EXIT(tavor_eq_free);
1185         return (DDI_SUCCESS);
1186 }
1187 
1188 
1189 /*
1190  * tavor_eq_handler_init
1191  *    Context: Only called from attach() path context
1192  */
1193 static int
1194 tavor_eq_handler_init(tavor_state_t *state, tavor_eqhdl_t eq,
1195     uint_t evt_type_mask, int (*eq_func)(tavor_state_t *state,
1196     tavor_eqhdl_t eq, tavor_hw_eqe_t *eqe))
1197 {
1198         int             status;
1199 
1200         TAVOR_TNF_ENTER(tavor_eq_handler_init);
1201 
1202         /*
1203          * Save away the EQ handler function and the event type mask.  These
1204          * will be used later during interrupt and event queue processing.
1205          */
1206         eq->eq_func     = eq_func;
1207         eq->eq_evttypemask = evt_type_mask;
1208 
1209         /*
1210          * Map the EQ to a specific class of event (or events) depending
1211          * on the mask value passed in.  The TAVOR_EVT_NO_MASK means not
1212          * to attempt associating the EQ with any specific class of event.
1213          * This is particularly useful when initializing the events queues
1214          * used for CQ events.   The mapping is done using the Tavor MAP_EQ
1215          * firmware command.  Note: This command should not, in general, fail.
1216          * If it does, then something (probably HW related) has gone seriously
1217          * wrong.
1218          */
1219         if (evt_type_mask != TAVOR_EVT_NO_MASK) {
1220                 status = tavor_map_eq_cmd_post(state,
1221                     TAVOR_CMD_MAP_EQ_EVT_MAP, eq->eq_eqnum, evt_type_mask,
1222                     TAVOR_CMD_NOSLEEP_SPIN);
1223                 if (status != TAVOR_CMD_SUCCESS) {
1224                         cmn_err(CE_CONT, "Tavor: MAP_EQ command failed: "
1225                             "%08x\n", status);
1226                         TNF_PROBE_1(tavor_eq_handler_init_map_eq_cmd_fail,
1227                             TAVOR_TNF_ERROR, "", tnf_uint, status, status);
1228                         TAVOR_TNF_EXIT(tavor_eq_handler_init);
1229                         return (DDI_FAILURE);
1230                 }
1231         }
1232 
1233         TAVOR_TNF_EXIT(tavor_eq_handler_init);
1234         return (DDI_SUCCESS);
1235 }
1236 
1237 
1238 /*
1239  * tavor_eq_handler_fini
1240  *    Context: Only called from attach() and/or detach() path contexts
1241  */
1242 static int
1243 tavor_eq_handler_fini(tavor_state_t *state, tavor_eqhdl_t eq)
1244 {
1245         int                     status;
1246 
1247         TAVOR_TNF_ENTER(tavor_eq_handler_fini);
1248 
1249         /*
1250          * Unmap the EQ from the event class to which it had been previously
1251          * mapped.  The unmapping is done using the Tavor MAP_EQ (in much
1252          * the same way that the initial mapping was done).  The difference,
1253          * however, is in the TAVOR_EQ_EVT_UNMAP flag that is passed to the
1254          * MAP_EQ firmware command.  The TAVOR_EVT_NO_MASK (which may have
1255          * been passed in at init time) still means that no association has
1256          * been made between the EQ and any specific class of event (and,
1257          * hence, no unmapping is necessary).  Note: This command should not,
1258          * in general, fail.  If it does, then something (probably HW related)
1259          * has gone seriously wrong.
1260          */
1261         if (eq->eq_evttypemask != TAVOR_EVT_NO_MASK) {
1262                 status = tavor_map_eq_cmd_post(state,
1263                     TAVOR_CMD_MAP_EQ_EVT_UNMAP, eq->eq_eqnum,
1264                     eq->eq_evttypemask, TAVOR_CMD_NOSLEEP_SPIN);
1265                 if (status != TAVOR_CMD_SUCCESS) {
1266                         cmn_err(CE_CONT, "Tavor: MAP_EQ command failed: "
1267                             "%08x\n", status);
1268                         TNF_PROBE_1(tavor_eq_handler_fini_map_eq_cmd_fail,
1269                             TAVOR_TNF_ERROR, "", tnf_uint, status, status);
1270                         TAVOR_TNF_EXIT(tavor_eq_handler_fini);
1271                         return (DDI_FAILURE);
1272                 }
1273         }
1274 
1275         TAVOR_TNF_EXIT(tavor_eq_handler_fini);
1276         return (DDI_SUCCESS);
1277 }
1278 
1279 
1280 /*
1281  * tavor_eqe_sync()
1282  *    Context: Can be called from interrupt or base context.
1283  *
1284  *    Typically, this routine does nothing unless the EQ memory is
1285  *    mapped as DDI_DMA_STREAMING.  However, there is a condition where
1286  *    ddi_dma_sync() is necessary even if the memory was mapped in
1287  *    consistent mode.  The "force_sync" parameter is used here to force
1288  *    the call to ddi_dma_sync() independent of how the EQ memory was
1289  *    mapped.
1290  */
1291 static void
1292 tavor_eqe_sync(tavor_eqhdl_t eq, tavor_hw_eqe_t *eqe, uint_t flag,
1293     uint_t force_sync)
1294 {
1295         ddi_dma_handle_t        dmahdl;
1296         off_t                   offset;
1297         int                     status;
1298 
1299         TAVOR_TNF_ENTER(tavor_eqe_sync);
1300 
1301         /* Determine if EQ needs to be synced or not */
1302         if ((eq->eq_sync == 0) && (force_sync == TAVOR_EQ_SYNC_NORMAL)) {
1303                 TAVOR_TNF_EXIT(tavor_eqe_sync);
1304                 return;
1305         }
1306 
1307         /* Get the DMA handle from EQ context */
1308         dmahdl = eq->eq_mrhdl->mr_bindinfo.bi_dmahdl;
1309 
1310         /* Calculate offset of next EQE */
1311         offset = (off_t)((uintptr_t)eqe - (uintptr_t)&eq->eq_buf[0]);
1312         status = ddi_dma_sync(dmahdl, offset, sizeof (tavor_hw_eqe_t), flag);
1313         if (status != DDI_SUCCESS) {
1314                 TNF_PROBE_0(tavor_eqe_sync_getnextentry_fail,
1315                     TAVOR_TNF_ERROR, "");
1316                 TAVOR_TNF_EXIT(tavor_eqe_sync);
1317                 return;
1318         }
1319 
1320         TAVOR_TNF_EXIT(tavor_eqe_sync);
1321 }
1322 
1323 
1324 /*
1325  * tavor_port_state_change_handler()
1326  *    Context: Only called from interrupt context
1327  */
1328 static int
1329 tavor_port_state_change_handler(tavor_state_t *state, tavor_eqhdl_t eq,
1330     tavor_hw_eqe_t *eqe)
1331 {
1332         ibc_async_event_t       event;
1333         ibt_async_code_t        type;
1334         uint_t                  port, subtype;
1335         uint_t                  eqe_evttype;
1336         char                    link_msg[24];
1337 
1338         TAVOR_TNF_ENTER(tavor_port_state_change_handler);
1339 
1340         eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe);
1341 
1342         ASSERT(eqe_evttype == TAVOR_EVT_PORT_STATE_CHANGE ||
1343             eqe_evttype == TAVOR_EVT_EQ_OVERFLOW);
1344 
1345         if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) {
1346                 TNF_PROBE_0(tavor_port_state_change_eq_overflow_condition,
1347                     TAVOR_TNF_ERROR, "");
1348                 tavor_eq_overflow_handler(state, eq, eqe);
1349 
1350                 TAVOR_TNF_EXIT(tavor_port_state_change_handler);
1351                 return (DDI_FAILURE);
1352         }
1353 
1354         /*
1355          * Depending on the type of Port State Change event, pass the
1356          * appropriate asynch event to the IBTF.
1357          */
1358         port = TAVOR_EQE_PORTNUM_GET(eq, eqe);
1359 
1360         /* Check for valid port number in event */
1361         if ((port == 0) || (port > state->ts_cfg_profile->cp_num_ports)) {
1362                 TAVOR_WARNING(state, "Unexpected port number in port state "
1363                     "change event");
1364                 cmn_err(CE_CONT, "  Port number: %02x\n", port);
1365                 TAVOR_TNF_EXIT(tavor_port_state_change_handler);
1366                 return (DDI_FAILURE);
1367         }
1368 
1369         subtype = TAVOR_EQE_EVTSUBTYPE_GET(eq, eqe);
1370         if (subtype == TAVOR_PORT_LINK_ACTIVE) {
1371                 event.ev_port   = port;
1372                 type            = IBT_EVENT_PORT_UP;
1373 
1374                 (void) snprintf(link_msg, 23, "port %d up", port);
1375                 ddi_dev_report_fault(state->ts_dip, DDI_SERVICE_RESTORED,
1376                     DDI_EXTERNAL_FAULT, link_msg);
1377         } else if (subtype == TAVOR_PORT_LINK_DOWN) {
1378                 event.ev_port   = port;
1379                 type            = IBT_ERROR_PORT_DOWN;
1380 
1381                 (void) snprintf(link_msg, 23, "port %d down", port);
1382                 ddi_dev_report_fault(state->ts_dip, DDI_SERVICE_LOST,
1383                     DDI_EXTERNAL_FAULT, link_msg);
1384         } else {
1385                 TAVOR_WARNING(state, "Unexpected subtype in port state change "
1386                     "event");
1387                 cmn_err(CE_CONT, "  Event type: %02x, subtype: %02x\n",
1388                     TAVOR_EQE_EVTTYPE_GET(eq, eqe), subtype);
1389                 TAVOR_TNF_EXIT(tavor_port_state_change_handler);
1390                 return (DDI_FAILURE);
1391         }
1392 
1393         /*
1394          * Deliver the event to the IBTF.  Note: If "ts_ibtfpriv" is NULL,
1395          * then we have either received this event before we finished
1396          * attaching to the IBTF or we've received it while we are in the
1397          * process of detaching.
1398          */
1399         if (state->ts_ibtfpriv != NULL) {
1400                 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event);
1401         }
1402 
1403         TAVOR_TNF_EXIT(tavor_port_state_change_handler);
1404         return (DDI_SUCCESS);
1405 }
1406 
1407 
1408 /*
1409  * tavor_comm_estbl_handler()
1410  *    Context: Only called from interrupt context
1411  */
1412 static int
1413 tavor_comm_estbl_handler(tavor_state_t *state, tavor_eqhdl_t eq,
1414     tavor_hw_eqe_t *eqe)
1415 {
1416         tavor_qphdl_t           qp;
1417         uint_t                  qpnum;
1418         ibc_async_event_t       event;
1419         ibt_async_code_t        type;
1420         uint_t                  eqe_evttype;
1421 
1422         TAVOR_TNF_ENTER(tavor_comm_estbl_handler);
1423 
1424         eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe);
1425 
1426         ASSERT(eqe_evttype == TAVOR_EVT_COMM_ESTABLISHED ||
1427             eqe_evttype == TAVOR_EVT_EQ_OVERFLOW);
1428 
1429         if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) {
1430                 TNF_PROBE_0(tavor_comm_estbl_eq_overflow_condition,
1431                     TAVOR_TNF_ERROR, "");
1432                 tavor_eq_overflow_handler(state, eq, eqe);
1433 
1434                 TAVOR_TNF_EXIT(tavor_comm_estbl_handler);
1435                 return (DDI_FAILURE);
1436         }
1437 
1438         /* Get the QP handle from QP number in event descriptor */
1439         qpnum = TAVOR_EQE_QPNUM_GET(eq, eqe);
1440         qp = tavor_qphdl_from_qpnum(state, qpnum);
1441 
1442         /*
1443          * If the QP handle is NULL, this is probably an indication
1444          * that the QP has been freed already.  In which case, we
1445          * should not deliver this event.
1446          *
1447          * We also check that the QP number in the handle is the
1448          * same as the QP number in the event queue entry.  This
1449          * extra check allows us to handle the case where a QP was
1450          * freed and then allocated again in the time it took to
1451          * handle the event queue processing.  By constantly incrementing
1452          * the non-constrained portion of the QP number every time
1453          * a new QP is allocated, we mitigate (somewhat) the chance
1454          * that a stale event could be passed to the client's QP
1455          * handler.
1456          *
1457          * Lastly, we check if "ts_ibtfpriv" is NULL.  If it is then it
1458          * means that we've have either received this event before we
1459          * finished attaching to the IBTF or we've received it while we
1460          * are in the process of detaching.
1461          */
1462         if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
1463             (state->ts_ibtfpriv != NULL)) {
1464                 event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg;
1465                 type            = IBT_EVENT_COM_EST_QP;
1466 
1467                 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event);
1468         } else {
1469                 TNF_PROBE_2(tavor_comm_estbl_handler_dropped_event,
1470                     TAVOR_TNF_ERROR, "", tnf_uint, ev_qpnum, qpnum,
1471                     tnf_uint, hdl_qpnum, qpnum);
1472         }
1473 
1474         TAVOR_TNF_EXIT(tavor_comm_estbl_handler);
1475         return (DDI_SUCCESS);
1476 }
1477 
1478 
1479 /*
1480  * tavor_local_wq_cat_err_handler()
1481  *    Context: Only called from interrupt context
1482  */
1483 static int
1484 tavor_local_wq_cat_err_handler(tavor_state_t *state, tavor_eqhdl_t eq,
1485     tavor_hw_eqe_t *eqe)
1486 {
1487         tavor_qphdl_t           qp;
1488         uint_t                  qpnum;
1489         ibc_async_event_t       event;
1490         ibt_async_code_t        type;
1491         uint_t                  eqe_evttype;
1492 
1493         TAVOR_TNF_ENTER(tavor_local_wq_cat_err_handler);
1494 
1495         eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe);
1496 
1497         ASSERT(eqe_evttype == TAVOR_EVT_LOCAL_WQ_CAT_ERROR ||
1498             eqe_evttype == TAVOR_EVT_EQ_OVERFLOW);
1499 
1500         if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) {
1501                 TNF_PROBE_0(tavor_local_wq_cat_err_eq_overflow_condition,
1502                     TAVOR_TNF_ERROR, "");
1503                 tavor_eq_overflow_handler(state, eq, eqe);
1504 
1505                 TAVOR_TNF_EXIT(tavor_local_wq_cat_err_handler);
1506                 return (DDI_FAILURE);
1507         }
1508 
1509         /* Get the QP handle from QP number in event descriptor */
1510         qpnum = TAVOR_EQE_QPNUM_GET(eq, eqe);
1511         qp = tavor_qphdl_from_qpnum(state, qpnum);
1512 
1513         /*
1514          * If the QP handle is NULL, this is probably an indication
1515          * that the QP has been freed already.  In which case, we
1516          * should not deliver this event.
1517          *
1518          * We also check that the QP number in the handle is the
1519          * same as the QP number in the event queue entry.  This
1520          * extra check allows us to handle the case where a QP was
1521          * freed and then allocated again in the time it took to
1522          * handle the event queue processing.  By constantly incrementing
1523          * the non-constrained portion of the QP number every time
1524          * a new QP is allocated, we mitigate (somewhat) the chance
1525          * that a stale event could be passed to the client's QP
1526          * handler.
1527          *
1528          * Lastly, we check if "ts_ibtfpriv" is NULL.  If it is then it
1529          * means that we've have either received this event before we
1530          * finished attaching to the IBTF or we've received it while we
1531          * are in the process of detaching.
1532          */
1533         if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
1534             (state->ts_ibtfpriv != NULL)) {
1535                 event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg;
1536                 type            = IBT_ERROR_CATASTROPHIC_QP;
1537 
1538                 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event);
1539         } else {
1540                 TNF_PROBE_2(tavor_local_wq_cat_err_handler_dropped_event,
1541                     TAVOR_TNF_ERROR, "", tnf_uint, ev_qpnum, qpnum,
1542                     tnf_uint, hdl_qpnum, qpnum);
1543         }
1544 
1545         TAVOR_TNF_EXIT(tavor_local_wq_cat_err_handler);
1546         return (DDI_SUCCESS);
1547 }
1548 
1549 
1550 /*
1551  * tavor_invreq_local_wq_err_handler()
1552  *    Context: Only called from interrupt context
1553  */
1554 static int
1555 tavor_invreq_local_wq_err_handler(tavor_state_t *state, tavor_eqhdl_t eq,
1556     tavor_hw_eqe_t *eqe)
1557 {
1558         tavor_qphdl_t           qp;
1559         uint_t                  qpnum;
1560         ibc_async_event_t       event;
1561         ibt_async_code_t        type;
1562         uint_t                  eqe_evttype;
1563 
1564         TAVOR_TNF_ENTER(tavor_invreq_local_wq_err_handler);
1565 
1566         eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe);
1567 
1568         ASSERT(eqe_evttype == TAVOR_EVT_INV_REQ_LOCAL_WQ_ERROR ||
1569             eqe_evttype == TAVOR_EVT_EQ_OVERFLOW);
1570 
1571         if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) {
1572                 TNF_PROBE_0(tavor_invreq_local_wq_err_eq_overflow_condition,
1573                     TAVOR_TNF_ERROR, "");
1574                 tavor_eq_overflow_handler(state, eq, eqe);
1575 
1576                 TAVOR_TNF_EXIT(tavor_port_state_change_handler);
1577                 return (DDI_FAILURE);
1578         }
1579 
1580         /* Get the QP handle from QP number in event descriptor */
1581         qpnum = TAVOR_EQE_QPNUM_GET(eq, eqe);
1582         qp = tavor_qphdl_from_qpnum(state, qpnum);
1583 
1584         /*
1585          * If the QP handle is NULL, this is probably an indication
1586          * that the QP has been freed already.  In which case, we
1587          * should not deliver this event.
1588          *
1589          * We also check that the QP number in the handle is the
1590          * same as the QP number in the event queue entry.  This
1591          * extra check allows us to handle the case where a QP was
1592          * freed and then allocated again in the time it took to
1593          * handle the event queue processing.  By constantly incrementing
1594          * the non-constrained portion of the QP number every time
1595          * a new QP is allocated, we mitigate (somewhat) the chance
1596          * that a stale event could be passed to the client's QP
1597          * handler.
1598          *
1599          * Lastly, we check if "ts_ibtfpriv" is NULL.  If it is then it
1600          * means that we've have either received this event before we
1601          * finished attaching to the IBTF or we've received it while we
1602          * are in the process of detaching.
1603          */
1604         if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
1605             (state->ts_ibtfpriv != NULL)) {
1606                 event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg;
1607                 type            = IBT_ERROR_INVALID_REQUEST_QP;
1608 
1609                 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event);
1610         } else {
1611                 TNF_PROBE_2(tavor_invreq_local_wq_err_handler_dropped_event,
1612                     TAVOR_TNF_ERROR, "", tnf_uint, ev_qpnum, qpnum,
1613                     tnf_uint, hdl_qpnum, qpnum);
1614         }
1615 
1616         TAVOR_TNF_EXIT(tavor_invreq_local_wq_err_handler);
1617         return (DDI_SUCCESS);
1618 }
1619 
1620 
1621 /*
1622  * tavor_local_acc_vio_wq_err_handler()
1623  *    Context: Only called from interrupt context
1624  */
1625 static int
1626 tavor_local_acc_vio_wq_err_handler(tavor_state_t *state, tavor_eqhdl_t eq,
1627     tavor_hw_eqe_t *eqe)
1628 {
1629         tavor_qphdl_t           qp;
1630         uint_t                  qpnum;
1631         ibc_async_event_t       event;
1632         ibt_async_code_t        type;
1633         uint_t                  eqe_evttype;
1634 
1635         TAVOR_TNF_ENTER(tavor_local_acc_vio_wq_err_handler);
1636 
1637         eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe);
1638 
1639         ASSERT(eqe_evttype == TAVOR_EVT_LOCAL_ACC_VIO_WQ_ERROR ||
1640             eqe_evttype == TAVOR_EVT_EQ_OVERFLOW);
1641 
1642         if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) {
1643                 TNF_PROBE_0(tavor_local_acc_vio_wq_err_eq_overflow_condition,
1644                     TAVOR_TNF_ERROR, "");
1645                 tavor_eq_overflow_handler(state, eq, eqe);
1646 
1647                 TAVOR_TNF_EXIT(tavor_local_acc_vio_wq_err_handler);
1648                 return (DDI_FAILURE);
1649         }
1650 
1651         /* Get the QP handle from QP number in event descriptor */
1652         qpnum = TAVOR_EQE_QPNUM_GET(eq, eqe);
1653         qp = tavor_qphdl_from_qpnum(state, qpnum);
1654 
1655         /*
1656          * If the QP handle is NULL, this is probably an indication
1657          * that the QP has been freed already.  In which case, we
1658          * should not deliver this event.
1659          *
1660          * We also check that the QP number in the handle is the
1661          * same as the QP number in the event queue entry.  This
1662          * extra check allows us to handle the case where a QP was
1663          * freed and then allocated again in the time it took to
1664          * handle the event queue processing.  By constantly incrementing
1665          * the non-constrained portion of the QP number every time
1666          * a new QP is allocated, we mitigate (somewhat) the chance
1667          * that a stale event could be passed to the client's QP
1668          * handler.
1669          *
1670          * Lastly, we check if "ts_ibtfpriv" is NULL.  If it is then it
1671          * means that we've have either received this event before we
1672          * finished attaching to the IBTF or we've received it while we
1673          * are in the process of detaching.
1674          */
1675         if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
1676             (state->ts_ibtfpriv != NULL)) {
1677                 event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg;
1678                 type            = IBT_ERROR_ACCESS_VIOLATION_QP;
1679 
1680                 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event);
1681         } else {
1682                 TNF_PROBE_2(tavor_local_acc_vio_wq_err_handler_dropped_event,
1683                     TAVOR_TNF_ERROR, "", tnf_uint, ev_qpnum, qpnum,
1684                     tnf_uint, hdl_qpnum, qpnum);
1685         }
1686 
1687         TAVOR_TNF_EXIT(tavor_local_acc_vio_wq_err_handler);
1688         return (DDI_SUCCESS);
1689 }
1690 
1691 
1692 /*
1693  * tavor_sendq_drained_handler()
1694  *    Context: Only called from interrupt context
1695  */
1696 static int
1697 tavor_sendq_drained_handler(tavor_state_t *state, tavor_eqhdl_t eq,
1698     tavor_hw_eqe_t *eqe)
1699 {
1700         tavor_qphdl_t           qp;
1701         uint_t                  qpnum;
1702         ibc_async_event_t       event;
1703         uint_t                  forward_sqd_event;
1704         ibt_async_code_t        type;
1705         uint_t                  eqe_evttype;
1706 
1707         TAVOR_TNF_ENTER(tavor_sendq_drained_handler);
1708 
1709         eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe);
1710 
1711         ASSERT(eqe_evttype == TAVOR_EVT_SEND_QUEUE_DRAINED ||
1712             eqe_evttype == TAVOR_EVT_EQ_OVERFLOW);
1713 
1714         if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) {
1715                 TNF_PROBE_0(tavor_sendq_drained_eq_overflow_condition,
1716                     TAVOR_TNF_ERROR, "");
1717                 tavor_eq_overflow_handler(state, eq, eqe);
1718 
1719                 TAVOR_TNF_EXIT(tavor_sendq_drained_handler);
1720                 return (DDI_FAILURE);
1721         }
1722 
1723         /* Get the QP handle from QP number in event descriptor */
1724         qpnum = TAVOR_EQE_QPNUM_GET(eq, eqe);
1725         qp = tavor_qphdl_from_qpnum(state, qpnum);
1726 
1727         /*
1728          * If the QP handle is NULL, this is probably an indication
1729          * that the QP has been freed already.  In which case, we
1730          * should not deliver this event.
1731          *
1732          * We also check that the QP number in the handle is the
1733          * same as the QP number in the event queue entry.  This
1734          * extra check allows us to handle the case where a QP was
1735          * freed and then allocated again in the time it took to
1736          * handle the event queue processing.  By constantly incrementing
1737          * the non-constrained portion of the QP number every time
1738          * a new QP is allocated, we mitigate (somewhat) the chance
1739          * that a stale event could be passed to the client's QP
1740          * handler.
1741          *
1742          * And then we check if "ts_ibtfpriv" is NULL.  If it is then it
1743          * means that we've have either received this event before we
1744          * finished attaching to the IBTF or we've received it while we
1745          * are in the process of detaching.
1746          */
1747         if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
1748             (state->ts_ibtfpriv != NULL)) {
1749                 event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg;
1750                 type            = IBT_EVENT_SQD;
1751 
1752                 /*
1753                  * Grab the QP lock and update the QP state to reflect that
1754                  * the Send Queue Drained event has arrived.  Also determine
1755                  * whether the event is intended to be forwarded on to the
1756                  * consumer or not.  This information is used below in
1757                  * determining whether or not to call the IBTF.
1758                  */
1759                 mutex_enter(&qp->qp_lock);
1760                 forward_sqd_event = qp->qp_forward_sqd_event;
1761                 qp->qp_forward_sqd_event  = 0;
1762                 qp->qp_sqd_still_draining = 0;
1763                 mutex_exit(&qp->qp_lock);
1764 
1765                 if (forward_sqd_event != 0) {
1766                         TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event);
1767                 }
1768         } else {
1769                 TNF_PROBE_2(tavor_sendq_drained_handler_dropped_event,
1770                     TAVOR_TNF_ERROR, "", tnf_uint, ev_qpnum, qpnum,
1771                     tnf_uint, hdl_qpnum, qpnum);
1772         }
1773 
1774         TAVOR_TNF_EXIT(tavor_sendq_drained_handler);
1775         return (DDI_SUCCESS);
1776 }
1777 
1778 
1779 /*
1780  * tavor_path_mig_handler()
1781  *    Context: Only called from interrupt context
1782  */
1783 static int
1784 tavor_path_mig_handler(tavor_state_t *state, tavor_eqhdl_t eq,
1785     tavor_hw_eqe_t *eqe)
1786 {
1787         tavor_qphdl_t           qp;
1788         uint_t                  qpnum;
1789         ibc_async_event_t       event;
1790         ibt_async_code_t        type;
1791         uint_t                  eqe_evttype;
1792 
1793         TAVOR_TNF_ENTER(tavor_path_mig_handler);
1794 
1795         eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe);
1796 
1797         ASSERT(eqe_evttype == TAVOR_EVT_PATH_MIGRATED ||
1798             eqe_evttype == TAVOR_EVT_EQ_OVERFLOW);
1799 
1800         if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) {
1801                 TNF_PROBE_0(tavor_path_mig_eq_overflow_condition,
1802                     TAVOR_TNF_ERROR, "");
1803                 tavor_eq_overflow_handler(state, eq, eqe);
1804 
1805                 TAVOR_TNF_EXIT(tavor_path_mig_handler);
1806                 return (DDI_FAILURE);
1807         }
1808 
1809         /* Get the QP handle from QP number in event descriptor */
1810         qpnum = TAVOR_EQE_QPNUM_GET(eq, eqe);
1811         qp = tavor_qphdl_from_qpnum(state, qpnum);
1812 
1813         /*
1814          * If the QP handle is NULL, this is probably an indication
1815          * that the QP has been freed already.  In which case, we
1816          * should not deliver this event.
1817          *
1818          * We also check that the QP number in the handle is the
1819          * same as the QP number in the event queue entry.  This
1820          * extra check allows us to handle the case where a QP was
1821          * freed and then allocated again in the time it took to
1822          * handle the event queue processing.  By constantly incrementing
1823          * the non-constrained portion of the QP number every time
1824          * a new QP is allocated, we mitigate (somewhat) the chance
1825          * that a stale event could be passed to the client's QP
1826          * handler.
1827          *
1828          * Lastly, we check if "ts_ibtfpriv" is NULL.  If it is then it
1829          * means that we've have either received this event before we
1830          * finished attaching to the IBTF or we've received it while we
1831          * are in the process of detaching.
1832          */
1833         if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
1834             (state->ts_ibtfpriv != NULL)) {
1835                 event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg;
1836                 type            = IBT_EVENT_PATH_MIGRATED_QP;
1837 
1838                 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event);
1839         } else {
1840                 TNF_PROBE_2(tavor_path_mig_handler_dropped_event,
1841                     TAVOR_TNF_ERROR, "", tnf_uint, ev_qpnum, qpnum,
1842                     tnf_uint, hdl_qpnum, qpnum);
1843         }
1844 
1845         TAVOR_TNF_EXIT(tavor_path_mig_handler);
1846         return (DDI_SUCCESS);
1847 }
1848 
1849 
1850 /*
1851  * tavor_path_mig_err_handler()
1852  *    Context: Only called from interrupt context
1853  */
1854 static int
1855 tavor_path_mig_err_handler(tavor_state_t *state, tavor_eqhdl_t eq,
1856     tavor_hw_eqe_t *eqe)
1857 {
1858         tavor_qphdl_t           qp;
1859         uint_t                  qpnum;
1860         ibc_async_event_t       event;
1861         ibt_async_code_t        type;
1862         uint_t                  eqe_evttype;
1863 
1864         TAVOR_TNF_ENTER(tavor_path_mig_err_handler);
1865 
1866         eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe);
1867 
1868         ASSERT(eqe_evttype == TAVOR_EVT_PATH_MIGRATE_FAILED ||
1869             eqe_evttype == TAVOR_EVT_EQ_OVERFLOW);
1870 
1871         if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) {
1872                 TNF_PROBE_0(tavor_path_mig_err_eq_overflow_condition,
1873                     TAVOR_TNF_ERROR, "");
1874                 tavor_eq_overflow_handler(state, eq, eqe);
1875 
1876                 TAVOR_TNF_EXIT(tavor_path_mig_err_handler);
1877                 return (DDI_FAILURE);
1878         }
1879 
1880         /* Get the QP handle from QP number in event descriptor */
1881         qpnum = TAVOR_EQE_QPNUM_GET(eq, eqe);
1882         qp = tavor_qphdl_from_qpnum(state, qpnum);
1883 
1884         /*
1885          * If the QP handle is NULL, this is probably an indication
1886          * that the QP has been freed already.  In which case, we
1887          * should not deliver this event.
1888          *
1889          * We also check that the QP number in the handle is the
1890          * same as the QP number in the event queue entry.  This
1891          * extra check allows us to handle the case where a QP was
1892          * freed and then allocated again in the time it took to
1893          * handle the event queue processing.  By constantly incrementing
1894          * the non-constrained portion of the QP number every time
1895          * a new QP is allocated, we mitigate (somewhat) the chance
1896          * that a stale event could be passed to the client's QP
1897          * handler.
1898          *
1899          * Lastly, we check if "ts_ibtfpriv" is NULL.  If it is then it
1900          * means that we've have either received this event before we
1901          * finished attaching to the IBTF or we've received it while we
1902          * are in the process of detaching.
1903          */
1904         if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
1905             (state->ts_ibtfpriv != NULL)) {
1906                 event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg;
1907                 type            = IBT_ERROR_PATH_MIGRATE_REQ_QP;
1908 
1909                 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event);
1910         } else {
1911                 TNF_PROBE_2(tavor_path_mig_err_handler_dropped_event,
1912                     TAVOR_TNF_ERROR, "", tnf_uint, ev_qpnum, qpnum,
1913                     tnf_uint, hdl_qpnum, qpnum);
1914         }
1915 
1916         TAVOR_TNF_EXIT(tavor_path_mig_err_handler);
1917         return (DDI_SUCCESS);
1918 }
1919 
1920 
1921 /*
1922  * tavor_srq_catastrophic_handler()
1923  *    Context: Only called from interrupt context
1924  */
1925 static int
1926 tavor_srq_catastrophic_handler(tavor_state_t *state, tavor_eqhdl_t eq,
1927     tavor_hw_eqe_t *eqe)
1928 {
1929         tavor_qphdl_t           qp;
1930         uint_t                  qpnum;
1931         ibc_async_event_t       event;
1932         ibt_async_code_t        type;
1933         uint_t                  eqe_evttype;
1934 
1935         TAVOR_TNF_ENTER(tavor_srq_catastrophic_handler);
1936 
1937         eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe);
1938 
1939         ASSERT(eqe_evttype == TAVOR_EVT_SRQ_CATASTROPHIC_ERROR ||
1940             eqe_evttype == TAVOR_EVT_EQ_OVERFLOW);
1941 
1942         if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) {
1943                 TNF_PROBE_0(tavor_srq_catastrophic_overflow_condition,
1944                     TAVOR_TNF_ERROR, "");
1945                 tavor_eq_overflow_handler(state, eq, eqe);
1946 
1947                 TAVOR_TNF_EXIT(tavor_srq_catastrophic_handler);
1948                 return (DDI_FAILURE);
1949         }
1950 
1951         /* Get the QP handle from QP number in event descriptor */
1952         qpnum = TAVOR_EQE_QPNUM_GET(eq, eqe);
1953         qp = tavor_qphdl_from_qpnum(state, qpnum);
1954 
1955         /*
1956          * If the QP handle is NULL, this is probably an indication
1957          * that the QP has been freed already.  In which case, we
1958          * should not deliver this event.
1959          *
1960          * We also check that the QP number in the handle is the
1961          * same as the QP number in the event queue entry.  This
1962          * extra check allows us to handle the case where a QP was
1963          * freed and then allocated again in the time it took to
1964          * handle the event queue processing.  By constantly incrementing
1965          * the non-constrained portion of the QP number every time
1966          * a new QP is allocated, we mitigate (somewhat) the chance
1967          * that a stale event could be passed to the client's QP
1968          * handler.
1969          *
1970          * Lastly, we check if "ts_ibtfpriv" is NULL.  If it is then it
1971          * means that we've have either received this event before we
1972          * finished attaching to the IBTF or we've received it while we
1973          * are in the process of detaching.
1974          */
1975         if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
1976             (state->ts_ibtfpriv != NULL)) {
1977                 event.ev_srq_hdl = (ibt_srq_hdl_t)qp->qp_srqhdl->srq_hdlrarg;
1978                 type            = IBT_ERROR_CATASTROPHIC_SRQ;
1979 
1980                 mutex_enter(&qp->qp_srqhdl->srq_lock);
1981                 qp->qp_srqhdl->srq_state = TAVOR_SRQ_STATE_ERROR;
1982                 mutex_exit(&qp->qp_srqhdl->srq_lock);
1983 
1984                 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event);
1985         } else {
1986                 TNF_PROBE_2(tavor_srq_catastrophic_handler_dropped_event,
1987                     TAVOR_TNF_ERROR, "", tnf_uint, ev_qpnum, qpnum,
1988                     tnf_uint, hdl_qpnum, qpnum);
1989         }
1990 
1991         TAVOR_TNF_EXIT(tavor_srq_catastrophic_handler);
1992         return (DDI_SUCCESS);
1993 }
1994 
1995 
1996 /*
1997  * tavor_srq_last_wqe_reached_handler()
1998  *    Context: Only called from interrupt context
1999  */
2000 static int
2001 tavor_srq_last_wqe_reached_handler(tavor_state_t *state, tavor_eqhdl_t eq,
2002     tavor_hw_eqe_t *eqe)
2003 {
2004         tavor_qphdl_t           qp;
2005         uint_t                  qpnum;
2006         ibc_async_event_t       event;
2007         ibt_async_code_t        type;
2008         uint_t                  eqe_evttype;
2009 
2010         TAVOR_TNF_ENTER(tavor_srq_last_wqe_reached_handler);
2011 
2012         eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe);
2013 
2014         ASSERT(eqe_evttype == TAVOR_EVT_SRQ_LAST_WQE_REACHED ||
2015             eqe_evttype == TAVOR_EVT_EQ_OVERFLOW);
2016 
2017         if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) {
2018                 TNF_PROBE_0(tavor_srq_last_wqe_reached_over_condition,
2019                     TAVOR_TNF_ERROR, "");
2020                 tavor_eq_overflow_handler(state, eq, eqe);
2021 
2022                 TAVOR_TNF_EXIT(tavor_srq_last_wqe_reached_handler);
2023                 return (DDI_FAILURE);
2024         }
2025 
2026         /* Get the QP handle from QP number in event descriptor */
2027         qpnum = TAVOR_EQE_QPNUM_GET(eq, eqe);
2028         qp = tavor_qphdl_from_qpnum(state, qpnum);
2029 
2030         /*
2031          * If the QP handle is NULL, this is probably an indication
2032          * that the QP has been freed already.  In which case, we
2033          * should not deliver this event.
2034          *
2035          * We also check that the QP number in the handle is the
2036          * same as the QP number in the event queue entry.  This
2037          * extra check allows us to handle the case where a QP was
2038          * freed and then allocated again in the time it took to
2039          * handle the event queue processing.  By constantly incrementing
2040          * the non-constrained portion of the QP number every time
2041          * a new QP is allocated, we mitigate (somewhat) the chance
2042          * that a stale event could be passed to the client's QP
2043          * handler.
2044          *
2045          * Lastly, we check if "ts_ibtfpriv" is NULL.  If it is then it
2046          * means that we've have either received this event before we
2047          * finished attaching to the IBTF or we've received it while we
2048          * are in the process of detaching.
2049          */
2050         if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
2051             (state->ts_ibtfpriv != NULL)) {
2052                 event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg;
2053                 type            = IBT_EVENT_EMPTY_CHAN;
2054 
2055                 TAVOR_DO_IBTF_ASYNC_CALLB(state, type, &event);
2056         } else {
2057                 TNF_PROBE_2(tavor_srq_last_wqe_reached_dropped_event,
2058                     TAVOR_TNF_ERROR, "", tnf_uint, ev_qpnum, qpnum,
2059                     tnf_uint, hdl_qpnum, qpnum);
2060         }
2061 
2062         TAVOR_TNF_EXIT(tavor_srq_last_wqe_reached_handler);
2063         return (DDI_SUCCESS);
2064 }
2065 
2066 
2067 /*
2068  * tavor_ecc_detection_handler()
2069  *    Context: Only called from interrupt context
2070  */
2071 static int
2072 tavor_ecc_detection_handler(tavor_state_t *state, tavor_eqhdl_t eq,
2073     tavor_hw_eqe_t *eqe)
2074 {
2075         uint_t                  eqe_evttype;
2076         uint_t                  data;
2077         int                     i;
2078 
2079         TAVOR_TNF_ENTER(tavor_ecc_detection_handler);
2080 
2081         eqe_evttype = TAVOR_EQE_EVTTYPE_GET(eq, eqe);
2082 
2083         ASSERT(eqe_evttype == TAVOR_EVT_ECC_DETECTION ||
2084             eqe_evttype == TAVOR_EVT_EQ_OVERFLOW);
2085 
2086         if (eqe_evttype == TAVOR_EVT_EQ_OVERFLOW) {
2087                 TNF_PROBE_0(tavor_ecc_detection_eq_overflow_condition,
2088                     TAVOR_TNF_ERROR, "");
2089                 tavor_eq_overflow_handler(state, eq, eqe);
2090 
2091                 TAVOR_TNF_EXIT(tavor_ecc_detection_handler);
2092                 return (DDI_FAILURE);
2093         }
2094 
2095         /*
2096          * The "ECC Detection Event" indicates that a correctable single-bit
2097          * has occurred with the attached DDR.  The EQE provides some
2098          * additional information about the errored EQ.  So we print a warning
2099          * message here along with that additional information.
2100          */
2101         TAVOR_WARNING(state, "ECC Correctable Error Event Detected");
2102         for (i = 0; i < sizeof (tavor_hw_eqe_t) >> 2; i++) {
2103                 data = ((uint_t *)eqe)[i];
2104                 cmn_err(CE_CONT, "!  EQE[%02x]: %08x\n", i, data);
2105         }
2106 
2107         TAVOR_TNF_EXIT(tavor_ecc_detection_handler);
2108         return (DDI_SUCCESS);
2109 }
2110 
2111 
2112 /*
2113  * tavor_eq_overflow_handler()
2114  *    Context: Only called from interrupt context
2115  */
2116 void
2117 tavor_eq_overflow_handler(tavor_state_t *state, tavor_eqhdl_t eq,
2118     tavor_hw_eqe_t *eqe)
2119 {
2120         uint_t          error_type, data;
2121 
2122         TAVOR_TNF_ENTER(tavor_eq_overflow_handler);
2123 
2124         ASSERT(TAVOR_EQE_EVTTYPE_GET(eq, eqe) == TAVOR_EVT_EQ_OVERFLOW);
2125 
2126         /*
2127          * The "Event Queue Overflow Event" indicates that something has
2128          * probably gone seriously wrong with some hardware (or, perhaps,
2129          * with the software... though it's unlikely in this case).  The EQE
2130          * provides some additional information about the errored EQ.  So we
2131          * print a warning message here along with that additional information.
2132          */
2133         error_type = TAVOR_EQE_OPERRTYPE_GET(eq, eqe);
2134         data       = TAVOR_EQE_OPERRDATA_GET(eq, eqe);
2135 
2136         TAVOR_WARNING(state, "Event Queue overflow");
2137         cmn_err(CE_CONT, "  Error type: %02x, data: %08x\n", error_type, data);
2138 
2139         TAVOR_TNF_EXIT(tavor_eq_overflow_handler);
2140 }
2141 
2142 
2143 /*
2144  * tavor_no_eqhandler
2145  *    Context: Only called from interrupt context
2146  */
2147 /* ARGSUSED */
2148 static int
2149 tavor_no_eqhandler(tavor_state_t *state, tavor_eqhdl_t eq,
2150     tavor_hw_eqe_t *eqe)
2151 {
2152         uint_t          data;
2153         int             i;
2154 
2155         TAVOR_TNF_ENTER(tavor_no_eqhandler);
2156 
2157         /*
2158          * This "unexpected event" handler (or "catch-all" handler) will
2159          * receive all events for which no other handler has been registered.
2160          * If we end up here, then something has probably gone seriously wrong
2161          * with the Tavor hardware (or, perhaps, with the software... though
2162          * it's unlikely in this case).  The EQE provides all the information
2163          * about the event.  So we print a warning message here along with
2164          * the contents of the EQE.
2165          */
2166         TAVOR_WARNING(state, "Unexpected Event handler");
2167         cmn_err(CE_CONT, "  Event type: %02x, subtype: %02x\n",
2168             TAVOR_EQE_EVTTYPE_GET(eq, eqe), TAVOR_EQE_EVTSUBTYPE_GET(eq, eqe));
2169         for (i = 0; i < sizeof (tavor_hw_eqe_t) >> 2; i++) {
2170                 data = ((uint_t *)eqe)[i];
2171                 cmn_err(CE_CONT, "  EQE[%02x]: %08x\n", i, data);
2172         }
2173 
2174         TAVOR_TNF_EXIT(tavor_no_eqhandler);
2175         return (DDI_SUCCESS);
2176 }