b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * CDDL HEADER START
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 * 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 * 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 * CDDL HEADER END
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/ib/mgt/sm_attr.h> /* SM_INIT_TYPE_REPLY_... */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Static function declarations
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 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 * NDI event handle we need
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * SM's init type reply flags
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (((itr) & SM_INIT_TYPE_REPLY_NO_LOAD_REPLY) == 0)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (((itr) & SM_INIT_TYPE_PRESERVE_CONTENT_REPLY) == 0)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (((itr) & SM_INIT_TYPE_PRESERVE_PRESENCE_REPLY) == 0)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Port monitor progress flags (all flag values should be non-zero)
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 (void) snprintf(thr_name, MAXNAMELEN, ENX_PORT_MONITOR,
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 * 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 while (info->ti_pi->p_linkstate != IBT_PORT_ACTIVE) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (ENX_EVENT_LINK_UP | ENX_EVENT_DIE)) == 0) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_wait(&info->ti_event_cv, &info->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress |= ENX_MON_LINKSTATE_UP;
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 while (eibnx_find_mgroups(info) != ENX_E_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (ENX_EVENT_MCGS_AVAILABLE | ENX_EVENT_DIE)) == 0) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_wait(&info->ti_event_cv, &info->ti_event_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_event &= (~ENX_EVENT_MCGS_AVAILABLE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Setup a shared CQ
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 * Setup UD channel
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 info->ti_progress |= ENX_MON_SETUP_UD_CHAN;
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 * Setup completion handler
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 info->ti_progress |= ENX_MON_SETUP_CQ_HDLR;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Join EoIB multicast groups
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 * Send SOLICIT pkt to the EoIB multicast group
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 info->ti_progress |= ENX_MON_MULTICAST_SLCT;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan solicit_period_ticks = drv_usectohz(ENX_DFL_SOLICIT_PERIOD_USEC);
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 if (cv_timedwait(&info->ti_event_cv, &info->ti_event_lock,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_event & ENX_EVENT_TIMED_OUT) {
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 if (info->ti_progress & ENX_MON_MULTICAST_SLCT) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress &= (~ENX_MON_MULTICAST_SLCT);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_progress & ENX_MON_JOINED_MCGS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress &= (~ENX_MON_JOINED_MCGS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_progress & ENX_MON_SETUP_CQ_HDLR) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress &= (~ENX_MON_SETUP_CQ_HDLR);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_progress & ENX_MON_SETUP_BUFS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress &= (~ENX_MON_SETUP_BUFS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_progress & ENX_MON_SETUP_UD_CHAN) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress &= (~ENX_MON_SETUP_UD_CHAN);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_progress & ENX_MON_SETUP_CQ) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (info->ti_progress & ENX_MON_FOUND_MCGS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_progress &= (~ENX_MON_FOUND_MCGS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Async subnet notices handler registered with IBTF
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 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 for (ti = ss->nx_thr_info; ti; ti = ti->ti_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Async event handler registered with IBTF
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 ENX_DPRINTF_ERR("ibt ERROR event 0x%x received "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(hca_guid=0x%llx)", code, event->ev_hca_guid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("ibt PORT_DOWN event received "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(hca_guid=0x%llx, port_num=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("ibt PORT_UP event received "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(hca_guid=0x%llx, port_num=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_handle_port_events(hca, event->ev_port);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("ibt PORT_CHANGE event received "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(hca_guid=0x%llx, port_num=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_handle_port_events(hca, event->ev_port);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("ibt CLNT_REREG event received "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(hca_guid=0x%llx, port_num=0x%x)",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_handle_port_events(hca, event->ev_port);
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 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 ENX_DPRINTF_VERBOSE("ibt UNSUPPORTED event 0x%x received "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "(hca_guid=0x%llx)", code, event->ev_hca_guid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((cur_lbolt - gwi->gw_adv_last_lbolt) > gwi->gw_adv_timeout_ticks) {
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 gwi->gw_adv_last_lbolt = ddi_get_lbolt64();
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_gw_is_aware(eibnx_thr_info_t *info, eibnx_gw_info_t *gwi,
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 gwi->gw_adv_last_lbolt = ddi_get_lbolt64();
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 eib_gwi.gi_system_guid = gwi->gw_system_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_vnic_ka_period = gwi->gw_vnic_ka_period;
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 bcopy(gwi->gw_system_name, eib_gwi.gi_system_name,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(gwi->gw_port_name, eib_gwi.gi_port_name,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(gwi->gw_vendor_id, eib_gwi.gi_vendor_id,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_handle_gw_info_update(info, eib_gwi.gi_portid, &eib_gwi);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_handle_gw_rebirth(info, gwi->gw_portid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Thread to create eoib nodes and online instances
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 while ((ss->nx_nodeq == NULL) && (ss->nx_nodeq_thr_die == 0)) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_wait(&ss->nx_nodeq_cv, &ss->nx_nodeq_lock);
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 * Grab the first node entry from the queue
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) eibnx_configure_node(node->nc_info, node->nc_gwi, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*NOTREACHED*/
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Tx and Rx completion interrupt handler. Guaranteed to be single
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * threaded and nonreentrant for this CQ.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_comp_intr(ibt_cq_hdl_t cq_hdl, void *arg)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "cq_hdl(0x%llx) != info->ti_cq_hdl(0x%llx), "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ignoring completion", cq_hdl, info->ti_cq_hdl);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) ddi_intr_trigger_softint(info->ti_softint_hdl, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Send and Receive completion handler functions for EoIB nexus
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_comp_handler(caddr_t arg1, caddr_t arg2)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_thr_info_t *info = (eibnx_thr_info_t *)arg1;
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 if (info->ti_event & (ENX_EVENT_DIE | ENX_EVENT_COMPLETION)) {
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 ret = ibt_enable_cq_notify(info->ti_cq_hdl, IBT_NEXT_COMPLETION);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("ibt_enable_cq_notify(cq_hdl=0x%llx) "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Handle tx and rx completions
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan while ((ret = ibt_poll_cq(info->ti_cq_hdl, info->ti_wc, info->ti_cq_sz,
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 eibnx_handle_wcerr(wc->wc_status, wqe, info);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else if (wqe->qe_type == ENX_QETYP_RWQE) {
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 info->ti_event &= (~ENX_EVENT_COMPLETION);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Rx processing code
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_process_rx(eibnx_thr_info_t *info, ibt_wc_t *wc, eibnx_wqe_t *wqe)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan uint8_t *pkt = (uint8_t *)(uintptr_t)(wqe->qe_sgl.ds_va);
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 * Skip the GRH and parse the message in the packet
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eibnx_fip_parse_pkt(pkt + ENX_GRH_SZ, &msg) != ENX_E_SUCCESS) {
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 * Other than that, we only handle gateway advertisements
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (msg.gm_type != FIP_GW_ADVERTISE_MCAST &&
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 orig_gwi = eibnx_find_gw_in_gwlist(info, gwi);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) eibnx_add_gw_to_gwlist(info, gwi, wc, pkt);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else if (gwi->gw_flag_ucast_advt == 0) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (void) eibnx_add_gw_to_gwlist(info, gwi, wc, pkt);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_state = ENX_GW_STATE_READY_TO_LOGIN;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((new_gwi = eibnx_add_gw_to_gwlist(info, gwi,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_replace_gw_in_gwlist(info, orig_gwi, gwi,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else if (gwi->gw_flag_ucast_advt == 0) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (orig_gw_state == ENX_GW_STATE_UNAVAILABLE) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_replace_gw_in_gwlist(info, orig_gwi, gwi,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_state = ENX_GW_STATE_READY_TO_LOGIN;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_replace_gw_in_gwlist(info, orig_gwi, gwi,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_gw_is_aware(info, orig_gwi, gwi_changed);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (orig_gw_state != ENX_GW_STATE_READY_TO_LOGIN)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_handle_wcerr(uint8_t wcerr, eibnx_wqe_t *wqe, eibnx_thr_info_t *info)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Currently, all we do is report
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 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 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 Rajagopalaneibnx_handle_login_ack(eibnx_thr_info_t *info, uint8_t *pkt)
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 ack = (fip_login_ack_t *)(pkt + ENX_GRH_SZ);
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 ret = ndi_event_retrieve_cookie(enx_ndi_event_hdl, rdip,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_NDI_EVENT_LOGIN_ACK, &cookie, NDI_EVENT_NOPASS);
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 (void) ndi_post_event(ss->nx_dip, rdip, cookie, (void *)pkt);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_handle_gw_rebirth(eibnx_thr_info_t *info, uint16_t portid)
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 ret = ndi_event_retrieve_cookie(enx_ndi_event_hdl, rdip,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_NDI_EVENT_GW_AVAILABLE, &cookie, NDI_EVENT_NOPASS);
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 (void) ndi_post_event(ss->nx_dip, rdip, cookie, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_handle_gw_info_update(eibnx_thr_info_t *info, uint16_t portid,
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 ret = ndi_event_retrieve_cookie(enx_ndi_event_hdl, rdip,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_NDI_EVENT_GW_INFO_UPDATE, &cookie, NDI_EVENT_NOPASS);
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 (void) ndi_post_event(ss->nx_dip, rdip, cookie, new_gw_info);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_replace_portinfo(eibnx_thr_info_t *ti, ibt_hca_portinfo_t *new_pi,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (hca = ss->nx_hca; hca; hca = hca->hc_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("hca hdl (0x%llx) not found in hca list",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (port = hca->hc_port; port; port = port->po_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_free_portinfo(port->po_pi, port->po_pi_size);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("portinfo (0x%llx) not found in hca list",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_handle_port_events(ibt_hca_hdl_t ev_hca, uint8_t ev_portnum)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Find the port monitor thread that matches the event hca and
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (ti = ss->nx_thr_info; ti; ti = ti->ti_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * See if we need to rejoin the mcgs for this port and do so if true
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_query_hca_ports(ev_hca, ev_portnum, &pi, &num_pi, &size_pi);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("ibt_query_hca_ports() failed with %d", ret);
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 if (ENX_PORT_ATTR_LOADED(itr) && ENX_PORT_ATTR_NOT_PRESERVED(itr)) {
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 if (ti->ti_pi->p_base_lid != pi->p_base_lid) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (eibnx_replace_portinfo(ti, pi, size_pi) ==
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 if ((ti->ti_progress & ENX_MON_LINKSTATE_UP) != ENX_MON_LINKSTATE_UP) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ti->ti_progress & ENX_MON_JOINED_MCGS)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_handle_hca_attach(ib_guid_t new_hca_guid)
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 for (ti = ss->nx_thr_info; ti; ti = ti->ti_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_VERBOSE("hca (guid=0x%llx) already "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If we don't have it in our list, process the HCA and start the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * port monitors
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((hca = eibnx_prepare_hca(new_hca_guid)) != NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (port = hca->hc_port; port; port = port->po_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_handle_hca_detach(ib_guid_t del_hca_guid)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * We need to locate all monitor threads for this HCA and stop them
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (ti = ss->nx_thr_info; ti; ti = ti_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Take it out from the good list
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * And put it in the to-stop list
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Ask all the port_monitor threads to die.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (ti = ti_stop_list; ti; ti = ti_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Now, locate the HCA in our list and release all HCA related
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (hca = ss->nx_hca; hca; hca = hca->hc_next) {