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/ksynch.h>
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan#include <sys/ib/clients/eoib/enx_impl.h>
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Acquire an SWQE
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*ARGSUSED*/
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_wqe_t *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_acquire_swqe(eibnx_thr_info_t *info, int flag)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_wqe_t *wqe = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_tx_t *snd_p = &info->ti_snd;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan int i;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (i = 0; i < ENX_NUM_SWQE; i++) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan wqe = &(snd_p->tx_wqe[i]);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&wqe->qe_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((wqe->qe_flags & ENX_QEFL_INUSE) == 0) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan wqe->qe_flags |= ENX_QEFL_INUSE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&wqe->qe_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&wqe->qe_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * We probably have enough swqe entries for doing our solicitations.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If we find it not enough in practice, we need to implement some
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * sort of dynamic allocation.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (i == ENX_NUM_SWQE)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan wqe = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (wqe);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Return a SWQE from completion. We may have to release
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * it or keep it.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_return_swqe(eibnx_wqe_t *wqe)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ASSERT(wqe->qe_type == ENX_QETYP_SWQE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&wqe->qe_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * This send wqe is from the completion queue. We need to
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * clear the 'posted' flag first.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ASSERT((wqe->qe_flags & ENX_QEFL_POSTED) == ENX_QEFL_POSTED);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan wqe->qe_flags &= (~ENX_QEFL_POSTED);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * See if we need to release this send wqe back to the pool
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * on completion. We may not need to do so if, for example,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * this were a swqe acquired specifically for a particular gw.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (wqe->qe_flags & ENX_QEFL_RELONCOMP) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan wqe->qe_sgl.ds_len = wqe->qe_bufsz;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan wqe->qe_flags &= (~ENX_QEFL_INUSE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan wqe->qe_flags &= (~ENX_QEFL_RELONCOMP);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&wqe->qe_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Return a RWQE from completion. We probably have to repost it.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_return_rwqe(eibnx_thr_info_t *info, eibnx_wqe_t *wqe)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_status_t ret;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ASSERT(wqe->qe_type == ENX_QETYP_RWQE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&wqe->qe_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * We should never need to free an rwqe on completion.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ASSERT((wqe->qe_flags & ENX_QEFL_RELONCOMP) == 0);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * An rwqe is always in-use and posted, so we only need to make
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * sure the ds_len is adjusted back to the value it's supposed
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * to have.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan wqe->qe_sgl.ds_len = wqe->qe_bufsz;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Repost the recv wqe
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ret = ibt_post_recv(info->ti_chan, &(wqe->qe_wr.recv), 1, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ret != IBT_SUCCESS) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("ibt_post_recv(chan_hdl=0x%llx) failed, "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "ret=%d", info->ti_chan, ret);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&wqe->qe_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Release an SWQE that was acquired earlier.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_release_swqe(eibnx_wqe_t *wqe)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ASSERT(wqe->qe_type == ENX_QETYP_SWQE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&wqe->qe_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Make sure this swqe is in use. Since this routine may also be
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * called when we're trying to cleanup the eoib nodes, we
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * should clear all flag bits.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ASSERT((wqe->qe_flags & ENX_QEFL_INUSE) == ENX_QEFL_INUSE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan wqe->qe_flags = 0;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&wqe->qe_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Insert the passed child to the head of the queue
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_enqueue_child(eibnx_thr_info_t *info, eibnx_gw_info_t *gwi,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan char *node_name, dev_info_t *dip)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_child_t *ch;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_child_t *new_ch;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_ch = kmem_zalloc(sizeof (eibnx_child_t), KM_SLEEP);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_ch->ch_dip = dip;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_ch->ch_node_name = node_name;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_ch->ch_gwi = gwi;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&info->ti_child_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Search existing children to see if we already have this
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * child. If so, simply update its dip and node_name
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (ch = info->ti_child; ch; ch = ch->ch_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ch->ch_gwi->gw_portid == gwi->gw_portid) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ch->ch_dip = dip;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ch->ch_node_name) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(ch->ch_node_name, MAXNAMELEN);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ch->ch_node_name = node_name;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(new_ch, sizeof (eibnx_child_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If not, add the new child to the list of children
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_ch->ch_next = info->ti_child;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_child = new_ch;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&info->ti_child_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanint
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_update_child(eibnx_thr_info_t *info, eibnx_gw_info_t *gwi,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan dev_info_t *dip)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_child_t *ch;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&info->ti_child_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (ch = info->ti_child; ch; ch = ch->ch_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ch->ch_gwi->gw_portid == gwi->gw_portid) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ch->ch_dip != dip) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_DEBUG("updating child dip for "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "gw portid 0x%x to 0x%llx",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_portid, dip);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ch->ch_dip = dip;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&info->ti_child_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (ENX_E_SUCCESS);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&info->ti_child_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (ENX_E_FAILURE);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalandev_info_t *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_find_child_dip_by_inst(eibnx_thr_info_t *info, int inst)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_child_t *ch;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan dev_info_t *dip = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&info->ti_child_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (ch = info->ti_child; ch != NULL; ch = ch->ch_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan dip = ch->ch_dip;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ddi_get_instance(dip) == inst)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&info->ti_child_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (dip);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalandev_info_t *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_find_child_dip_by_gw(eibnx_thr_info_t *info, uint16_t gw_portid)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_child_t *ch;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan dev_info_t *dip = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&info->ti_child_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (ch = info->ti_child; ch != NULL; ch = ch->ch_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan dip = ch->ch_dip;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ch->ch_gwi->gw_portid == gw_portid)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&info->ti_child_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (dip);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * See if the passed gateway is already found in our list. Note
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * that we assume that the gateway port id uniquely identifies each
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * gateway.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_gw_info_t *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_find_gw_in_gwlist(eibnx_thr_info_t *info, eibnx_gw_info_t *gwi)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_gw_info_t *lgw = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&info->ti_gw_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan for (lgw = info->ti_gw; lgw; lgw = lgw->gw_next) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (lgw->gw_portid == gwi->gw_portid)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan break;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&info->ti_gw_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (lgw);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Add a newly discovered gateway to the gateway list. Since we'll
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * need to send unicast solicitations to this gateway soon, we'll
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * also grab a swqe entry, and initialize basic gw adress parameters
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * such as the gid, qpn, qkey and pkey of the GW. When we eventually
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * get to sending the unicast to this gateway for the first time,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * we'll discover the path to this gateway using these parameters
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * and modify the ud destination handle appropriately.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_gw_info_t *
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_add_gw_to_gwlist(eibnx_thr_info_t *info, eibnx_gw_info_t *gwi,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ibt_wc_t *wc, uint8_t *recv_buf)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_gw_info_t *new_gwi;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_wqe_t *wqe;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ib_grh_t *grh;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ib_gid_t sgid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan clock_t timeout_usecs;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * For now, we'll simply do KM_NOSLEEP allocation, since this code
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * is called from within rx processing
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi = kmem_zalloc(sizeof (eibnx_gw_info_t), KM_NOSLEEP);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (new_gwi == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("no memory, gw port_id 0x%x "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "will be ignored by hca_guid=0x%llx, port=0x%x",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_portid, info->ti_hca_guid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_pi->p_port_num);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * We also need to acquire a send wqe to do unicast solicitations
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * to this gateway later on. We should've enough pre-allocated swqes
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * to do this without sleeping.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if ((wqe = eibnx_acquire_swqe(info, KM_NOSLEEP)) == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("no swqe available, gw port_id 0x%x "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "will be ignored by hca_guid=0x%llx, port=0x%x",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gwi->gw_portid, info->ti_hca_guid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_pi->p_port_num);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(new_gwi, sizeof (eibnx_gw_info_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Initialize gw state and wqe information.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_next = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_swqe = wqe;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_state = gwi->gw_state;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Set up gateway advertisement monitoring parameters. Since we
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * always need to check against a timeout value of 2.5 * gw_adv_period,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * we'll keep this pre-calculated value as well.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_init(&new_gwi->gw_adv_lock, NULL, MUTEX_DRIVER, NULL);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_adv_flag = gwi->gw_adv_flag;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_adv_last_lbolt = ddi_get_lbolt64();
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan timeout_usecs = gwi->gw_adv_period * 1000;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan timeout_usecs = ((timeout_usecs << 2) + timeout_usecs) >> 1;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_adv_timeout_ticks = drv_usectohz(timeout_usecs);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Initialize gateway address information. Note that if the message has
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * a GRH, we'll use the subnet prefix, otherwise we'll assume that the
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * gateway is in the same subnet as ourselves.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_addr.ga_vect = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (wc->wc_flags & IBT_WC_GRH_PRESENT) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan grh = (ib_grh_t *)(uintptr_t)recv_buf;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_addr.ga_gid.gid_prefix =
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ntohll(grh->SGID.gid_prefix);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan sgid = info->ti_pi->p_sgid_tbl[0];
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_addr.ga_gid.gid_prefix =
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan sgid.gid_prefix;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_addr.ga_gid.gid_guid = gwi->gw_guid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_addr.ga_qpn = gwi->gw_ctrl_qpn;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_addr.ga_qkey = EIB_FIP_QKEY;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_addr.ga_pkey = EIB_ADMIN_PKEY;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Initialize gateway parameters received via the advertisement
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_system_guid = gwi->gw_system_guid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_guid = gwi->gw_guid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_adv_period = gwi->gw_adv_period;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_ka_period = gwi->gw_ka_period;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_vnic_ka_period = gwi->gw_vnic_ka_period;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_ctrl_qpn = gwi->gw_ctrl_qpn;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_lid = gwi->gw_lid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_portid = gwi->gw_portid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_num_net_vnics = gwi->gw_num_net_vnics;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_is_host_adm_vnics = gwi->gw_is_host_adm_vnics;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_sl = gwi->gw_sl;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_n_rss_qpn = gwi->gw_n_rss_qpn;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_flag_ucast_advt = gwi->gw_flag_ucast_advt;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_flag_available = gwi->gw_flag_available;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(gwi->gw_system_name, new_gwi->gw_system_name,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan sizeof (new_gwi->gw_system_name));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(gwi->gw_port_name, new_gwi->gw_port_name,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan sizeof (new_gwi->gw_port_name));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(gwi->gw_vendor_id, new_gwi->gw_vendor_id,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan sizeof (new_gwi->gw_vendor_id));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Queue up the new gwi and return it
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&info->ti_gw_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_next = info->ti_gw;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_gw = new_gwi;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&info->ti_gw_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return (new_gwi);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Update old data for the gateway in our list with the new data.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_replace_gw_in_gwlist(eibnx_thr_info_t *info, eibnx_gw_info_t *orig_gwi,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_gw_info_t *new_gwi, ibt_wc_t *wc, uint8_t *recv_buf,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan boolean_t *gwi_changed)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ib_sn_prefix_t new_gw_sn_prefix;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ib_grh_t *grh;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ib_gid_t sgid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan boolean_t changed = B_FALSE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan boolean_t gw_addr_changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * We'll update all info received in the new advertisement in
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * the original gwi and also move the gw_state to that of the state
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * in the new gwi.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&info->ti_gw_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_state = new_gwi->gw_state;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * The guids shouldn't really change for the "same" gateway
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (new_gwi->gw_system_guid != orig_gwi->gw_system_guid) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("gateway system guid changed for the "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "*same* gateway from 0x%llx to 0x%llx",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_system_guid, new_gwi->gw_system_guid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_system_guid = new_gwi->gw_system_guid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (new_gwi->gw_guid != orig_gwi->gw_guid) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("gateway guid changed for the "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "*same* gateway from 0x%llx to 0x%llx",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_guid, new_gwi->gw_guid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_guid = new_gwi->gw_guid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gw_addr_changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (new_gwi->gw_adv_period != orig_gwi->gw_adv_period) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_DEBUG("gateway adv period changed "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "from 0x%lx to 0x%lx", orig_gwi->gw_adv_period,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_adv_period);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_adv_period = new_gwi->gw_adv_period;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (new_gwi->gw_ka_period != orig_gwi->gw_ka_period) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_DEBUG("gateway ka period changed "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "from 0x%lx to 0x%lx", orig_gwi->gw_ka_period,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_ka_period);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_ka_period = new_gwi->gw_ka_period;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (new_gwi->gw_vnic_ka_period != orig_gwi->gw_vnic_ka_period) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_DEBUG("vnic ka period changed "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "from 0x%lx to 0x%lx", orig_gwi->gw_vnic_ka_period,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_vnic_ka_period);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_vnic_ka_period = new_gwi->gw_vnic_ka_period;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (new_gwi->gw_ctrl_qpn != orig_gwi->gw_ctrl_qpn) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_DEBUG("gateway control qpn changed "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "from 0x%lx to 0x%lx", orig_gwi->gw_ctrl_qpn,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_ctrl_qpn);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_ctrl_qpn = new_gwi->gw_ctrl_qpn;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (new_gwi->gw_lid != orig_gwi->gw_lid) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_DEBUG("gateway lid changed from 0x%x to 0x%x",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_lid, new_gwi->gw_lid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_lid = new_gwi->gw_lid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gw_addr_changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * The identity of the gateway is currently defined by its portid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * so this cannot be different or eibnx_find_gw_in_gwlist() wouldn't
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * have thought it's the same. For now though, we'll treat it
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * like any other parameter, and flag it if we find this different.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (new_gwi->gw_portid != orig_gwi->gw_portid) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("gateway portid changed for the *same* "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "gateway from 0x%x to 0x%x", orig_gwi->gw_portid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_portid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_portid = new_gwi->gw_portid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (new_gwi->gw_is_host_adm_vnics != orig_gwi->gw_is_host_adm_vnics) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_DEBUG("host adm vnics changed from 0x%x to 0x%x",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_is_host_adm_vnics,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gwi->gw_is_host_adm_vnics);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_is_host_adm_vnics = new_gwi->gw_is_host_adm_vnics;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (new_gwi->gw_sl != orig_gwi->gw_sl) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_DEBUG("gateway sl changed from 0x%x to 0x%x",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_sl, new_gwi->gw_sl);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_sl = new_gwi->gw_sl;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (new_gwi->gw_n_rss_qpn != orig_gwi->gw_n_rss_qpn) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_DEBUG("gateway n_rss_qpn changed from 0x%x to 0x%x",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_n_rss_qpn, new_gwi->gw_n_rss_qpn);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_n_rss_qpn = new_gwi->gw_n_rss_qpn;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * The gw_flag_ucast_advt and gw_flag_available are expected to
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * change over time (and even gw_num_net_vnics could change, but
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * it's of no use to us presently), and we shouldn't trigger any
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * flag for these
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_flag_ucast_advt = new_gwi->gw_flag_ucast_advt;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_flag_available = new_gwi->gw_flag_available;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_num_net_vnics = new_gwi->gw_num_net_vnics;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (strncmp((const char *)new_gwi->gw_system_name,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (const char *)orig_gwi->gw_system_name, EIB_GW_SYSNAME_LEN) != 0) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_DEBUG("gateway system name changed from %s to %s",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_system_name, new_gwi->gw_system_name);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(new_gwi->gw_system_name, orig_gwi->gw_system_name,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_GW_SYSNAME_LEN);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (strncmp((const char *)new_gwi->gw_port_name,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (const char *)orig_gwi->gw_port_name, EIB_GW_PORTNAME_LEN) != 0) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_DEBUG("gateway port name changed from %s to %s",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_port_name, new_gwi->gw_port_name);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(new_gwi->gw_port_name, orig_gwi->gw_port_name,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_GW_PORTNAME_LEN);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (strncmp((const char *)new_gwi->gw_vendor_id,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan (const char *)orig_gwi->gw_vendor_id, EIB_GW_VENDOR_LEN) != 0) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_DEBUG("vendor id changed from %s to %s",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_vendor_id, new_gwi->gw_vendor_id);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan bcopy(new_gwi->gw_vendor_id, orig_gwi->gw_vendor_id,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan EIB_GW_VENDOR_LEN);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * See if the subnet prefix for the gateway has changed
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (wc->wc_flags & IBT_WC_GRH_PRESENT) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan grh = (ib_grh_t *)(uintptr_t)recv_buf;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gw_sn_prefix = ntohll(grh->SGID.gid_prefix);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan sgid = info->ti_pi->p_sgid_tbl[0];
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_gw_sn_prefix = sgid.gid_prefix;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (new_gw_sn_prefix != orig_gwi->gw_addr.ga_gid.gid_prefix) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("subnet prefix changed from 0x%llx to 0x%llx",
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_addr.ga_gid.gid_prefix, new_gw_sn_prefix);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan gw_addr_changed = B_TRUE;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If the gateway address has changed in any way, clear the current
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * address vector and update the gateway guid and gateway qpn. The
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * address vector will be created the next time a unicast solicit
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * is attempted for this gateway.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (gw_addr_changed) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (orig_gwi->gw_addr.ga_vect != NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(orig_gwi->gw_addr.ga_vect,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan sizeof (ibt_adds_vect_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_addr.ga_vect = NULL;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_addr.ga_gid.gid_prefix = new_gw_sn_prefix;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_addr.ga_gid.gid_guid = new_gwi->gw_guid;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_addr.ga_qpn = new_gwi->gw_ctrl_qpn;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_addr.ga_qkey = EIB_FIP_QKEY;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan orig_gwi->gw_addr.ga_pkey = EIB_ADMIN_PKEY;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&info->ti_gw_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (gwi_changed) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan *gwi_changed = changed;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan/*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * Queue up a node for EoIB instantiation and wake up the thread
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * that creates eoib nodes.
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalanvoid
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalaneibnx_queue_for_creation(eibnx_thr_info_t *info, eibnx_gw_info_t *gwi)
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan{
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_t *ss = enx_global_ss;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan eibnx_nodeq_t *new_node;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * For now, we'll simply do KM_NOSLEEP allocation, since this
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * code is called from within rx processing
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_node = kmem_zalloc(sizeof (eibnx_nodeq_t), KM_NOSLEEP);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (new_node == NULL) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ENX_DPRINTF_WARN("no memory, eoib node will not be "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "created for hca_guid=0x%llx, hca_port=0x%x, "
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan "gw_port_id=0x%x", info->ti_hca_guid,
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan info->ti_pi->p_port_num, gwi->gw_portid);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan return;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_node->nc_info = info;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_node->nc_gwi = gwi;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan /*
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * If the eoib node creation thread is dying (or dead), don't
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan * queue up any more requests for creation
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan */
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_enter(&ss->nx_nodeq_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan if (ss->nx_nodeq_thr_die) {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan kmem_free(new_node, sizeof (eibnx_nodeq_t));
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan } else {
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan new_node->nc_next = ss->nx_nodeq;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan ss->nx_nodeq = new_node;
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan cv_signal(&ss->nx_nodeq_cv);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan }
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan mutex_exit(&ss->nx_nodeq_lock);
b494511a9cf72b1fc4eb13a0e593f55c624ab829Venki Rajagopalan}