9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * CDDL HEADER START
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The contents of this file are subject to the terms of the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Common Development and Distribution License (the "License").
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * You may not use this file except in compliance with the License.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * or http://www.opensolaris.org/os/licensing.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * See the License for the specific language governing permissions
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * and limitations under the License.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * When distributing Covered Code, include this CDDL HEADER in each
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If applicable, add the following below this CDDL HEADER, with the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * fields enclosed by brackets "[]" replaced with your own identifying
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * information: Portions Copyright [yyyy] [name of copyright owner]
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * CDDL HEADER END
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Use is subject to license terms.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_agents.c
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Tavor InfiniBand Management Agent (SMA, PMA, BMA) routines
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Implements all the routines necessary for initializing, handling,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * and (later) tearing down all the infrastructure necessary for Tavor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * MAD processing.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/types.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/conf.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/ddi.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/sunddi.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/modctl.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/ib/adapters/tavor/tavor.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/ib/mgt/ibmf/ibmf.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/disp.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void tavor_agent_request_cb(ibmf_handle_t ibmf_handle,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibmf_msg_t *msgp, void *args);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void tavor_agent_handle_req(void *cb_args);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void tavor_agent_response_cb(ibmf_handle_t ibmf_handle,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibmf_msg_t *msgp, void *args);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_agent_list_init(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void tavor_agent_list_fini(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_agent_register_all(tavor_state_t *state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int tavor_agent_unregister_all(tavor_state_t *state, int num_reg);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void tavor_agent_mad_resp_handling(tavor_state_t *state,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibmf_msg_t *msgp, uint_t port);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_agent_handlers_init()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() and/or detach() path contexts
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorint
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_agent_handlers_init(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor char *errormsg, *rsrc_name;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_agent_handlers_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Determine if we need to register any agents with the IBMF */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((state->ts_cfg_profile->cp_qp0_agents_in_fw) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (state->ts_cfg_profile->cp_qp1_agents_in_fw)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_handlers_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Build a unique name for the Tavor task queue from the Tavor driver
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * instance number and TAVOR_TASKQ_NAME
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rsrc_name = (char *)kmem_zalloc(TAVOR_RSRC_NAME_MAXLEN, KM_SLEEP);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_TASKQ_NAME);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Initialize the Tavor IB management agent list */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_agent_list_init(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Set "status" and "errormsg" and goto failure */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_FAIL(DDI_FAILURE, "failed agent list init");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto agentsinit_fail;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Initialize the agent handling task queue. Note: We set the task
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * queue priority to the minimum system priority. At this point this
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * is considered acceptable because MADs are unreliable datagrams
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * and could get lost (in general) anyway.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_taskq_agents = ddi_taskq_create(state->ts_dip,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rsrc_name, TAVOR_TASKQ_NTHREADS, TASKQ_DEFAULTPRI, 0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_taskq_agents == NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_agent_list_fini(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Set "status" and "errormsg" and goto failure */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_FAIL(DDI_FAILURE, "failed task queue");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto agentsinit_fail;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Now attempt to register all of the agents with the IBMF */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_agent_register_all(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_taskq_destroy(state->ts_taskq_agents);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_agent_list_fini(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Set "status" and "errormsg" and goto failure */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_FAIL(DDI_FAILURE, "failed IBMF register");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto agentsinit_fail;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(rsrc_name, TAVOR_RSRC_NAME_MAXLEN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_handlers_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Tayloragentsinit_fail:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(rsrc_name, TAVOR_RSRC_NAME_MAXLEN);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_1(tavor_agent_handlers_init_fail, TAVOR_TNF_ERROR, "",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tnf_string, msg, errormsg);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_handlers_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_agent_handlers_fini()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from detach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorint
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_agent_handlers_fini(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_agent_handlers_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Determine if we need to unregister any agents from the IBMF */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((state->ts_cfg_profile->cp_qp0_agents_in_fw) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (state->ts_cfg_profile->cp_qp1_agents_in_fw)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_handlers_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Now attempt to unregister all of the agents from the IBMF */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_agent_unregister_all(state, state->ts_num_agents);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != DDI_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_agent_handlers_fini_unreg_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_handlers_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Destroy the task queue. The task queue destroy is guaranteed to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * wait until any scheduled tasks have completed. We are able to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * guarantee that no _new_ tasks will be added the task queue while
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * we are in the ddi_taskq_destroy() call because we have
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * (at this point) successfully unregistered from IBMF (in
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_agent_unregister_all() above).
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ddi_taskq_destroy(state->ts_taskq_agents);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Teardown the Tavor IB management agent list */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_agent_list_fini(state);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_handlers_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_agent_request_cb()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Called from the IBMF context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_agent_request_cb(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor void *args)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_agent_handler_arg_t *cb_args;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_agent_list_t *curr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_state_t *state;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int ibmf_status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_agent_request_cb);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor curr = (tavor_agent_list_t *)args;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state = curr->agl_state;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Allocate space to hold the callback args (for passing to the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * task queue). Note: If we are unable to allocate space for the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the callback args here, then we just return. But we must ensure
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that we call ibmf_free_msg() to free up the message.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cb_args = (tavor_agent_handler_arg_t *)kmem_zalloc(
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sizeof (tavor_agent_handler_arg_t), KM_NOSLEEP);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (cb_args == NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibmf_status = ibmf_free_msg(ibmf_handle, &msgp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ibmf_status != IBMF_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_1(tavor_agent_request_cb_ibmf_free_msg_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_uint, ibmf_status,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibmf_status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_agent_request_cb_kma_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_request_cb);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*cb_args))
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Fill in the callback args */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cb_args->ahd_ibmfhdl = ibmf_handle;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cb_args->ahd_ibmfmsg = msgp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cb_args->ahd_agentlist = args;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Dispatch the message to the task queue. Note: Just like above,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * if this request fails for any reason then make sure to free up
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the IBMF message and then return
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ddi_taskq_dispatch(state->ts_taskq_agents,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_agent_handle_req, cb_args, DDI_NOSLEEP);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status == DDI_FAILURE) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(cb_args, sizeof (tavor_agent_handler_arg_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibmf_status = ibmf_free_msg(ibmf_handle, &msgp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ibmf_status != IBMF_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_1(tavor_agent_request_cb_ibmf_free_msg_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_uint, ibmf_status,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibmf_status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_agent_request_cb_taskq_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_request_cb);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_agent_handle_req()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Called with priority of taskQ thread
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_agent_handle_req(void *cb_args)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_agent_handler_arg_t *agent_args;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_agent_list_t *curr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_state_t *state;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibmf_handle_t ibmf_handle;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibmf_msg_t *msgp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibmf_msg_bufs_t *recv_msgbufp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibmf_msg_bufs_t *send_msgbufp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibmf_retrans_t retrans;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t port;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_agent_handle_req);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Extract the necessary info from the callback args parameter */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor agent_args = (tavor_agent_handler_arg_t *)cb_args;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibmf_handle = agent_args->ahd_ibmfhdl;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor msgp = agent_args->ahd_ibmfmsg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor curr = agent_args->ahd_agentlist;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state = curr->agl_state;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor port = curr->agl_port;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Set the message send buffer pointers to the message receive buffer
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * pointers to reuse the IBMF provided buffers for the sender
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * information.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor recv_msgbufp = &msgp->im_msgbufs_recv;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor send_msgbufp = &msgp->im_msgbufs_send;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor bcopy(recv_msgbufp, send_msgbufp, sizeof (ibmf_msg_bufs_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Check if the incoming packet is a special "Tavor Trap" MAD. If it
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * is, then do the special handling. If it isn't, then simply pass it
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * on to the firmware and forward the response back to the IBMF.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Note: Tavor has a unique method for handling internally generated
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Traps. All internally detected/generated Trap messages are
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * automatically received by the IBMF (as receive completions on QP0),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * which (because all Tavor Trap MADs have SLID == 0) detects it as a
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * special "Tavor Trap" and forwards it here to the driver's SMA.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * It is then our responsibility here to fill in the Trap MAD's DLID
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * for forwarding to the real Master SM (as programmed in the port's
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * PortInfo.MasterSMLID field.)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(msgp->im_local_addr))
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (TAVOR_IS_SPECIAL_TRAP_MAD(msgp)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor msgp->im_local_addr.ia_remote_lid =
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_PORT_MASTERSMLID_GET(state, port - 1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Post the command to the firmware (using the MAD_IFC
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * command). Note: We also reuse the command that was passed
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * in. We pass the pointer to the original MAD payload as if
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * it were both the source of the incoming MAD as well as the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * destination for the response. This is acceptable and saves
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * us the step of one additional copy. Note: If this command
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * fails for any reason other than TAVOR_CMD_BAD_PKT, it
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * probably indicates a serious problem.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = tavor_mad_ifc_cmd_post(state, port,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_CMD_SLEEP_NOSPIN,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (uint32_t *)recv_msgbufp->im_bufs_mad_hdr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (uint32_t *)send_msgbufp->im_bufs_mad_hdr);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != TAVOR_CMD_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((status != TAVOR_CMD_BAD_PKT) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (status != TAVOR_CMD_INSUFF_RSRC)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor cmn_err(CE_CONT, "Tavor: MAD_IFC (port %02d) "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "command failed: %08x\n", port, status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_1(tavor_agent_handle_req_madifc_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_uint, cmd_status,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* finish cleanup */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto tavor_agent_handle_req_skip_response;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If incoming MAD was "TrapRepress", then no response is necessary.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Free the IBMF message and return.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (TAVOR_IS_TRAP_REPRESS_MAD(msgp)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto tavor_agent_handle_req_skip_response;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Modify the response MAD as necessary (for any special cases).
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Specifically, if this MAD was a directed route MAD, then some
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * additional packet manipulation may be necessary because the Tavor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * firmware does not do all the required steps to respond to the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * MAD.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_agent_mad_resp_handling(state, msgp, port);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Send response (or forwarded "Trap" MAD) back to IBMF. We use the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * "response callback" to indicate when it is appropriate (later) to
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * free the IBMF msg.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ibmf_msg_transport(ibmf_handle, IBMF_QP_HANDLE_DEFAULT,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor msgp, &retrans, tavor_agent_response_cb, state, 0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != IBMF_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_1(tavor_ibmf_send_msg_fail, TAVOR_TNF_ERROR, "",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tnf_uint, ibmf_status, status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto tavor_agent_handle_req_skip_response;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free up the callback args parameter */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(agent_args, sizeof (tavor_agent_handler_arg_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_handle_req);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_agent_handle_req_skip_response:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free up the ibmf message */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ibmf_free_msg(ibmf_handle, &msgp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != IBMF_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_1(tavor_agent_handle_req_ibmf_free_msg_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_uint, ibmf_status,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free up the callback args parameter */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(agent_args, sizeof (tavor_agent_handler_arg_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_handle_req);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_agent_response_cb()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Called from the IBMF context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/* ARGSUSED */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_agent_response_cb(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor void *args)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_agent_response_cb);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * It is the responsibility of each IBMF callback recipient to free
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the packets that it has been given. Now that we are in the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * response callback, we can be assured that it is safe to do so.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ibmf_free_msg(ibmf_handle, &msgp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != IBMF_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_1(tavor_agent_response_cb_ibmf_free_msg_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "", tnf_uint, ibmf_status, status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_response_cb);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_agent_list_init()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_agent_list_init(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_agent_list_t *curr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t num_ports, num_agents, num_agents_per_port;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t num_sma_agents = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t num_pma_agents = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t num_bma_agents = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t do_qp0, do_qp1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int i, j, indx;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_agent_list_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Calculate the number of registered agents for each port
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * (SMA, PMA, and BMA) and determine whether or not to register
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * a given agent with the IBMF (or whether to let the Tavor firmware
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * handle it)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_ports = state->ts_cfg_profile->cp_num_ports;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_agents = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_agents_per_port = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor do_qp0 = state->ts_cfg_profile->cp_qp0_agents_in_fw;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor do_qp1 = state->ts_cfg_profile->cp_qp1_agents_in_fw;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (do_qp0 == 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_agents += (num_ports * TAVOR_NUM_QP0_AGENTS_PER_PORT);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_agents_per_port += TAVOR_NUM_QP0_AGENTS_PER_PORT;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_sma_agents = num_ports;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (do_qp1 == 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_agents += (num_ports * TAVOR_NUM_QP1_AGENTS_PER_PORT);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_agents_per_port += TAVOR_NUM_QP1_AGENTS_PER_PORT;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_pma_agents = num_ports;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The following line is commented out because the Tavor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * firmware does not currently support a BMA. If it did,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * then we would want to register the agent with the IBMF.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * (We would also need to have TAVOR_NUM_QP1_AGENTS_PER_PORT
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * set to 2, instead of 1.)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * num_bma_agents = num_ports;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_num_agents = num_agents;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Allocate the memory for all of the agent list entries
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_agents = (tavor_agent_list_t *)kmem_zalloc(num_agents *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sizeof (tavor_agent_list_t), KM_SLEEP);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (state->ts_agents == NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_agent_list_init_kma_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_list_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Fill in each of the agent list entries with the agent's
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * MgmtClass, port number, and Tavor softstate pointer
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor indx = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < num_agents_per_port; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (j = 0; j < num_ports; j++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor curr = &state->ts_agents[indx];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor curr->agl_state = state;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor curr->agl_port = j + 1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((do_qp0 == 0) && num_sma_agents) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor curr->agl_mgmtclass = SUBN_AGENT;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_sma_agents--;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor indx++;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else if ((do_qp1 == 0) && (num_pma_agents)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor curr->agl_mgmtclass = PERF_AGENT;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_pma_agents--;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor indx++;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else if ((do_qp1 == 0) && (num_bma_agents)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor curr->agl_mgmtclass = BM_AGENT;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_bma_agents--;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor indx++;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_list_init);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_agent_list_fini()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() and/or detach() path contexts
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_agent_list_fini(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_agent_list_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Free up the memory for the agent list entries */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor kmem_free(state->ts_agents,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor state->ts_num_agents * sizeof (tavor_agent_list_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_list_fini);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_agent_register_all()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from attach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_agent_register_all(tavor_state_t *state)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_agent_list_t *curr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibmf_register_info_t ibmf_reg;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibmf_impl_caps_t impl_caps;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ib_guid_t nodeguid;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int i, status, num_registered;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_agent_register_all);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Get the Tavor NodeGUID from the softstate */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor nodeguid = state->ts_ibtfinfo.hca_attr->hca_node_guid;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Register each of the agents with the IBMF (and add callbacks for
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * each to the tavor_agent_request_cb() routine). Note: If we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * fail somewhere along the line here, we attempt to cleanup as much
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * of the mess as we can and then jump to tavor_agent_unregister_all()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * to cleanup the rest.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_registered = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < state->ts_num_agents; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Register each agent with the IBMF */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor curr = &state->ts_agents[i];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibmf_reg.ir_ci_guid = nodeguid;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibmf_reg.ir_port_num = curr->agl_port;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ibmf_reg.ir_client_class = curr->agl_mgmtclass;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ibmf_register(&ibmf_reg, IBMF_VERSION, 0,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor NULL, NULL, &curr->agl_ibmfhdl, &impl_caps);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != IBMF_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_agent_register_all_ibmf_reg_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto agents_reg_fail;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Setup callbacks with the IBMF */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ibmf_setup_async_cb(curr->agl_ibmfhdl,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IBMF_QP_HANDLE_DEFAULT, tavor_agent_request_cb, curr, 0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != IBMF_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) ibmf_unregister(&curr->agl_ibmfhdl, 0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_agent_register_all_ibmf_cb_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto agents_reg_fail;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor num_registered++;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_register_all);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Tayloragents_reg_fail:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) tavor_agent_unregister_all(state, num_registered);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_register_all);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_agent_unregister_all()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Only called from detach() path context
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_agent_unregister_all(tavor_state_t *state, int num_reg)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tavor_agent_list_t *curr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int i, status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ENTER(tavor_agent_unregister_all);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * For each registered agent in the agent list, teardown the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * callbacks from the IBMF and unregister.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < num_reg; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor curr = &state->ts_agents[i];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Teardown the IBMF callback */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ibmf_tear_down_async_cb(curr->agl_ibmfhdl,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IBMF_QP_HANDLE_DEFAULT, 0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != IBMF_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_agents_unreg_teardown_cb_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_unregister_all);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Unregister the agent from the IBMF */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor status = ibmf_unregister(&curr->agl_ibmfhdl, 0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (status != IBMF_SUCCESS) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TNF_PROBE_0(tavor_agents_unreg_ibmf_fail,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_ERROR, "");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_unregister_all);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_TNF_EXIT(tavor_agent_unregister_all);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DDI_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * tavor_agent_mad_resp_handling()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Context: Called with priority of taskQ thread
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/* ARGSUSED */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic void
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylortavor_agent_mad_resp_handling(tavor_state_t *state, ibmf_msg_t *msgp,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t port)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ib_mad_hdr_t *rmadhdrp = msgp->im_msgbufs_recv.im_bufs_mad_hdr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ib_mad_hdr_t *smadhdrp = msgp->im_msgbufs_send.im_bufs_mad_hdr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint_t hop_count, hop_point;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uchar_t *resp, *ret_path;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor resp = (uchar_t *)msgp->im_msgbufs_send.im_bufs_cl_data;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Handle directed route MADs as a special case. Tavor firmware
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * does not update the "direction" bit, "hop pointer", "Return
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Path" or, in fact, any of the "directed route" parameters. So
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the responsibility falls on Tavor driver software to inspect the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * MADs and update those fields as appropriate (see section 14.2.2
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * of the IBA specification, rev 1.1)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (TAVOR_MAD_IS_DR(rmadhdrp)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*((sm_dr_mad_hdr_t *)rmadhdrp)))
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*((sm_dr_mad_hdr_t *)smadhdrp)))
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Set the "Direction" bit to one. This indicates that this
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * is now directed route response
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_DRMAD_SET_DIRECTION(rmadhdrp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Extract the "hop pointer" and "hop count" from the MAD */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hop_count = TAVOR_DRMAD_GET_HOPCOUNT(rmadhdrp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hop_point = TAVOR_DRMAD_GET_HOPPOINTER(rmadhdrp);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Append the port we came in on to the "Return Path" */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((hop_count != 0) && ((hop_point == hop_count) ||
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (hop_point == hop_count + 1))) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ret_path = &resp[TAVOR_DRMAD_RETURN_PATH_OFFSET];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ret_path[hop_point] = port;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* Then increment the "hop pointer" in the MAD */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor hop_point++;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor TAVOR_DRMAD_SET_HOPPOINTER(smadhdrp, hop_point);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}