b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * CDDL HEADER START
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * The contents of this file are subject to the terms of the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Common Development and Distribution License (the "License").
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * You may not use this file except in compliance with the License.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * or http://www.opensolaris.org/os/licensing.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * See the License for the specific language governing permissions
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * and limitations under the License.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * When distributing Covered Code, include this CDDL HEADER in each
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If applicable, add the following below this CDDL HEADER, with the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * fields enclosed by brackets "[]" replaced with your own identifying
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * information: Portions Copyright [yyyy] [name of copyright owner]
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * CDDL HEADER END
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/types.h>
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/kmem.h>
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/conf.h>
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/ddi.h>
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/sunddi.h>
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/sunndi.h>
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/ksynch.h>
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/callb.h>
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/ib/mgt/sm_attr.h> /* SM_INIT_TYPE_REPLY_... */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/ib/clients/eoib/enx_impl.h>
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Static function declarations
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eibnx_gw_is_alive(eibnx_gw_info_t *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eibnx_gw_is_aware(eibnx_thr_info_t *, eibnx_gw_info_t *, boolean_t);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eibnx_process_rx(eibnx_thr_info_t *, ibt_wc_t *, eibnx_wqe_t *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eibnx_handle_wcerr(uint8_t, eibnx_wqe_t *, eibnx_thr_info_t *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eibnx_handle_login_ack(eibnx_thr_info_t *, uint8_t *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eibnx_handle_gw_rebirth(eibnx_thr_info_t *, uint16_t);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eibnx_handle_gw_info_update(eibnx_thr_info_t *, uint16_t, void *);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic int eibnx_replace_portinfo(eibnx_thr_info_t *, ibt_hca_portinfo_t *,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint_t);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eibnx_handle_port_events(ibt_hca_hdl_t, uint8_t);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eibnx_handle_hca_attach(ib_guid_t);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void eibnx_handle_hca_detach(ib_guid_t);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * NDI event handle we need
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanextern ndi_event_hdl_t enx_ndi_event_hdl;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * SM's init type reply flags
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define ENX_PORT_ATTR_LOADED(itr) \
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (((itr) & SM_INIT_TYPE_REPLY_NO_LOAD_REPLY) == 0)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define ENX_PORT_ATTR_NOT_PRESERVED(itr) \
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (((itr) & SM_INIT_TYPE_PRESERVE_CONTENT_REPLY) == 0)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define ENX_PORT_PRES_NOT_PRESERVED(itr) \
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (((itr) & SM_INIT_TYPE_PRESERVE_PRESENCE_REPLY) == 0)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Port monitor progress flags (all flag values should be non-zero)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define ENX_MON_LINKSTATE_UP 0x01
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define ENX_MON_FOUND_MCGS 0x02
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define ENX_MON_SETUP_CQ 0x04
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define ENX_MON_SETUP_UD_CHAN 0x08
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define ENX_MON_SETUP_BUFS 0x10
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define ENX_MON_SETUP_CQ_HDLR 0x20
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define ENX_MON_JOINED_MCGS 0x40
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define ENX_MON_MULTICAST_SLCT 0x80
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#define ENX_MON_MAX 0xFF
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Per-port thread to solicit, monitor and discover EoIB gateways
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * and create the corresponding EoIB driver instances on the host.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_port_monitor(eibnx_thr_info_t *info)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan clock_t solicit_period_ticks;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan clock_t deadline;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmutex_t ci_lock;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan callb_cpr_t ci;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan char thr_name[MAXNAMELEN];
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) snprintf(thr_name, MAXNAMELEN, ENX_PORT_MONITOR,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_pi->p_port_num);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_init(&ci_lock, NULL, MUTEX_DRIVER, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan CALLB_CPR_INIT(&ci, &ci_lock, callb_generic_cpr, thr_name);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress = 0;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If the port is not active yet, wait for a port up event. The
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * async handler, when it sees a port-up event, is expected to
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * update the port_monitor's portinfo structure's p_linkstate
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * and wake us up with ENX_EVENT_LINK_UP.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan while (info->ti_pi->p_linkstate != IBT_PORT_ACTIVE) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&info->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan while ((info->ti_event &
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (ENX_EVENT_LINK_UP | ENX_EVENT_DIE)) == 0) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan CALLB_CPR_SAFE_BEGIN(&ci);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_wait(&info->ti_event_cv, &info->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan CALLB_CPR_SAFE_END(&ci, &ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_event & ENX_EVENT_DIE) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&info->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto port_monitor_exit;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_event &= (~ENX_EVENT_LINK_UP);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&info->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress |= ENX_MON_LINKSTATE_UP;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Locate the multicast groups for sending solicit requests
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * to the GW and receiving advertisements from the GW. If
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * either of the mcg is not present, wait for them to be
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * created by the GW.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan while (eibnx_find_mgroups(info) != ENX_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&info->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan while ((info->ti_event &
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (ENX_EVENT_MCGS_AVAILABLE | ENX_EVENT_DIE)) == 0) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan CALLB_CPR_SAFE_BEGIN(&ci);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_wait(&info->ti_event_cv, &info->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan CALLB_CPR_SAFE_END(&ci, &ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_event & ENX_EVENT_DIE) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&info->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto port_monitor_exit;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_event &= (~ENX_EVENT_MCGS_AVAILABLE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&info->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress |= ENX_MON_FOUND_MCGS;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Setup a shared CQ
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eibnx_setup_cq(info) != ENX_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_ERR("eibnx_setup_cq() failed, terminating "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "port monitor for (hca_guid=0x%llx, port_num=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_hca_guid, info->ti_pi->p_port_num);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto port_monitor_exit;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress |= ENX_MON_SETUP_CQ;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Setup UD channel
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eibnx_setup_ud_channel(info) != ENX_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_ERR("eibnx_setup_ud_channel() failed, terminating "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "port monitor for (hca_guid=0x%llx, port_num=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_hca_guid, info->ti_pi->p_port_num);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto port_monitor_exit;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress |= ENX_MON_SETUP_UD_CHAN;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Allocate/initialize any tx/rx buffers
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eibnx_setup_bufs(info) != ENX_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_ERR("eibnx_setup_bufs() failed, terminating "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "port monitor for (hca_guid=0x%llx, port_num=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_hca_guid, info->ti_pi->p_port_num);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto port_monitor_exit;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress |= ENX_MON_SETUP_BUFS;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Setup completion handler
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eibnx_setup_cq_handler(info) != ENX_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_ERR("eibnx_setup_cq_handler() failed, terminating "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "port monitor for (hca_guid=0x%llx, port_num=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_hca_guid, info->ti_pi->p_port_num);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto port_monitor_exit;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress |= ENX_MON_SETUP_CQ_HDLR;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Join EoIB multicast groups
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eibnx_join_mcgs(info) != ENX_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_ERR("eibnx_join_mcgs() failed, terminating ",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "port monitor for (hca_guid=0x%llx, port_num=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_hca_guid, info->ti_pi->p_port_num);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto port_monitor_exit;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress |= ENX_MON_JOINED_MCGS;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Send SOLICIT pkt to the EoIB multicast group
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eibnx_fip_solicit_mcast(info) != ENX_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_ERR("eibnx_fip_solicit_mcast() failed, terminating "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "port monitor for (hca_guid=0x%llx, port_num=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_hca_guid, info->ti_pi->p_port_num);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto port_monitor_exit;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress |= ENX_MON_MULTICAST_SLCT;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&info->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan solicit_period_ticks = drv_usectohz(ENX_DFL_SOLICIT_PERIOD_USEC);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanperiodic_solicit:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan deadline = ddi_get_lbolt() + solicit_period_ticks;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan while ((info->ti_event & (ENX_EVENT_TIMED_OUT | ENX_EVENT_DIE)) == 0) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan CALLB_CPR_SAFE_BEGIN(&ci);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (cv_timedwait(&info->ti_event_cv, &info->ti_event_lock,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan deadline) == -1) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_event |= ENX_EVENT_TIMED_OUT;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan CALLB_CPR_SAFE_END(&ci, &ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_event & ENX_EVENT_DIE) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&info->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto port_monitor_exit;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_event & ENX_EVENT_TIMED_OUT) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eibnx_fip_solicit_ucast(info,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan &solicit_period_ticks) != ENX_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("failed to send solicit ucast to "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "gateways (hca_guid=0x%llx, port_num=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_hca_guid, info->ti_pi->p_port_num);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_event &= ~ENX_EVENT_TIMED_OUT;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto periodic_solicit;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanport_monitor_exit:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_progress & ENX_MON_MULTICAST_SLCT) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_cleanup_port_nodes(info);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress &= (~ENX_MON_MULTICAST_SLCT);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_progress & ENX_MON_JOINED_MCGS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_rb_join_mcgs(info);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress &= (~ENX_MON_JOINED_MCGS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_progress & ENX_MON_SETUP_CQ_HDLR) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_rb_setup_cq_handler(info);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress &= (~ENX_MON_SETUP_CQ_HDLR);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_progress & ENX_MON_SETUP_BUFS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_rb_setup_bufs(info);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress &= (~ENX_MON_SETUP_BUFS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_progress & ENX_MON_SETUP_UD_CHAN) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_rb_setup_ud_channel(info);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress &= (~ENX_MON_SETUP_UD_CHAN);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_progress & ENX_MON_SETUP_CQ) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_rb_setup_cq(info);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress &= (~ENX_MON_SETUP_CQ);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_progress & ENX_MON_FOUND_MCGS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_rb_find_mgroups(info);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress &= (~ENX_MON_FOUND_MCGS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan CALLB_CPR_EXIT(&ci);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_destroy(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Async subnet notices handler registered with IBTF
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*ARGSUSED*/
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_subnet_notices_handler(void *arg, ib_gid_t gid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_subnet_event_code_t sn_evcode, ibt_subnet_event_t *sn_event)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_t *ss = enx_global_ss;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_thr_info_t *ti;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ib_gid_t notice_gid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan switch (sn_evcode) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan case IBT_SM_EVENT_MCG_CREATED:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan notice_gid = sn_event->sm_notice_gid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((notice_gid.gid_prefix == enx_solicit_mgid.gid_prefix &&
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan notice_gid.gid_guid == enx_solicit_mgid.gid_guid) ||
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (notice_gid.gid_prefix == enx_advertise_mgid.gid_prefix &&
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan notice_gid.gid_guid == enx_advertise_mgid.gid_guid)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->nx_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (ti = ss->nx_thr_info; ti; ti = ti->ti_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ti->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ti->ti_event |= ENX_EVENT_MCGS_AVAILABLE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_broadcast(&ti->ti_event_cv);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ti->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->nx_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan case IBT_SM_EVENT_MCG_DELETED:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan default:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Async event handler registered with IBTF
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*ARGSUSED*/
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_async_handler(void *clnt_pvt, ibt_hca_hdl_t hca,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_async_code_t code, ibt_async_event_t *event)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan switch (code) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan case IBT_ERROR_CATASTROPHIC_CHAN:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan case IBT_ERROR_INVALID_REQUEST_CHAN:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan case IBT_ERROR_ACCESS_VIOLATION_CHAN:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan case IBT_ERROR_CQ:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan case IBT_ERROR_CATASTROPHIC_SRQ:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_ERR("ibt ERROR event 0x%x received "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(hca_guid=0x%llx)", code, event->ev_hca_guid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan case IBT_ERROR_PORT_DOWN:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("ibt PORT_DOWN event received "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(hca_guid=0x%llx, port_num=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan event->ev_hca_guid, event->ev_port);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan case IBT_EVENT_PORT_UP:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("ibt PORT_UP event received "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(hca_guid=0x%llx, port_num=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan event->ev_hca_guid, event->ev_port);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_handle_port_events(hca, event->ev_port);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan case IBT_PORT_CHANGE_EVENT:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("ibt PORT_CHANGE event received "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(hca_guid=0x%llx, port_num=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan event->ev_hca_guid, event->ev_port);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_handle_port_events(hca, event->ev_port);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan case IBT_CLNT_REREG_EVENT:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("ibt CLNT_REREG event received "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(hca_guid=0x%llx, port_num=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan event->ev_hca_guid, event->ev_port);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_handle_port_events(hca, event->ev_port);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan case IBT_HCA_ATTACH_EVENT:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_VERBOSE("ibt HCA_ATTACH event received "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(new hca_guid=0x%llx)", event->ev_hca_guid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_handle_hca_attach(event->ev_hca_guid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan case IBT_HCA_DETACH_EVENT:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_VERBOSE("ibt HCA_DETACH event received "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(target hca_guid=0x%llx)", event->ev_hca_guid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_handle_hca_detach(event->ev_hca_guid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan default:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_VERBOSE("ibt UNSUPPORTED event 0x%x received "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(hca_guid=0x%llx)", code, event->ev_hca_guid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanboolean_t
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_is_gw_dead(eibnx_gw_info_t *gwi)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int64_t cur_lbolt;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cur_lbolt = ddi_get_lbolt64();
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&gwi->gw_adv_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((cur_lbolt - gwi->gw_adv_last_lbolt) > gwi->gw_adv_timeout_ticks) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_adv_flag = ENX_GW_DEAD;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&gwi->gw_adv_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (B_TRUE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&gwi->gw_adv_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (B_FALSE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_gw_is_alive(eibnx_gw_info_t *gwi)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * We've just received a multicast advertisement from this
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * gateway. Multicast or unicast, this means that the gateway
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * is alive. Record this timestamp (in ticks).
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&gwi->gw_adv_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_adv_last_lbolt = ddi_get_lbolt64();
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (gwi->gw_adv_flag == ENX_GW_DEAD) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_adv_flag = ENX_GW_ALIVE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&gwi->gw_adv_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_gw_is_aware(eibnx_thr_info_t *info, eibnx_gw_info_t *gwi,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan boolean_t gwi_changed)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_gw_info_t eib_gwi;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan boolean_t post_rebirth_event = B_FALSE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * We're here when we receive a unicast advertisement from a
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * gateway. If this gateway was discovered earlier but was in
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * a dead state, this means it has come back alive and become
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * aware of us. We may need to inform any EoIB children
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * waiting for notification. Note that if this gateway is
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * being discovered for the first time now, we wouldn't have
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * created the binding eoib node for it (we will do that when
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * we return from this routine), so the "rebirth" and "gw info
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * update" event postings will be NOPs.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&gwi->gw_adv_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_adv_last_lbolt = ddi_get_lbolt64();
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (gwi->gw_adv_flag != ENX_GW_AWARE) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan post_rebirth_event = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_adv_flag = ENX_GW_AWARE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&gwi->gw_adv_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If we have a gateway information update event, we post that
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * first, so any rebirth event processed later will have the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * correct gateway information.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (gwi_changed) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_gwi.gi_system_guid = gwi->gw_system_guid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_gwi.gi_guid = gwi->gw_guid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_gwi.gi_sn_prefix = gwi->gw_addr.ga_gid.gid_prefix;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_gwi.gi_adv_period = gwi->gw_adv_period;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_gwi.gi_ka_period = gwi->gw_ka_period;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_gwi.gi_vnic_ka_period = gwi->gw_vnic_ka_period;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_gwi.gi_ctrl_qpn = gwi->gw_ctrl_qpn;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_gwi.gi_lid = gwi->gw_lid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_gwi.gi_portid = gwi->gw_portid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_gwi.gi_num_net_vnics = gwi->gw_num_net_vnics;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_gwi.gi_flag_available = gwi->gw_flag_available;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_gwi.gi_is_host_adm_vnics = gwi->gw_is_host_adm_vnics;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_gwi.gi_sl = gwi->gw_sl;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eib_gwi.gi_n_rss_qpn = gwi->gw_n_rss_qpn;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(gwi->gw_system_name, eib_gwi.gi_system_name,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_GW_SYSNAME_LEN);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(gwi->gw_port_name, eib_gwi.gi_port_name,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_GW_PORTNAME_LEN);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(gwi->gw_vendor_id, eib_gwi.gi_vendor_id,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_GW_VENDOR_LEN);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_handle_gw_info_update(info, eib_gwi.gi_portid, &eib_gwi);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (post_rebirth_event) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_handle_gw_rebirth(info, gwi->gw_portid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Thread to create eoib nodes and online instances
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_create_eoib_node(void)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_t *ss = enx_global_ss;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_nodeq_t *node;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmutex_t ci_lock;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan callb_cpr_t ci;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_init(&ci_lock, NULL, MUTEX_DRIVER, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan CALLB_CPR_INIT(&ci, &ci_lock, callb_generic_cpr, ENX_NODE_CREATOR);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanwait_for_node_to_create:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->nx_nodeq_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan while ((ss->nx_nodeq == NULL) && (ss->nx_nodeq_thr_die == 0)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan CALLB_CPR_SAFE_BEGIN(&ci);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_wait(&ss->nx_nodeq_cv, &ss->nx_nodeq_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan CALLB_CPR_SAFE_END(&ci, &ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If this is not really a work item, but a request for us to
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * die, throwaway all pending work requests and just die.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ss->nx_nodeq_thr_die) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan while (ss->nx_nodeq) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan node = ss->nx_nodeq;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->nx_nodeq = node->nc_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan node->nc_next = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(node, sizeof (eibnx_nodeq_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->nx_nodeq_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan CALLB_CPR_EXIT(&ci);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_destroy(&ci_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Grab the first node entry from the queue
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ASSERT(ss->nx_nodeq != NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan node = ss->nx_nodeq;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->nx_nodeq = node->nc_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan node->nc_next = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->nx_nodeq_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) eibnx_configure_node(node->nc_info, node->nc_gwi, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(node, sizeof (eibnx_nodeq_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan goto wait_for_node_to_create;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*NOTREACHED*/
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Tx and Rx completion interrupt handler. Guaranteed to be single
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * threaded and nonreentrant for this CQ.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_comp_intr(ibt_cq_hdl_t cq_hdl, void *arg)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_thr_info_t *info = arg;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_cq_hdl != cq_hdl) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_DEBUG("eibnx_comp_intr: "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "cq_hdl(0x%llx) != info->ti_cq_hdl(0x%llx), "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ignoring completion", cq_hdl, info->ti_cq_hdl);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ASSERT(info->ti_softint_hdl != NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) ddi_intr_trigger_softint(info->ti_softint_hdl, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Send and Receive completion handler functions for EoIB nexus
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*ARGSUSED*/
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanuint_t
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_comp_handler(caddr_t arg1, caddr_t arg2)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_thr_info_t *info = (eibnx_thr_info_t *)arg1;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_wc_t *wc;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_wqe_t *wqe;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_status_t ret;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint_t polled;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int i;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Make sure the port monitor isn't killed if we're in the completion
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * handler. If the port monitor thread is already being killed, we'll
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * stop processing completions.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&info->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_event & (ENX_EVENT_DIE | ENX_EVENT_COMPLETION)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&info->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return ((uint_t)ENX_E_SUCCESS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_event |= ENX_EVENT_COMPLETION;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&info->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Re-arm the notification callback before we start polling
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * the completion queue. There's nothing much we can do if the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * enable_cq_notify fails - we issue a warning and move on.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_enable_cq_notify(info->ti_cq_hdl, IBT_NEXT_COMPLETION);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("ibt_enable_cq_notify(cq_hdl=0x%llx) "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "failed, ret=%d", info->ti_cq_hdl, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Handle tx and rx completions
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan while ((ret = ibt_poll_cq(info->ti_cq_hdl, info->ti_wc, info->ti_cq_sz,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan &polled)) == IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (wc = info->ti_wc, i = 0; i < polled; i++, wc++) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan wqe = (eibnx_wqe_t *)(uintptr_t)wc->wc_id;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (wc->wc_status != IBT_WC_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_handle_wcerr(wc->wc_status, wqe, info);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else if (wqe->qe_type == ENX_QETYP_RWQE) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_process_rx(info, wc, wqe);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_return_rwqe(info, wqe);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_return_swqe(wqe);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * On the way out, make sure we wake up any pending death requestor
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * for the port-monitor thread. Note that we need to do a cv_broadcast()
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * here since there could be multiple threads sleeping on the event cv
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * and we want to make sure all waiters get a chance to see if it's
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * their turn.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&info->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_event &= (~ENX_EVENT_COMPLETION);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_broadcast(&info->ti_event_cv);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&info->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (DDI_INTR_CLAIMED);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Rx processing code
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_process_rx(eibnx_thr_info_t *info, ibt_wc_t *wc, eibnx_wqe_t *wqe)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_gw_msg_t msg;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_gw_info_t *gwi;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_gw_info_t *orig_gwi;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_gw_info_t *new_gwi;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint_t orig_gw_state;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint8_t *pkt = (uint8_t *)(uintptr_t)(wqe->qe_sgl.ds_va);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan boolean_t gwi_changed;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * We'll simply drop any packet (including broadcast advertisements
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * from gws) we receive before we've done our solicitation broadcast.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_mcast_done == 0) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Skip the GRH and parse the message in the packet
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eibnx_fip_parse_pkt(pkt + ENX_GRH_SZ, &msg) != ENX_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If it was a login ack for one of our children, we need to pass
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * it on to the child
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (msg.gm_type == FIP_VNIC_LOGIN_ACK) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_handle_login_ack(info, pkt);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Other than that, we only handle gateway advertisements
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (msg.gm_type != FIP_GW_ADVERTISE_MCAST &&
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan msg.gm_type != FIP_GW_ADVERTISE_UCAST) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi = &msg.u.gm_info;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * State machine to create eoib instances. Whether this advertisement
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * is from a new gateway or an old gateway that we already know about,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * if this was a unicast response to our earlier solicitation and it's
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * the first time we're receiving it from this gateway, we're ready to
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * login, so we create the EoIB instance for it.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi = eibnx_find_gw_in_gwlist(info, gwi);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (orig_gwi == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (gwi->gw_flag_available == 0) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_state = ENX_GW_STATE_UNAVAILABLE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_adv_flag = ENX_GW_ALIVE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) eibnx_add_gw_to_gwlist(info, gwi, wc, pkt);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else if (gwi->gw_flag_ucast_advt == 0) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_state = ENX_GW_STATE_AVAILABLE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_adv_flag = ENX_GW_ALIVE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) eibnx_add_gw_to_gwlist(info, gwi, wc, pkt);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_state = ENX_GW_STATE_READY_TO_LOGIN;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_adv_flag = ENX_GW_AWARE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((new_gwi = eibnx_add_gw_to_gwlist(info, gwi,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan wc, pkt)) != NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_queue_for_creation(info, new_gwi);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gw_state = orig_gwi->gw_state;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (gwi->gw_flag_available == 0) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_state = ENX_GW_STATE_UNAVAILABLE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_replace_gw_in_gwlist(info, orig_gwi, gwi,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan wc, pkt, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_gw_is_alive(orig_gwi);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else if (gwi->gw_flag_ucast_advt == 0) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (orig_gw_state == ENX_GW_STATE_UNAVAILABLE) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_state = ENX_GW_STATE_AVAILABLE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_state = orig_gw_state;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_replace_gw_in_gwlist(info, orig_gwi, gwi,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan wc, pkt, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_gw_is_alive(orig_gwi);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_state = ENX_GW_STATE_READY_TO_LOGIN;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_replace_gw_in_gwlist(info, orig_gwi, gwi,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan wc, pkt, &gwi_changed);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_gw_is_aware(info, orig_gwi, gwi_changed);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (orig_gw_state != ENX_GW_STATE_READY_TO_LOGIN)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_queue_for_creation(info, orig_gwi);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*ARGSUSED*/
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_handle_wcerr(uint8_t wcerr, eibnx_wqe_t *wqe, eibnx_thr_info_t *info)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Currently, all we do is report
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan switch (wcerr) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan case IBT_WC_WR_FLUSHED_ERR:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_VERBOSE("IBT_WC_WR_FLUSHED_ERR seen "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(hca_guid=0x%llx, port_num=0x%x, wqe_type=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_hca_guid, info->ti_pi->p_port_num, wqe->qe_type);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan case IBT_WC_LOCAL_CHAN_OP_ERR:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_ERR("IBT_WC_LOCAL_CHAN_OP_ERR seen "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(hca_guid=0x%llx, port_num=0x%x, wqe_type=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_hca_guid, info->ti_pi->p_port_num, wqe->qe_type);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan case IBT_WC_LOCAL_PROTECT_ERR:
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_ERR("IBT_WC_LOCAL_PROTECT_ERR seen "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(hca_guid=0x%llx, port_num=0x%x, wqe_type=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_hca_guid, info->ti_pi->p_port_num, wqe->qe_type);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_handle_login_ack(eibnx_thr_info_t *info, uint8_t *pkt)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_t *ss = enx_global_ss;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan fip_login_ack_t *ack;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan fip_desc_vnic_login_t *login;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ddi_eventcookie_t cookie;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan dev_info_t *rdip;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint16_t vnic_id;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint16_t inst;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int ret;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * When we get login acknowledgements, we simply invoke the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * appropriate EoIB driver callback to process it on behalf
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * of the driver instance. We will let the callback do error
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * checks.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ack = (fip_login_ack_t *)(pkt + ENX_GRH_SZ);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan login = &(ack->ak_vnic_login);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan vnic_id = ntohs(login->vl_vnic_id);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan inst = EIB_DEVI_INSTANCE(vnic_id);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((rdip = eibnx_find_child_dip_by_inst(info, inst)) == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_DEBUG("no eoib child with instance 0x%x found "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "for (hca_guid=0x%llx, port_num=0x%x)", inst,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_hca_guid, info->ti_pi->p_port_num);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ndi_event_retrieve_cookie(enx_ndi_event_hdl, rdip,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_NDI_EVENT_LOGIN_ACK, &cookie, NDI_EVENT_NOPASS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != NDI_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("no login-ack cookie for (hca_guid=0x%llx, "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "port_num=0x%x, eoib_inst=0x%x), ret=%d", info->ti_hca_guid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_pi->p_port_num, inst, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) ndi_post_event(ss->nx_dip, rdip, cookie, (void *)pkt);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_handle_gw_rebirth(eibnx_thr_info_t *info, uint16_t portid)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_t *ss = enx_global_ss;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ddi_eventcookie_t cookie;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan dev_info_t *rdip;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int ret;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((rdip = eibnx_find_child_dip_by_gw(info, portid)) == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("no eoib child bound to gw portid 0x%x "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "found for (hca_guid=0x%llx, port_num=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan portid, info->ti_hca_guid, info->ti_pi->p_port_num);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ndi_event_retrieve_cookie(enx_ndi_event_hdl, rdip,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_NDI_EVENT_GW_AVAILABLE, &cookie, NDI_EVENT_NOPASS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != NDI_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("no gw-available cookie for (hca_guid=0x%llx, "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "port_num=0x%x, gw_portid=0x%x), ret=%d", info->ti_hca_guid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_pi->p_port_num, portid, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) ndi_post_event(ss->nx_dip, rdip, cookie, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_handle_gw_info_update(eibnx_thr_info_t *info, uint16_t portid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan void *new_gw_info)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_t *ss = enx_global_ss;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ddi_eventcookie_t cookie;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan dev_info_t *rdip;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int ret;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((rdip = eibnx_find_child_dip_by_gw(info, portid)) == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("no eoib child bound to gw portid 0x%x "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "found for (hca_guid=0x%llx, port_num=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan portid, info->ti_hca_guid, info->ti_pi->p_port_num);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ndi_event_retrieve_cookie(enx_ndi_event_hdl, rdip,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_NDI_EVENT_GW_INFO_UPDATE, &cookie, NDI_EVENT_NOPASS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != NDI_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("no gw-info-update cookie for "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(hca_guid=0x%llx, port_num=0x%x, gw_portid=0x%x), "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ret=%d", info->ti_hca_guid, info->ti_pi->p_port_num,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan portid, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) ndi_post_event(ss->nx_dip, rdip, cookie, new_gw_info);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic int
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_replace_portinfo(eibnx_thr_info_t *ti, ibt_hca_portinfo_t *new_pi,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint_t new_size_pi)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_t *ss = enx_global_ss;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_hca_t *hca;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_port_t *port;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->nx_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (hca = ss->nx_hca; hca; hca = hca->hc_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (hca->hc_hdl == ti->ti_hca)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (hca == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("hca hdl (0x%llx) not found in hca list",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ti->ti_hca);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->nx_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (ENX_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (port = hca->hc_port; port; port = port->po_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (port->po_pi == ti->ti_pi) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_free_portinfo(port->po_pi, port->po_pi_size);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan port->po_pi = new_pi;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan port->po_pi_size = new_size_pi;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ti->ti_pi = port->po_pi;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (port == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("portinfo (0x%llx) not found in hca list",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ti->ti_pi);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->nx_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (ENX_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->nx_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (ENX_E_SUCCESS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_handle_port_events(ibt_hca_hdl_t ev_hca, uint8_t ev_portnum)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_t *ss = enx_global_ss;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_thr_info_t *ti;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_hca_portinfo_t *pi;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_status_t ret;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint_t num_pi;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint_t size_pi;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint8_t itr;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Find the port monitor thread that matches the event hca and
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * portnum
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->nx_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (ti = ss->nx_thr_info; ti; ti = ti->ti_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((ti->ti_hca == ev_hca) &&
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (ti->ti_pi->p_port_num == ev_portnum)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->nx_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ti == NULL)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * See if we need to rejoin the mcgs for this port and do so if true
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_query_hca_ports(ev_hca, ev_portnum, &pi, &num_pi, &size_pi);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("ibt_query_hca_ports() failed with %d", ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else if (num_pi != 1 || pi->p_linkstate != IBT_PORT_ACTIVE) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("ibt_query_hca_ports(port_num=%d) failed, "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "num_pi=%d, linkstate=0x%x", ev_portnum, num_pi,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan pi->p_linkstate);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_free_portinfo(pi, size_pi);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan itr = pi->p_init_type_reply;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ENX_PORT_ATTR_LOADED(itr) && ENX_PORT_ATTR_NOT_PRESERVED(itr)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If our port's base lid has changed, we need to replace
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * the saved portinfo in our lists with the new one before
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * going further.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ti->ti_pi->p_base_lid != pi->p_base_lid) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eibnx_replace_portinfo(ti, pi, size_pi) ==
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan pi = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan size_pi = 0;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If the port monitor was stuck waiting for the link to come up,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * let it know that it is up now.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ti->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((ti->ti_progress & ENX_MON_LINKSTATE_UP) != ENX_MON_LINKSTATE_UP) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ti->ti_pi->p_linkstate = IBT_PORT_ACTIVE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ti->ti_event |= ENX_EVENT_LINK_UP;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_broadcast(&ti->ti_event_cv);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ti->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ENX_PORT_PRES_NOT_PRESERVED(itr)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ti->ti_progress & ENX_MON_JOINED_MCGS)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) eibnx_rejoin_mcgs(ti);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (pi != NULL)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_free_portinfo(pi, size_pi);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_handle_hca_attach(ib_guid_t new_hca_guid)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_t *ss = enx_global_ss;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_thr_info_t *ti;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_hca_t *hca;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_port_t *port;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * All we need to do is to start a port monitor for all the ports
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * on the new HCA. To do this, go through our current port monitors
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * and see if we already have a monitor for this HCA - if so, print
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * a warning and return.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->nx_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (ti = ss->nx_thr_info; ti; ti = ti->ti_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ti->ti_hca_guid == new_hca_guid) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_VERBOSE("hca (guid=0x%llx) already "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "attached", new_hca_guid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->nx_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->nx_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If we don't have it in our list, process the HCA and start the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * port monitors
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((hca = eibnx_prepare_hca(new_hca_guid)) != NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->nx_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan hca->hc_next = ss->nx_hca;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->nx_hca = hca;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (port = hca->hc_port; port; port = port->po_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ti = eibnx_start_port_monitor(hca, port);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ti->ti_next = ss->nx_thr_info;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->nx_thr_info = ti;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->nx_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanstatic void
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_handle_hca_detach(ib_guid_t del_hca_guid)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_t *ss = enx_global_ss;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_thr_info_t *ti;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_thr_info_t *ti_stop_list = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_thr_info_t *ti_prev;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_thr_info_t *ti_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_hca_t *hca;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_hca_t *hca_prev;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * We need to locate all monitor threads for this HCA and stop them
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->nx_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ti_prev = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (ti = ss->nx_thr_info; ti; ti = ti_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ti_next = ti->ti_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ti->ti_hca_guid != del_hca_guid) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ti_prev = ti;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Take it out from the good list
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ti_prev)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ti_prev->ti_next = ti_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan else
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->nx_thr_info = ti_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * And put it in the to-stop list
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ti->ti_next = ti_stop_list;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ti_stop_list = ti;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->nx_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Ask all the port_monitor threads to die.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (ti = ti_stop_list; ti; ti = ti_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ti_next = ti->ti_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_stop_port_monitor(ti);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Now, locate the HCA in our list and release all HCA related
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * resources.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->nx_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan hca_prev = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (hca = ss->nx_hca; hca; hca = hca->hc_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (hca->hc_guid != del_hca_guid) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan hca_prev = hca;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (hca_prev) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan hca_prev->hc_next = hca->hc_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->nx_hca = hca->hc_next;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan hca->hc_next = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->nx_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (hca) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) eibnx_cleanup_hca(hca);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}