9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * CDDL HEADER START
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The contents of this file are subject to the terms of the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Common Development and Distribution License (the "License").
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * You may not use this file except in compliance with the License.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * or http://www.opensolaris.org/os/licensing.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * See the License for the specific language governing permissions
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * and limitations under the License.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * When distributing Covered Code, include this CDDL HEADER in each
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If applicable, add the following below this CDDL HEADER, with the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * fields enclosed by brackets "[]" replaced with your own identifying
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * information: Portions Copyright [yyyy] [name of copyright owner]
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * CDDL HEADER END
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_event.c
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Hermon Interrupt and Event Processing Routines
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Implements all the routines necessary for allocating, freeing, and
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handling all of the various event types that the Hermon hardware can
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * generate.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * These routines include the main Hermon interrupt service routine
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * (hermon_isr()) as well as all the code necessary to setup and handle
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * events from each of the many event queues used by the Hermon device.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/types.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/conf.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/ddi.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/sunddi.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/modctl.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/ib/adapters/hermon/hermon.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void hermon_eq_poll(hermon_state_t *state, hermon_eqhdl_t eq);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void hermon_eq_catastrophic(hermon_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int hermon_eq_alloc(hermon_state_t *state, uint32_t log_eq_size,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t intr, hermon_eqhdl_t *eqhdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int hermon_eq_free(hermon_state_t *state, hermon_eqhdl_t *eqhdl);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int hermon_eq_handler_init(hermon_state_t *state, hermon_eqhdl_t eq,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t evt_type_mask, int (*eqfunc)(hermon_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eqhdl_t eq, hermon_hw_eqe_t *eqe));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int hermon_eq_handler_fini(hermon_state_t *state, hermon_eqhdl_t eq);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int hermon_port_state_change_handler(hermon_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eqhdl_t eq, hermon_hw_eqe_t *eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int hermon_comm_estbl_handler(hermon_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eqhdl_t eq, hermon_hw_eqe_t *eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int hermon_local_wq_cat_err_handler(hermon_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eqhdl_t eq, hermon_hw_eqe_t *eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int hermon_invreq_local_wq_err_handler(hermon_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eqhdl_t eq, hermon_hw_eqe_t *eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int hermon_local_acc_vio_wq_err_handler(hermon_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eqhdl_t eq, hermon_hw_eqe_t *eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int hermon_sendq_drained_handler(hermon_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eqhdl_t eq, hermon_hw_eqe_t *eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int hermon_path_mig_handler(hermon_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eqhdl_t eq, hermon_hw_eqe_t *eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int hermon_path_mig_err_handler(hermon_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eqhdl_t eq, hermon_hw_eqe_t *eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int hermon_catastrophic_handler(hermon_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eqhdl_t eq, hermon_hw_eqe_t *eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int hermon_srq_last_wqe_reached_handler(hermon_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eqhdl_t eq, hermon_hw_eqe_t *eqe);
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylorstatic int hermon_fexch_error_handler(hermon_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eqhdl_t eq, hermon_hw_eqe_t *eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int hermon_no_eqhandler(hermon_state_t *state, hermon_eqhdl_t eq,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqe_t *eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int hermon_eq_demux(hermon_state_t *state, hermon_eqhdl_t eq,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqe_t *eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_eq_init_all
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorint
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_eq_init_all(hermon_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t log_eq_size, intr_num;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t num_eq, num_eq_init, num_eq_unmap, num_eq_rsvd;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t event_mask; /* used for multiple event types */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status, i, num_extra;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor struct hermon_sw_eq_s **eq;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_acc_handle_t uarhdl = hermon_get_uarhdl(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* initialize the FMA retry loop */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * For now, all Event Queues default to the same size (pulled from
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the current configuration profile) and are all assigned to the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * same interrupt or MSI. In the future we may support assigning
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * EQs to specific interrupts or MSIs XXX
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor log_eq_size = state->hs_cfg_profile->cp_log_eq_sz;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Total number of supported EQs is fixed. Hermon hardware
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * supports up to 512 EQs, though in theory they will one day be
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * alloc'd to virtual HCA's. We are currently using only 47 of them
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * - that is, in Arbel and Tavor, before HERMON, where
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * we had set aside the first 32 for use with Completion Queues (CQ)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * and reserved a few of the other 32 for each specific class of event
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * However, with the coming of vitualization, we'll have only 4 per
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * potential guest - so, we'll try alloc'ing them differntly
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * (see below for more details).
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_eq = HERMON_NUM_EQ_USED;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor num_eq_rsvd = state->hs_rsvd_eqs;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor eq = &state->hs_eqhdl[num_eq_rsvd];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If MSI is to be used, then set intr_num to the MSI number.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Otherwise, for fixed (i.e. 'legacy') interrupts,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * it is what the card tells us in 'inta_pin'.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->hs_intr_type_chosen == DDI_INTR_TYPE_FIXED) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor intr_num = state->hs_adapter.inta_pin;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_extra = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* If we have more than one MSI-X vector, init them. */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i + 1 < state->hs_intrmsi_allocd; i++) {
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor status = hermon_eq_alloc(state, log_eq_size, i, &eq[i]);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor while (--i >= 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) hermon_eq_handler_fini(state,
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor eq[i]);
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor (void) hermon_eq_free(state, &eq[i]);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor (void) hermon_eq_handler_init(state, eq[i],
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EVT_NO_MASK, hermon_cq_handler);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor intr_num = i;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_extra = i;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Allocate and initialize the rest of the Event Queues to be used.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If any of these EQ allocations fail then jump to the end, cleanup
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * what had been successfully initialized, and return an error.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < num_eq; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_eq_alloc(state, log_eq_size, intr_num,
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor &eq[num_extra + i]);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_eq_init = i;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto all_eq_init_fail;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_eq_init = num_eq;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The "num_eq_unmap" variable is used in any possible failure
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * cleanup (below) to indicate which events queues might require
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * possible event class unmapping.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_eq_unmap = 0;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Setup EQ0 (first avail) for use with Completion Queues. Note: We can
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * cast the return value to void here because, when we use the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * HERMON_EVT_NO_MASK flag, it is not possible for
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_eq_handler_init() to return an error.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor (void) hermon_eq_handler_init(state, eq[num_eq_unmap + num_extra],
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EVT_NO_MASK, hermon_cq_handler);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_eq_unmap++;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Setup EQ1 for handling Completion Queue Error Events.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * These events include things like CQ overflow or CQ access
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * violation errors. If this setup fails for any reason (which, in
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * general, it really never should), then jump to the end, cleanup
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * everything that has been successfully initialized, and return an
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * error.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor status = hermon_eq_handler_init(state, eq[num_eq_unmap + num_extra],
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EVT_MSK_CQ_ERRORS, hermon_cq_err_handler);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto all_eq_init_fail;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor state->hs_cq_erreqnum = num_eq_unmap + num_extra + num_eq_rsvd;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_eq_unmap++;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Setup EQ2 for handling most other things including:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Port State Change Events
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * These events include things like Port Up and Port Down events.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Communication Established Events
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * These events correspond to the IB affiliated asynchronous events
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that are used for connection management
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Path Migration Succeeded Events
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * These evens corresponid to the IB affiliated asynchronous events
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that are used to indicate successful completion of a
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Path Migration.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Command Completion Events
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * These events correspond to the Arbel generated events that are used
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * to indicate Arbel firmware command completion.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Local WQ Catastrophic Error Events
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Invalid Req Local WQ Error Events
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Local Access Violation WQ Error Events
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * SRQ Catastrophic Error Events
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * SRQ Last WQE Reached Events
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * ECC error detection events
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * These events also correspond to the similarly-named IB affiliated
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * asynchronous error type.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Send Queue Drained Events
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * These events correspond to the IB affiliated asynchronous events
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that are used to indicate completion of a Send Queue Drained QP
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * state transition.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Path Migration Failed Events
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * These events correspond to the IB affiliated asynchronous events
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that are used to indicate that path migration was not successful.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * Fibre Channel Error Event
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * This event is affiliated with an Fexch QP.
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * NOTE: When an event fires on this EQ, it will demux the type and
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * send it to the right specific handler routine
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor event_mask =
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EVT_MSK_PORT_STATE_CHANGE |
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EVT_MSK_COMM_ESTABLISHED |
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EVT_MSK_COMMAND_INTF_COMP |
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EVT_MSK_LOCAL_WQ_CAT_ERROR |
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EVT_MSK_INV_REQ_LOCAL_WQ_ERROR |
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EVT_MSK_LOCAL_ACC_VIO_WQ_ERROR |
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EVT_MSK_SEND_QUEUE_DRAINED |
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EVT_MSK_PATH_MIGRATED |
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EVT_MSK_PATH_MIGRATE_FAILED |
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EVT_MSK_SRQ_CATASTROPHIC_ERROR |
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EVT_MSK_SRQ_LAST_WQE_REACHED |
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor HERMON_EVT_MSK_FEXCH_ERROR;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor status = hermon_eq_handler_init(state, eq[num_eq_unmap + num_extra],
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor event_mask, hermon_eq_demux);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto all_eq_init_fail;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_eq_unmap++;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Setup EQ3 to catch all other types of events. Specifically, we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * do not catch the "Local EEC Catastrophic Error Event" because we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * should have no EEC (the Arbel driver does not support RD). We also
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * choose not to handle any of the address translation page fault
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * event types. Since we are not doing any page fault handling (and
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * since the Arbel firmware does not currently support any such
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handling), we allow these events to go to the catch-all handler.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor status = hermon_eq_handler_init(state, eq[num_eq_unmap + num_extra],
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EVT_CATCHALL_MASK, hermon_no_eqhandler);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto all_eq_init_fail;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_eq_unmap++;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* the FMA retry loop starts. */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pio_start(state, uarhdl, all_eq_init_fail, fm_loop_cnt,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor fm_status, fm_test);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Run through and initialize the Consumer Index for each EQC.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < num_eq + num_extra; i++) {
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor ddi_put32(uarhdl, eq[i]->eq_doorbell, 0x0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* the FMA retry loop ends. */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pio_end(state, uarhdl, all_eq_init_fail, fm_loop_cnt,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor fm_status, fm_test);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorall_eq_init_fail:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Unmap any of the partially mapped EQs from above */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < num_eq_unmap + num_extra; i++) {
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor (void) hermon_eq_handler_fini(state, eq[i]);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free up any of the partially allocated EQs from above */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < num_eq_init + num_extra; i++) {
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor (void) hermon_eq_free(state, &eq[i]);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* If a HW error happen during ddi_pio, return DDI_FAILURE */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (fm_status == HCA_PIO_PERSISTENT) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_NON_FATAL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = DDI_FAILURE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_eq_fini_all
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() and/or detach() path contexts
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorint
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_eq_fini_all(hermon_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t num_eq, num_eq_rsvd;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status, i;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor struct hermon_sw_eq_s **eq;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Grab the total number of supported EQs again. This is the same
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hardcoded value that was used above (during the event queue
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * initialization.)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_eq = HERMON_NUM_EQ_USED + state->hs_intrmsi_allocd - 1;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor num_eq_rsvd = state->hs_rsvd_eqs;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor eq = &state->hs_eqhdl[num_eq_rsvd];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * For each of the event queues that we initialized and mapped
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * earlier, attempt to unmap the events from the EQ.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < num_eq; i++) {
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor status = hermon_eq_handler_fini(state, eq[i]);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Teardown and free up all the Event Queues that were allocated
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * earlier.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < num_eq; i++) {
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor status = hermon_eq_free(state, &eq[i]);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * hermon_eq_reset_uar_baseaddr
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * Context: Only called from attach()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorvoid
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylorhermon_eq_reset_uar_baseaddr(hermon_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor int i, num_eq;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor hermon_eqhdl_t eq, *eqh;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor num_eq = HERMON_NUM_EQ_USED + state->hs_intrmsi_allocd - 1;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor eqh = &state->hs_eqhdl[state->hs_rsvd_eqs];
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor for (i = 0; i < num_eq; i++) {
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor eq = eqh[i];
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor eq->eq_doorbell = (uint32_t *)
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor ((uintptr_t)state->hs_reg_uar_baseaddr +
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor (uint32_t)ARM_EQ_INDEX(eq->eq_eqnum));
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_eq_arm_all
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() and/or detach() path contexts
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorint
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_eq_arm_all(hermon_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t num_eq, num_eq_rsvd;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint64_t offset;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eqhdl_t eq;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t eq_ci;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int i;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_acc_handle_t uarhdl = hermon_get_uarhdl(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* initialize the FMA retry loop */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor num_eq = HERMON_NUM_EQ_USED + state->hs_intrmsi_allocd - 1;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor num_eq_rsvd = state->hs_rsvd_eqs;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* the FMA retry loop starts. */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pio_start(state, uarhdl, pio_error, fm_loop_cnt, fm_status,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor fm_test);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < num_eq; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor offset = ARM_EQ_INDEX(i + num_eq_rsvd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eq = state->hs_eqhdl[i + num_eq_rsvd];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eq_ci = (eq->eq_consindx & HERMON_EQ_CI_MASK) | EQ_ARM_BIT;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_put32(uarhdl,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (uint32_t *)((uintptr_t)state->hs_reg_uar_baseaddr +
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (uint32_t)offset), eq_ci);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* the FMA retry loop ends. */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pio_end(state, uarhdl, pio_error, fm_loop_cnt, fm_status,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor fm_test);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorpio_error:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_NON_FATAL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_isr()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from interrupt context (and during panic)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Tayloruint_t
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_isr(caddr_t arg1, caddr_t arg2)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_state_t *state;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int i, r;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int intr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Grab the Hermon softstate pointer from the input parameter
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state = (hermon_state_t *)(void *)arg1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get the interrupt number */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor intr = (int)(uintptr_t)arg2;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Clear the interrupt. Note: This is only needed for
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * fixed interrupts as the framework does what is needed for
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * MSI-X interrupts.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->hs_intr_type_chosen == DDI_INTR_TYPE_FIXED) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_acc_handle_t cmdhdl = hermon_get_cmdhdl(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* initialize the FMA retry loop */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* the FMA retry loop starts. */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pio_start(state, cmdhdl, pio_error, fm_loop_cnt,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor fm_status, fm_test);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_put64(cmdhdl, state->hs_cmd_regs.clr_intr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (uint64_t)1 << state->hs_adapter.inta_pin);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* the FMA retry loop ends. */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pio_end(state, cmdhdl, pio_error, fm_loop_cnt, fm_status,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor fm_test);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Loop through all the EQs looking for ones that have "fired".
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * To determine if an EQ is fired, the ownership will be the SW
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * (the HW will set the owner appropriately). Update the Consumer Index
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * of the Event Queue Entry (EQE) and pass it to HW by writing it
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * to the respective Set CI DB Register.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The "else" case handles the extra EQs used only for completion
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * events, whereas the "if" case deals with the required interrupt
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * vector that is used for all classes of events.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor r = state->hs_rsvd_eqs;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (intr + 1 == state->hs_intrmsi_allocd) { /* last intr */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor r += state->hs_intrmsi_allocd - 1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < HERMON_NUM_EQ_USED; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eq_poll(state, state->hs_eqhdl[i + r]);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else { /* only poll the one EQ */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eq_poll(state, state->hs_eqhdl[intr + r]);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_INTR_CLAIMED);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorpio_error:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_FATAL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_INTR_UNCLAIMED);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_eq_poll
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from interrupt context (and during panic)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_eq_poll(hermon_state_t *state, hermon_eqhdl_t eq)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqe_t *eqe;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int polled_some;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor uint32_t cons_indx, wrap_around_mask, shift;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int (*eqfunction)(hermon_state_t *state, hermon_eqhdl_t eq,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqe_t *eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_acc_handle_t uarhdl = hermon_get_uarhdl(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* initialize the FMA retry loop */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*eq))
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get the consumer pointer index */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cons_indx = eq->eq_consindx;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor shift = eq->eq_log_eqsz - HERMON_EQE_OWNER_SHIFT;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Calculate the wrap around mask. Note: This operation only works
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * because all Hermon event queues have power-of-2 sizes
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor wrap_around_mask = (eq->eq_bufsz - 1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Calculate the pointer to the first EQ entry */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eqe = &eq->eq_buf[(cons_indx & wrap_around_mask)];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*eqe))
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Pull the handler function for this EQ from the Hermon Event Queue
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handle
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eqfunction = eq->eq_func;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (;;) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor polled_some = 0;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor while (HERMON_EQE_OWNER_IS_SW(eq, eqe, cons_indx, shift)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Call the EQ handler function. But only call if we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * are not in polled I/O mode (i.e. not processing
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * because of a system panic). Note: We don't call
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the EQ handling functions from a system panic
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * because we are primarily concerned only with
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * ensuring that the event queues do not overflow (or,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * more specifically, the event queue associated with
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the CQ that is being used in the sync/dump process).
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Also, we don't want to make any upcalls (to the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * IBTF) because we can't guarantee when/if those
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * calls would ever return. And, if we're in panic,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * then we reached here through a PollCQ() call (from
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_cq_poll()), and we need to ensure that we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * successfully return any work completions to the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * caller.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ddi_in_panic() == 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eqfunction(state, eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Reset to hardware ownership is implicit */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Increment the consumer index */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cons_indx++;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Update the pointer to the next EQ entry */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eqe = &eq->eq_buf[(cons_indx & wrap_around_mask)];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor polled_some = 1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * write consumer index via EQ set CI Doorbell, to keep overflow
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * from occuring during poll
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eq->eq_consindx = cons_indx;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* the FMA retry loop starts. */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pio_start(state, uarhdl, pio_error, fm_loop_cnt,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor fm_status, fm_test);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor ddi_put32(uarhdl, eq->eq_doorbell,
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor (cons_indx & HERMON_EQ_CI_MASK) | EQ_ARM_BIT);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* the FMA retry loop starts. */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pio_end(state, uarhdl, pio_error, fm_loop_cnt,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor fm_status, fm_test);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (polled_some == 0)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor };
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorpio_error:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_FATAL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_eq_catastrophic
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from interrupt context (and during panic)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_eq_catastrophic(hermon_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_acc_handle_t cmdhdl = hermon_get_cmdhdl(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibt_async_code_t type;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_async_event_t event;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t *base_addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t buf_size;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t word;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint8_t err_type;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t err_buf;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int i;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* initialize the FMA retry loop */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor bzero(&event, sizeof (ibc_async_event_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor base_addr = state->hs_cmd_regs.fw_err_buf;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor buf_size = state->hs_fw.error_buf_sz; /* in #dwords */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* the FMA retry loop starts. */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pio_start(state, cmdhdl, pio_error, fm_loop_cnt, fm_status,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor fm_test);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor word = ddi_get32(cmdhdl, base_addr);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* the FMA retry loop ends. */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pio_end(state, cmdhdl, pio_error, fm_loop_cnt, fm_status,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor fm_test);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor err_type = (word & 0xFF000000) >> 24;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor type = IBT_ERROR_LOCAL_CATASTROPHIC;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor switch (err_type) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case HERMON_CATASTROPHIC_INTERNAL_ERROR:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_WARN, "Catastrophic Internal Error: 0x%02x",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor err_type);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case HERMON_CATASTROPHIC_UPLINK_BUS_ERROR:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_WARN, "Catastrophic Uplink Bus Error: 0x%02x",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor err_type);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case HERMON_CATASTROPHIC_DDR_DATA_ERROR:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_WARN, "Catastrophic DDR Data Error: 0x%02x",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor err_type);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case HERMON_CATASTROPHIC_INTERNAL_PARITY_ERROR:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_WARN, "Catastrophic Internal Parity Error: 0x%02x",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor err_type);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor default:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Unknown type of Catastrophic error */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_WARN, "Catastrophic Unknown Error: 0x%02x",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor err_type);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* the FMA retry loop starts. */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pio_start(state, cmdhdl, pio_error, fm_loop_cnt, fm_status,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor fm_test);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Read in the catastrophic error buffer from the hardware.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < buf_size; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor base_addr =
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (state->hs_cmd_regs.fw_err_buf + i);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor err_buf = ddi_get32(cmdhdl, base_addr);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_NOTE, "hermon%d: catastrophic_error[%02x]: %08X",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->hs_instance, i, err_buf);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* the FMA retry loop ends. */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pio_end(state, cmdhdl, pio_error, fm_loop_cnt, fm_status,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor fm_test);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * We also call the IBTF here to inform it of the catastrophic error.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Note: Since no event information (i.e. QP handles, CQ handles,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * etc.) is necessary, we pass a NULL pointer instead of a pointer to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * an empty ibc_async_event_t struct.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * But we also check if "hs_ibtfpriv" is NULL. If it is then it
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * means that we've have either received this event before we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * finished attaching to the IBTF or we've received it while we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * are in the process of detaching.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->hs_ibtfpriv != NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_DO_IBTF_ASYNC_CALLB(state, type, &event);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorpio_error:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* ignore these errors but log them because they're harmless. */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_NON_FATAL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_eq_alloc()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_eq_alloc(hermon_state_t *state, uint32_t log_eq_size, uint_t intr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eqhdl_t *eqhdl)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_rsrc_t *eqc, *rsrc;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqc_t eqc_entry;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eqhdl_t eq;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibt_mr_attr_t mr_attr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_mr_options_t op;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pdhdl_t pd;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_mrhdl_t mr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqe_t *buf;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Use the internal protection domain (PD) for setting up EQs */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pd = state->hs_pdhdl_internal;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Increment the reference count on the protection domain (PD) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pd_refcnt_inc(pd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Allocate an EQ context entry. This will be filled in with all
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the necessary parameters to define the Event Queue. And then
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * ownership will be passed to the hardware in the final step
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * below. If we fail here, we must undo the protection domain
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * reference count.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_rsrc_alloc(state, HERMON_EQC, 1, HERMON_SLEEP, &eqc);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = DDI_FAILURE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto eqalloc_fail1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Allocate the software structure for tracking the event queue (i.e.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the Hermon Event Queue handle). If we fail here, we must undo the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * protection domain reference count and the previous resource
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * allocation.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_rsrc_alloc(state, HERMON_EQHDL, 1, HERMON_SLEEP, &rsrc);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = DDI_FAILURE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto eqalloc_fail2;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eq = (hermon_eqhdl_t)rsrc->hr_addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Allocate the memory for Event Queue.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eq->eq_eqinfo.qa_size = (1 << log_eq_size) * sizeof (hermon_hw_eqe_t);
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor eq->eq_eqinfo.qa_alloc_align = eq->eq_eqinfo.qa_bind_align = PAGESIZE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eq->eq_eqinfo.qa_location = HERMON_QUEUE_LOCATION_NORMAL;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_queue_alloc(state, &eq->eq_eqinfo, HERMON_SLEEP);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = DDI_FAILURE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto eqalloc_fail3;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor buf = (hermon_hw_eqe_t *)eq->eq_eqinfo.qa_buf_aligned;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Initializing each of the Event Queue Entries (EQE) by setting their
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * ownership to hardware ("owner" bit set to HW) is now done by HW
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * when the transfer of ownership (below) of the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * EQ context itself is done.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Register the memory for the EQ.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Because we are in the attach path we use NOSLEEP here so that we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * SPIN in the HCR since the event queues are not setup yet, and we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * cannot NOSPIN at this point in time.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mr_attr.mr_vaddr = (uint64_t)(uintptr_t)buf;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mr_attr.mr_len = eq->eq_eqinfo.qa_size;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mr_attr.mr_as = NULL;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mr_attr.mr_flags = IBT_MR_NOSLEEP | IBT_MR_ENABLE_LOCAL_WRITE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor op.mro_bind_type = state->hs_cfg_profile->cp_iommu_bypass;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor op.mro_bind_dmahdl = eq->eq_eqinfo.qa_dmahdl;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor op.mro_bind_override_addr = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_mr_register(state, pd, &mr_attr, &mr, &op,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EQ_CMPT);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = DDI_FAILURE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto eqalloc_fail4;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*mr))
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Fill in the EQC entry. This is the final step before passing
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * ownership of the EQC entry to the Hermon hardware. We use all of
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the information collected/calculated above to fill in the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * requisite portions of the EQC. Note: We create all EQs in the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * "fired" state. We will arm them later (after our interrupt
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * routine had been registered.)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor bzero(&eqc_entry, sizeof (hermon_hw_eqc_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eqc_entry.state = HERMON_EQ_ARMED;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eqc_entry.log_eq_sz = log_eq_size;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eqc_entry.intr = intr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eqc_entry.log2_pgsz = mr->mr_log2_pgsz;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eqc_entry.pg_offs = eq->eq_eqinfo.qa_pgoffs >> 5;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eqc_entry.mtt_base_addrh = (uint32_t)((mr->mr_mttaddr >> 32) & 0xFF);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eqc_entry.mtt_base_addrl = mr->mr_mttaddr >> 3;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eqc_entry.cons_indx = 0x0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eqc_entry.prod_indx = 0x0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Write the EQC entry to hardware. Lastly, we pass ownership of
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the entry to the hardware (using the Hermon SW2HW_EQ firmware
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * command). Note: in general, this operation shouldn't fail. But
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * if it does, we have to undo everything we've done above before
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * returning error.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_cmn_ownership_cmd_post(state, SW2HW_EQ, &eqc_entry,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sizeof (hermon_hw_eqc_t), eqc->hr_indx, HERMON_CMD_NOSLEEP_SPIN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != HERMON_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_NOTE, "hermon%d: SW2HW_EQ command failed: %08x\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->hs_instance, status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status == HERMON_CMD_INVALID_STATUS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_fm_ereport(state, HCA_SYS_ERR, HCA_ERR_SRV_LOST);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ibc_get_ci_failure(0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto eqalloc_fail5;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Fill in the rest of the Hermon Event Queue handle. Having
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * successfully transferred ownership of the EQC, we can update the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * following fields for use in further operations on the EQ.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eq->eq_eqcrsrcp = eqc;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eq->eq_rsrcp = rsrc;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eq->eq_consindx = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eq->eq_eqnum = eqc->hr_indx;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eq->eq_buf = buf;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eq->eq_bufsz = (1 << log_eq_size);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eq->eq_log_eqsz = log_eq_size;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eq->eq_mrhdl = mr;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor eq->eq_doorbell = (uint32_t *)((uintptr_t)state->hs_reg_uar_baseaddr +
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor (uint32_t)ARM_EQ_INDEX(eq->eq_eqnum));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *eqhdl = eq;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The following is cleanup for all possible failure cases in this routine
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Tayloreqalloc_fail5:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (hermon_mr_deregister(state, &mr, HERMON_MR_DEREG_ALL,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_NOSLEEP) != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_WARNING(state, "failed to deregister EQ memory");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Tayloreqalloc_fail4:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_queue_free(&eq->eq_eqinfo);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Tayloreqalloc_fail3:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_rsrc_free(state, &rsrc);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Tayloreqalloc_fail2:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_rsrc_free(state, &eqc);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Tayloreqalloc_fail1:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pd_refcnt_dec(pd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Tayloreqalloc_fail:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_eq_free()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() and/or detach() path contexts
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_eq_free(hermon_state_t *state, hermon_eqhdl_t *eqhdl)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_rsrc_t *eqc, *rsrc;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqc_t eqc_entry;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pdhdl_t pd;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_mrhdl_t mr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eqhdl_t eq;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t eqnum;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Pull all the necessary information from the Hermon Event Queue
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handle. This is necessary here because the resource for the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * EQ handle is going to be freed up as part of this operation.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eq = *eqhdl;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eqc = eq->eq_eqcrsrcp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rsrc = eq->eq_rsrcp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pd = state->hs_pdhdl_internal;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mr = eq->eq_mrhdl;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eqnum = eq->eq_eqnum;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Reclaim EQC entry from hardware (using the Hermon HW2SW_EQ
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * firmware command). If the ownership transfer fails for any reason,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * then it is an indication that something (either in HW or SW) has
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * gone seriously wrong.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_cmn_ownership_cmd_post(state, HW2SW_EQ, &eqc_entry,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sizeof (hermon_hw_eqc_t), eqnum, HERMON_CMD_NOSLEEP_SPIN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != HERMON_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_WARNING(state, "failed to reclaim EQC ownership");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Hermon: HW2SW_EQ command failed: %08x\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Deregister the memory for the Event Queue. If this fails
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * for any reason, then it is an indication that something (either
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * in HW or SW) has gone seriously wrong. So we print a warning
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * message and continue.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_mr_deregister(state, &mr, HERMON_MR_DEREG_ALL,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_NOSLEEP);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_WARNING(state, "failed to deregister EQ memory");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free the memory for the EQ */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_queue_free(&eq->eq_eqinfo);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free the Hermon Event Queue handle */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_rsrc_free(state, &rsrc);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free up the EQC entry resource */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_rsrc_free(state, &eqc);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Decrement the reference count on the protection domain (PD) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_pd_refcnt_dec(pd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Set the eqhdl pointer to NULL and return success */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *eqhdl = NULL;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_eq_handler_init
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_eq_handler_init(hermon_state_t *state, hermon_eqhdl_t eq,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t evt_type_mask, int (*eq_func)(hermon_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eqhdl_t eq, hermon_hw_eqe_t *eqe))
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Save away the EQ handler function and the event type mask. These
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * will be used later during interrupt and event queue processing.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eq->eq_func = eq_func;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eq->eq_evttypemask = evt_type_mask;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Map the EQ to a specific class of event (or events) depending
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * on the mask value passed in. The HERMON_EVT_NO_MASK means not
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * to attempt associating the EQ with any specific class of event.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * This is particularly useful when initializing the events queues
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * used for CQ events. The mapping is done using the Hermon MAP_EQ
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * firmware command. Note: This command should not, in general, fail.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If it does, then something (probably HW related) has gone seriously
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * wrong.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (evt_type_mask != HERMON_EVT_NO_MASK) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_map_eq_cmd_post(state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_CMD_MAP_EQ_EVT_MAP, eq->eq_eqnum, evt_type_mask,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_CMD_NOSLEEP_SPIN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != HERMON_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_NOTE, "hermon%d: MAP_EQ command failed: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "%08x\n", state->hs_instance, status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_eq_handler_fini
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() and/or detach() path contexts
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_eq_handler_fini(hermon_state_t *state, hermon_eqhdl_t eq)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Unmap the EQ from the event class to which it had been previously
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * mapped. The unmapping is done using the Hermon MAP_EQ (in much
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the same way that the initial mapping was done). The difference,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * however, is in the HERMON_EQ_EVT_UNMAP flag that is passed to the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * MAP_EQ firmware command. The HERMON_EVT_NO_MASK (which may have
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * been passed in at init time) still means that no association has
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * been made between the EQ and any specific class of event (and,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hence, no unmapping is necessary). Note: This command should not,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * in general, fail. If it does, then something (probably HW related)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * has gone seriously wrong.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (eq->eq_evttypemask != HERMON_EVT_NO_MASK) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_map_eq_cmd_post(state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_CMD_MAP_EQ_EVT_UNMAP, eq->eq_eqnum,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eq->eq_evttypemask, HERMON_CMD_NOSLEEP_SPIN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != HERMON_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_NOTE, "hermon%d: MAP_EQ command failed: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "%08x\n", state->hs_instance, status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_eq_demux()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Called only from interrupt context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Usage: to demux the various type reported on one EQ
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_eq_demux(hermon_state_t *state, hermon_eqhdl_t eq,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqe_t *eqe)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t eqe_evttype;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status = DDI_FAILURE;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor eqe_evttype = HERMON_EQE_EVTTYPE_GET(eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor switch (eqe_evttype) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case HERMON_EVT_PORT_STATE_CHANGE:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_port_state_change_handler(state, eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case HERMON_EVT_COMM_ESTABLISHED:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_comm_estbl_handler(state, eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case HERMON_EVT_COMMAND_INTF_COMP:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_cmd_complete_handler(state, eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case HERMON_EVT_LOCAL_WQ_CAT_ERROR:
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor HERMON_WARNING(state, HERMON_FMA_LOCCAT);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_local_wq_cat_err_handler(state, eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case HERMON_EVT_INV_REQ_LOCAL_WQ_ERROR:
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor HERMON_WARNING(state, HERMON_FMA_LOCINV);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_invreq_local_wq_err_handler(state, eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case HERMON_EVT_LOCAL_ACC_VIO_WQ_ERROR:
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor HERMON_WARNING(state, HERMON_FMA_LOCACEQ);
c7facc54c4abed9e554ff80225311e6b7048d3c9Bill Taylor IBTF_DPRINTF_L2("async", HERMON_FMA_LOCACEQ);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_local_acc_vio_wq_err_handler(state, eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case HERMON_EVT_SEND_QUEUE_DRAINED:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_sendq_drained_handler(state, eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case HERMON_EVT_PATH_MIGRATED:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_path_mig_handler(state, eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case HERMON_EVT_PATH_MIGRATE_FAILED:
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor HERMON_WARNING(state, HERMON_FMA_PATHMIG);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_path_mig_err_handler(state, eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case HERMON_EVT_SRQ_CATASTROPHIC_ERROR:
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor HERMON_WARNING(state, HERMON_FMA_SRQCAT);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_catastrophic_handler(state, eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor case HERMON_EVT_SRQ_LAST_WQE_REACHED:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = hermon_srq_last_wqe_reached_handler(state, eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor case HERMON_EVT_FEXCH_ERROR:
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor status = hermon_fexch_error_handler(state, eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor default:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor break;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_port_state_change_handler()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from interrupt context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor/* ARGSUSED */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_port_state_change_handler(hermon_state_t *state, hermon_eqhdl_t eq,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqe_t *eqe)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_async_event_t event;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibt_async_code_t type;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t subtype;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint8_t port;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor char link_msg[24];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Depending on the type of Port State Change event, pass the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * appropriate asynch event to the IBTF.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor port = (uint8_t)HERMON_EQE_PORTNUM_GET(eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Check for valid port number in event */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((port == 0) || (port > state->hs_cfg_profile->cp_num_ports)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_WARNING(state, "Unexpected port number in port state "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "change event");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, " Port number: %02x\n", port);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor subtype = HERMON_EQE_EVTSUBTYPE_GET(eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (subtype == HERMON_PORT_LINK_ACTIVE) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor event.ev_port = port;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor type = IBT_EVENT_PORT_UP;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) snprintf(link_msg, 23, "port %d up", port);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_dev_report_fault(state->hs_dip, DDI_SERVICE_RESTORED,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DDI_EXTERNAL_FAULT, link_msg);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else if (subtype == HERMON_PORT_LINK_DOWN) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor event.ev_port = port;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor type = IBT_ERROR_PORT_DOWN;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) snprintf(link_msg, 23, "port %d down", port);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_dev_report_fault(state->hs_dip, DDI_SERVICE_LOST,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DDI_EXTERNAL_FAULT, link_msg);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_WARNING(state, "Unexpected subtype in port state change "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "event");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, " Event type: %02x, subtype: %02x\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EQE_EVTTYPE_GET(eq, eqe), subtype);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Deliver the event to the IBTF. Note: If "hs_ibtfpriv" is NULL,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * then we have either received this event before we finished
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * attaching to the IBTF or we've received it while we are in the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * process of detaching.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->hs_ibtfpriv != NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_DO_IBTF_ASYNC_CALLB(state, type, &event);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_comm_estbl_handler()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from interrupt context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor/* ARGSUSED */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_comm_estbl_handler(hermon_state_t *state, hermon_eqhdl_t eq,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqe_t *eqe)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_qphdl_t qp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t qpnum;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_async_event_t event;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibt_async_code_t type;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get the QP handle from QP number in event descriptor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qpnum = HERMON_EQE_QPNUM_GET(eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qp = hermon_qphdl_from_qpnum(state, qpnum);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If the QP handle is NULL, this is probably an indication
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that the QP has been freed already. In which case, we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * should not deliver this event.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * We also check that the QP number in the handle is the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * same as the QP number in the event queue entry. This
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * extra check allows us to handle the case where a QP was
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * freed and then allocated again in the time it took to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handle the event queue processing. By constantly incrementing
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the non-constrained portion of the QP number every time
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * a new QP is allocated, we mitigate (somewhat) the chance
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that a stale event could be passed to the client's QP
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handler.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Lastly, we check if "hs_ibtfpriv" is NULL. If it is then it
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * means that we've have either received this event before we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * finished attaching to the IBTF or we've received it while we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * are in the process of detaching.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (state->hs_ibtfpriv != NULL)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor type = IBT_EVENT_COM_EST_QP;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_DO_IBTF_ASYNC_CALLB(state, type, &event);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_local_wq_cat_err_handler()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from interrupt context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor/* ARGSUSED */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_local_wq_cat_err_handler(hermon_state_t *state, hermon_eqhdl_t eq,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqe_t *eqe)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_qphdl_t qp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t qpnum;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_async_event_t event;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibt_async_code_t type;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get the QP handle from QP number in event descriptor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qpnum = HERMON_EQE_QPNUM_GET(eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qp = hermon_qphdl_from_qpnum(state, qpnum);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If the QP handle is NULL, this is probably an indication
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that the QP has been freed already. In which case, we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * should not deliver this event.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * We also check that the QP number in the handle is the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * same as the QP number in the event queue entry. This
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * extra check allows us to handle the case where a QP was
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * freed and then allocated again in the time it took to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handle the event queue processing. By constantly incrementing
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the non-constrained portion of the QP number every time
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * a new QP is allocated, we mitigate (somewhat) the chance
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that a stale event could be passed to the client's QP
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handler.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Lastly, we check if "hs_ibtfpriv" is NULL. If it is then it
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * means that we've have either received this event before we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * finished attaching to the IBTF or we've received it while we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * are in the process of detaching.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (state->hs_ibtfpriv != NULL)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor type = IBT_ERROR_CATASTROPHIC_QP;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_DO_IBTF_ASYNC_CALLB(state, type, &event);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_invreq_local_wq_err_handler()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from interrupt context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor/* ARGSUSED */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_invreq_local_wq_err_handler(hermon_state_t *state, hermon_eqhdl_t eq,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqe_t *eqe)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_qphdl_t qp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t qpnum;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_async_event_t event;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibt_async_code_t type;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get the QP handle from QP number in event descriptor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qpnum = HERMON_EQE_QPNUM_GET(eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qp = hermon_qphdl_from_qpnum(state, qpnum);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If the QP handle is NULL, this is probably an indication
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that the QP has been freed already. In which case, we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * should not deliver this event.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * We also check that the QP number in the handle is the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * same as the QP number in the event queue entry. This
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * extra check allows us to handle the case where a QP was
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * freed and then allocated again in the time it took to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handle the event queue processing. By constantly incrementing
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the non-constrained portion of the QP number every time
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * a new QP is allocated, we mitigate (somewhat) the chance
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that a stale event could be passed to the client's QP
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handler.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Lastly, we check if "hs_ibtfpriv" is NULL. If it is then it
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * means that we've have either received this event before we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * finished attaching to the IBTF or we've received it while we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * are in the process of detaching.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (state->hs_ibtfpriv != NULL)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor type = IBT_ERROR_INVALID_REQUEST_QP;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_DO_IBTF_ASYNC_CALLB(state, type, &event);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_local_acc_vio_wq_err_handler()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from interrupt context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor/* ARGSUSED */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_local_acc_vio_wq_err_handler(hermon_state_t *state, hermon_eqhdl_t eq,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqe_t *eqe)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_qphdl_t qp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t qpnum;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_async_event_t event;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibt_async_code_t type;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get the QP handle from QP number in event descriptor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qpnum = HERMON_EQE_QPNUM_GET(eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qp = hermon_qphdl_from_qpnum(state, qpnum);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If the QP handle is NULL, this is probably an indication
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that the QP has been freed already. In which case, we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * should not deliver this event.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * We also check that the QP number in the handle is the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * same as the QP number in the event queue entry. This
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * extra check allows us to handle the case where a QP was
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * freed and then allocated again in the time it took to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handle the event queue processing. By constantly incrementing
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the non-constrained portion of the QP number every time
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * a new QP is allocated, we mitigate (somewhat) the chance
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that a stale event could be passed to the client's QP
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handler.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Lastly, we check if "hs_ibtfpriv" is NULL. If it is then it
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * means that we've have either received this event before we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * finished attaching to the IBTF or we've received it while we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * are in the process of detaching.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (state->hs_ibtfpriv != NULL)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor type = IBT_ERROR_ACCESS_VIOLATION_QP;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_DO_IBTF_ASYNC_CALLB(state, type, &event);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_sendq_drained_handler()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from interrupt context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor/* ARGSUSED */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_sendq_drained_handler(hermon_state_t *state, hermon_eqhdl_t eq,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqe_t *eqe)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_qphdl_t qp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t qpnum;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_async_event_t event;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t forward_sqd_event;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibt_async_code_t type;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get the QP handle from QP number in event descriptor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qpnum = HERMON_EQE_QPNUM_GET(eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qp = hermon_qphdl_from_qpnum(state, qpnum);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If the QP handle is NULL, this is probably an indication
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that the QP has been freed already. In which case, we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * should not deliver this event.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * We also check that the QP number in the handle is the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * same as the QP number in the event queue entry. This
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * extra check allows us to handle the case where a QP was
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * freed and then allocated again in the time it took to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handle the event queue processing. By constantly incrementing
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the non-constrained portion of the QP number every time
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * a new QP is allocated, we mitigate (somewhat) the chance
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that a stale event could be passed to the client's QP
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handler.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * And then we check if "hs_ibtfpriv" is NULL. If it is then it
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * means that we've have either received this event before we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * finished attaching to the IBTF or we've received it while we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * are in the process of detaching.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (state->hs_ibtfpriv != NULL)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor type = IBT_EVENT_SQD;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Grab the QP lock and update the QP state to reflect that
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the Send Queue Drained event has arrived. Also determine
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * whether the event is intended to be forwarded on to the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * consumer or not. This information is used below in
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * determining whether or not to call the IBTF.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_enter(&qp->qp_lock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor forward_sqd_event = qp->qp_forward_sqd_event;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qp->qp_forward_sqd_event = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qp->qp_sqd_still_draining = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_exit(&qp->qp_lock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (forward_sqd_event != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_DO_IBTF_ASYNC_CALLB(state, type, &event);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_path_mig_handler()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from interrupt context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor/* ARGSUSED */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_path_mig_handler(hermon_state_t *state, hermon_eqhdl_t eq,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqe_t *eqe)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_qphdl_t qp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t qpnum;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_async_event_t event;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibt_async_code_t type;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get the QP handle from QP number in event descriptor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qpnum = HERMON_EQE_QPNUM_GET(eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qp = hermon_qphdl_from_qpnum(state, qpnum);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If the QP handle is NULL, this is probably an indication
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that the QP has been freed already. In which case, we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * should not deliver this event.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * We also check that the QP number in the handle is the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * same as the QP number in the event queue entry. This
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * extra check allows us to handle the case where a QP was
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * freed and then allocated again in the time it took to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handle the event queue processing. By constantly incrementing
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the non-constrained portion of the QP number every time
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * a new QP is allocated, we mitigate (somewhat) the chance
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that a stale event could be passed to the client's QP
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handler.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Lastly, we check if "hs_ibtfpriv" is NULL. If it is then it
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * means that we've have either received this event before we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * finished attaching to the IBTF or we've received it while we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * are in the process of detaching.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (state->hs_ibtfpriv != NULL)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor type = IBT_EVENT_PATH_MIGRATED_QP;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_DO_IBTF_ASYNC_CALLB(state, type, &event);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_path_mig_err_handler()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from interrupt context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor/* ARGSUSED */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_path_mig_err_handler(hermon_state_t *state, hermon_eqhdl_t eq,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqe_t *eqe)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_qphdl_t qp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t qpnum;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_async_event_t event;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibt_async_code_t type;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get the QP handle from QP number in event descriptor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qpnum = HERMON_EQE_QPNUM_GET(eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qp = hermon_qphdl_from_qpnum(state, qpnum);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If the QP handle is NULL, this is probably an indication
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that the QP has been freed already. In which case, we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * should not deliver this event.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * We also check that the QP number in the handle is the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * same as the QP number in the event queue entry. This
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * extra check allows us to handle the case where a QP was
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * freed and then allocated again in the time it took to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handle the event queue processing. By constantly incrementing
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the non-constrained portion of the QP number every time
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * a new QP is allocated, we mitigate (somewhat) the chance
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that a stale event could be passed to the client's QP
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handler.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Lastly, we check if "hs_ibtfpriv" is NULL. If it is then it
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * means that we've have either received this event before we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * finished attaching to the IBTF or we've received it while we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * are in the process of detaching.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (state->hs_ibtfpriv != NULL)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor type = IBT_ERROR_PATH_MIGRATE_REQ_QP;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_DO_IBTF_ASYNC_CALLB(state, type, &event);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_catastrophic_handler()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from interrupt context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor/* ARGSUSED */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_catastrophic_handler(hermon_state_t *state, hermon_eqhdl_t eq,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqe_t *eqe)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_qphdl_t qp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t qpnum;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_async_event_t event;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibt_async_code_t type;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (eq->eq_evttypemask == HERMON_EVT_MSK_LOCAL_CAT_ERROR) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_FMANOTE(state, HERMON_FMA_INTERNAL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_eq_catastrophic(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get the QP handle from QP number in event descriptor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qpnum = HERMON_EQE_QPNUM_GET(eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qp = hermon_qphdl_from_qpnum(state, qpnum);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If the QP handle is NULL, this is probably an indication
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that the QP has been freed already. In which case, we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * should not deliver this event.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * We also check that the QP number in the handle is the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * same as the QP number in the event queue entry. This
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * extra check allows us to handle the case where a QP was
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * freed and then allocated again in the time it took to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handle the event queue processing. By constantly incrementing
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the non-constrained portion of the QP number every time
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * a new QP is allocated, we mitigate (somewhat) the chance
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that a stale event could be passed to the client's QP
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handler.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Lastly, we check if "hs_ibtfpriv" is NULL. If it is then it
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * means that we've have either received this event before we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * finished attaching to the IBTF or we've received it while we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * are in the process of detaching.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (state->hs_ibtfpriv != NULL)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor event.ev_srq_hdl = (ibt_srq_hdl_t)qp->qp_srqhdl->srq_hdlrarg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor type = IBT_ERROR_CATASTROPHIC_SRQ;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_enter(&qp->qp_srqhdl->srq_lock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qp->qp_srqhdl->srq_state = HERMON_SRQ_STATE_ERROR;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mutex_exit(&qp->qp_srqhdl->srq_lock);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_DO_IBTF_ASYNC_CALLB(state, type, &event);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_srq_last_wqe_reached_handler()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from interrupt context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor/* ARGSUSED */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_srq_last_wqe_reached_handler(hermon_state_t *state, hermon_eqhdl_t eq,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqe_t *eqe)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_qphdl_t qp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t qpnum;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibc_async_event_t event;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibt_async_code_t type;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get the QP handle from QP number in event descriptor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qpnum = HERMON_EQE_QPNUM_GET(eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor qp = hermon_qphdl_from_qpnum(state, qpnum);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If the QP handle is NULL, this is probably an indication
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that the QP has been freed already. In which case, we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * should not deliver this event.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * We also check that the QP number in the handle is the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * same as the QP number in the event queue entry. This
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * extra check allows us to handle the case where a QP was
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * freed and then allocated again in the time it took to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handle the event queue processing. By constantly incrementing
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the non-constrained portion of the QP number every time
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * a new QP is allocated, we mitigate (somewhat) the chance
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that a stale event could be passed to the client's QP
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handler.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Lastly, we check if "hs_ibtfpriv" is NULL. If it is then it
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * means that we've have either received this event before we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * finished attaching to the IBTF or we've received it while we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * are in the process of detaching.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (state->hs_ibtfpriv != NULL)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor type = IBT_EVENT_EMPTY_CHAN;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_DO_IBTF_ASYNC_CALLB(state, type, &event);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor/* ARGSUSED */
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylorstatic int hermon_fexch_error_handler(hermon_state_t *state,
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor hermon_eqhdl_t eq, hermon_hw_eqe_t *eqe)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor hermon_qphdl_t qp;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor uint_t qpnum;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor ibc_async_event_t event;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor ibt_async_code_t type;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor /* Get the QP handle from QP number in event descriptor */
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor event.ev_port = HERMON_EQE_FEXCH_PORTNUM_GET(eq, eqe);
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor qpnum = hermon_fcoib_qpnum_from_fexch(state,
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor event.ev_port, HERMON_EQE_FEXCH_FEXCH_GET(eq, eqe));
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor qp = hermon_qphdl_from_qpnum(state, qpnum);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor event.ev_fc = HERMON_EQE_FEXCH_SYNDROME_GET(eq, eqe);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * If the QP handle is NULL, this is probably an indication
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * that the QP has been freed already. In which case, we
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * should not deliver this event.
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor *
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * We also check that the QP number in the handle is the
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * same as the QP number in the event queue entry. This
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * extra check allows us to handle the case where a QP was
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * freed and then allocated again in the time it took to
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * handle the event queue processing. By constantly incrementing
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * the non-constrained portion of the QP number every time
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * a new QP is allocated, we mitigate (somewhat) the chance
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * that a stale event could be passed to the client's QP
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * handler.
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor *
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * Lastly, we check if "hs_ibtfpriv" is NULL. If it is then it
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * means that we've have either received this event before we
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * finished attaching to the IBTF or we've received it while we
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor * are in the process of detaching.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor if ((qp != NULL) && (qp->qp_qpnum == qpnum) &&
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor (state->hs_ibtfpriv != NULL)) {
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor event.ev_qp_hdl = (ibtl_qp_hdl_t)qp->qp_hdlrarg;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor type = IBT_FEXCH_ERROR;
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor
17a2b317610f531d565bf4e940433aab2d9e6985Bill Taylor HERMON_DO_IBTF_ASYNC_CALLB(state, type, &event);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hermon_no_eqhandler
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from interrupt context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/* ARGSUSED */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorhermon_no_eqhandler(hermon_state_t *state, hermon_eqhdl_t eq,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hermon_hw_eqe_t *eqe)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t data;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int i;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * This "unexpected event" handler (or "catch-all" handler) will
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * receive all events for which no other handler has been registered.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If we end up here, then something has probably gone seriously wrong
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * with the Hermon hardware (or, perhaps, with the software... though
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * it's unlikely in this case). The EQE provides all the information
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * about the event. So we print a warning message here along with
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the contents of the EQE.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_WARNING(state, "Unexpected Event handler");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, " Event type: %02x, subtype: %02x\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EQE_EVTTYPE_GET(eq, eqe),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor HERMON_EQE_EVTSUBTYPE_GET(eq, eqe));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < sizeof (hermon_hw_eqe_t) >> 2; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor data = ((uint_t *)eqe)[i];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, " EQE[%02x]: %08x\n", i, data);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}