17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5448978d3Shiremath * Common Development and Distribution License (the "License").
6448978d3Shiremath * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
22a23420cfSShantkumar Hiremath * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate */
247c478bd9Sstevel@tonic-gate
257c478bd9Sstevel@tonic-gate #include <sys/ib/mgt/ibcm/ibcm_impl.h>
267c478bd9Sstevel@tonic-gate #include <sys/ib/ibtl/ibti.h>
27015f8fffShiremath #include <sys/ib/mgt/ibcm/ibcm_arp.h>
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate * ibcm_ti.c
317c478bd9Sstevel@tonic-gate * These routines implement the Communication Manager's interfaces to IBTL.
327c478bd9Sstevel@tonic-gate */
337c478bd9Sstevel@tonic-gate
347c478bd9Sstevel@tonic-gate /* CM rc recycle task args structure definition */
357c478bd9Sstevel@tonic-gate typedef struct ibcm_taskq_recycle_arg_s {
367c478bd9Sstevel@tonic-gate ibt_channel_hdl_t rc_chan;
377c478bd9Sstevel@tonic-gate ibt_cep_flags_t control;
387c478bd9Sstevel@tonic-gate uint8_t hca_port_num;
397c478bd9Sstevel@tonic-gate ibt_recycle_handler_t func;
407c478bd9Sstevel@tonic-gate void *arg;
417c478bd9Sstevel@tonic-gate } ibcm_taskq_recycle_arg_t;
427c478bd9Sstevel@tonic-gate
437c478bd9Sstevel@tonic-gate _NOTE(READ_ONLY_DATA(ibcm_taskq_recycle_arg_s))
447c478bd9Sstevel@tonic-gate
457c478bd9Sstevel@tonic-gate static ibt_status_t ibcm_init_reply_addr(ibcm_hca_info_t *hcap,
467c478bd9Sstevel@tonic-gate ibcm_mad_addr_t *reply_addr, ibt_chan_open_args_t *chan_args,
477c478bd9Sstevel@tonic-gate ibt_chan_open_flags_t flags, ib_time_t *cm_pkt_lt, ib_lid_t prim_slid);
487c478bd9Sstevel@tonic-gate static void ibcm_process_abort_via_taskq(void *args);
497c478bd9Sstevel@tonic-gate static ibt_status_t ibcm_process_rc_recycle_ret(void *recycle_arg);
507c478bd9Sstevel@tonic-gate static ibt_status_t ibcm_process_join_mcg(void *taskq_arg);
517c478bd9Sstevel@tonic-gate static void ibcm_process_async_join_mcg(void *tq_arg);
527c478bd9Sstevel@tonic-gate
5376c04273SRajkumar Sivaprakasam ibt_status_t ibcm_get_node_rec(ibmf_saa_handle_t, sa_node_record_t *,
547c478bd9Sstevel@tonic-gate uint64_t c_mask, void *, size_t *);
557c478bd9Sstevel@tonic-gate
56934f0bccShiremath static ibt_status_t ibcm_close_rc_channel(ibt_channel_hdl_t channel,
57934f0bccShiremath ibcm_state_data_t *statep, ibt_execution_mode_t mode);
58934f0bccShiremath
597c478bd9Sstevel@tonic-gate /* Address Record management definitions */
607c478bd9Sstevel@tonic-gate #define IBCM_DAPL_ATS_NAME "DAPL Address Translation Service"
617c478bd9Sstevel@tonic-gate #define IBCM_DAPL_ATS_SID 0x10000CE100415453ULL
627c478bd9Sstevel@tonic-gate #define IBCM_DAPL_ATS_NBYTES 16
637c478bd9Sstevel@tonic-gate ibcm_svc_info_t *ibcm_ar_svcinfop;
647c478bd9Sstevel@tonic-gate ibcm_ar_t *ibcm_ar_list;
657c478bd9Sstevel@tonic-gate
66934f0bccShiremath /*
67934f0bccShiremath * Tunable parameter to turnoff the overriding of pi_path_mtu value.
68934f0bccShiremath * 1 By default override the path record's pi_path_mtu value to
69934f0bccShiremath * IB_MTU_1K for all RC channels. This is done only for the
70934f0bccShiremath * channels established on Tavor HCA and the path's pi_path_mtu
71934f0bccShiremath * is greater than IB_MTU_1K.
72934f0bccShiremath * 0 Do not override, use pi_path_mtu by default.
73934f0bccShiremath */
74934f0bccShiremath int ibcm_override_path_mtu = 1;
75934f0bccShiremath
767c478bd9Sstevel@tonic-gate #ifdef DEBUG
777c478bd9Sstevel@tonic-gate static void ibcm_print_reply_addr(ibt_channel_hdl_t channel,
787c478bd9Sstevel@tonic-gate ibcm_mad_addr_t *cm_reply_addr);
797c478bd9Sstevel@tonic-gate #endif
807c478bd9Sstevel@tonic-gate
817c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ibcm_port_info_s::{port_ibmf_hdl}))
827c478bd9Sstevel@tonic-gate
837c478bd9Sstevel@tonic-gate /* access is controlled between ibcm_sm.c and ibcm_ti.c by CVs */
847c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("Serialized access by CV", {ibt_rc_returns_t
857c478bd9Sstevel@tonic-gate ibt_ud_returns_t ibt_ap_returns_t ibt_ar_t}))
867c478bd9Sstevel@tonic-gate
877c478bd9Sstevel@tonic-gate /*
887c478bd9Sstevel@tonic-gate * Typically, clients initialize these args in one api call, and use in
897c478bd9Sstevel@tonic-gate * another api
907c478bd9Sstevel@tonic-gate */
917c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("Expected usage of ibtl api by client",
927c478bd9Sstevel@tonic-gate {ibt_path_info_s ibt_cep_path_s ibt_adds_vect_s ibt_mcg_info_s ib_gid_s
937c478bd9Sstevel@tonic-gate ibt_ud_dest_attr_s ibt_ud_dest_s ibt_srv_data_s ibt_redirect_info_s}))
947c478bd9Sstevel@tonic-gate
957c478bd9Sstevel@tonic-gate /*
967c478bd9Sstevel@tonic-gate * ibt_open_rc_channel()
977c478bd9Sstevel@tonic-gate * ibt_open_rc_channel opens a communication channel on the specified
987c478bd9Sstevel@tonic-gate * channel to the specified service. For connection service type qp's
997c478bd9Sstevel@tonic-gate * the CM initiates the CEP to establish the connection and transitions
1007c478bd9Sstevel@tonic-gate * the QP/EEC to the "Ready to send" State modifying the QP/EEC's
1017c478bd9Sstevel@tonic-gate * attributes as necessary.
1027c478bd9Sstevel@tonic-gate * The implementation of this function assumes that alt path is different
1037c478bd9Sstevel@tonic-gate * from primary path. It is assumed that the Path functions ensure that.
1047c478bd9Sstevel@tonic-gate *
1057c478bd9Sstevel@tonic-gate * RETURN VALUES:
1067c478bd9Sstevel@tonic-gate * IBT_SUCCESS on success (or respective failure on error)
1077c478bd9Sstevel@tonic-gate */
1087c478bd9Sstevel@tonic-gate ibt_status_t
ibt_open_rc_channel(ibt_channel_hdl_t channel,ibt_chan_open_flags_t flags,ibt_execution_mode_t mode,ibt_chan_open_args_t * chan_args,ibt_rc_returns_t * ret_args)1097c478bd9Sstevel@tonic-gate ibt_open_rc_channel(ibt_channel_hdl_t channel, ibt_chan_open_flags_t flags,
1107c478bd9Sstevel@tonic-gate ibt_execution_mode_t mode, ibt_chan_open_args_t *chan_args,
1117c478bd9Sstevel@tonic-gate ibt_rc_returns_t *ret_args)
1127c478bd9Sstevel@tonic-gate {
1137c478bd9Sstevel@tonic-gate /* all fields that are related to REQ MAD formation */
1147c478bd9Sstevel@tonic-gate
1157c478bd9Sstevel@tonic-gate ib_pkey_t prim_pkey;
1167c478bd9Sstevel@tonic-gate ib_lid_t primary_slid, alternate_slid;
1177c478bd9Sstevel@tonic-gate ib_qpn_t local_qpn = 0;
1187c478bd9Sstevel@tonic-gate ib_guid_t hca_guid;
1197c478bd9Sstevel@tonic-gate ib_qkey_t local_qkey = 0;
1207c478bd9Sstevel@tonic-gate ib_eecn_t local_eecn = 0;
1217c478bd9Sstevel@tonic-gate ib_eecn_t remote_eecn = 0;
1227c478bd9Sstevel@tonic-gate boolean_t primary_grh;
1237c478bd9Sstevel@tonic-gate boolean_t alternate_grh = B_FALSE;
1247c478bd9Sstevel@tonic-gate ib_lid_t base_lid;
1257c478bd9Sstevel@tonic-gate ib_com_id_t local_comid;
126934f0bccShiremath ibmf_msg_t *ibmf_msg, *ibmf_msg_dreq;
1277c478bd9Sstevel@tonic-gate ibcm_req_msg_t *req_msgp;
1287c478bd9Sstevel@tonic-gate
1297c478bd9Sstevel@tonic-gate uint8_t rdma_in, rdma_out;
1307c478bd9Sstevel@tonic-gate uint8_t cm_retries;
1317c478bd9Sstevel@tonic-gate uint64_t local_cm_proc_time; /* In usec */
1327c478bd9Sstevel@tonic-gate uint8_t local_cm_resp_time; /* IB time */
1337c478bd9Sstevel@tonic-gate uint64_t remote_cm_resp_time; /* In usec */
1347c478bd9Sstevel@tonic-gate uint32_t starting_psn = 0;
1357c478bd9Sstevel@tonic-gate
1367c478bd9Sstevel@tonic-gate /* CM path related fields */
1377c478bd9Sstevel@tonic-gate ibmf_handle_t ibmf_hdl;
1387c478bd9Sstevel@tonic-gate ibcm_qp_list_t *cm_qp_entry;
1397c478bd9Sstevel@tonic-gate ibcm_mad_addr_t cm_reply_addr;
1407c478bd9Sstevel@tonic-gate
1417c478bd9Sstevel@tonic-gate uint8_t cm_pkt_lt;
1427c478bd9Sstevel@tonic-gate
1437c478bd9Sstevel@tonic-gate /* Local args for ibtl/internal CM functions called within */
1447c478bd9Sstevel@tonic-gate ibt_status_t status;
1457c478bd9Sstevel@tonic-gate ibcm_status_t lkup_status;
1467c478bd9Sstevel@tonic-gate ibt_qp_query_attr_t qp_query_attr;
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gate /* Other misc local args */
1497c478bd9Sstevel@tonic-gate ibt_priv_data_len_t len;
1507c478bd9Sstevel@tonic-gate ibcm_hca_info_t *hcap;
1517c478bd9Sstevel@tonic-gate ibcm_state_data_t *statep;
1527c478bd9Sstevel@tonic-gate uint8_t port_no;
1537c478bd9Sstevel@tonic-gate
1547c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_open_rc_channel(chan %p, %X, %x, %p, %p)",
1557c478bd9Sstevel@tonic-gate channel, flags, mode, chan_args, ret_args);
1567c478bd9Sstevel@tonic-gate
1577c478bd9Sstevel@tonic-gate if (IBCM_INVALID_CHANNEL(channel)) {
1587c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: invalid channel");
1597c478bd9Sstevel@tonic-gate return (IBT_CHAN_HDL_INVALID);
1607c478bd9Sstevel@tonic-gate }
1617c478bd9Sstevel@tonic-gate
1627c478bd9Sstevel@tonic-gate /* cm handler should always be specified */
1637c478bd9Sstevel@tonic-gate if (chan_args->oc_cm_handler == NULL) {
1647c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
1657c478bd9Sstevel@tonic-gate "CM handler is not be specified", channel);
1667c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
1677c478bd9Sstevel@tonic-gate }
1687c478bd9Sstevel@tonic-gate
1697c478bd9Sstevel@tonic-gate if (mode == IBT_NONBLOCKING) {
1707c478bd9Sstevel@tonic-gate if (ret_args != NULL) {
1717c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p"
1727c478bd9Sstevel@tonic-gate " ret_args should be NULL when called in "
1737c478bd9Sstevel@tonic-gate "non-blocking mode", channel);
1747c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
1757c478bd9Sstevel@tonic-gate }
1767c478bd9Sstevel@tonic-gate } else if (mode == IBT_BLOCKING) {
1777c478bd9Sstevel@tonic-gate if (ret_args == NULL) {
1787c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p"
1797c478bd9Sstevel@tonic-gate " ret_args should be Non-NULL when called in "
1807c478bd9Sstevel@tonic-gate "blocking mode", channel);
1817c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
1827c478bd9Sstevel@tonic-gate }
1837c478bd9Sstevel@tonic-gate if (ret_args->rc_priv_data_len > IBT_REP_PRIV_DATA_SZ) {
1847c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p"
1857c478bd9Sstevel@tonic-gate " private data length is too large", channel);
1867c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
1877c478bd9Sstevel@tonic-gate }
1887c478bd9Sstevel@tonic-gate if ((ret_args->rc_priv_data_len > 0) &&
1897c478bd9Sstevel@tonic-gate (ret_args->rc_priv_data == NULL)) {
1907c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p"
1917c478bd9Sstevel@tonic-gate " rc_priv_data_len > 0, but rc_priv_data NULL",
1927c478bd9Sstevel@tonic-gate channel);
1937c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
1947c478bd9Sstevel@tonic-gate }
1957c478bd9Sstevel@tonic-gate } else { /* any other mode is not valid for ibt_open_rc_channel */
1967c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
1977c478bd9Sstevel@tonic-gate "invalid mode %x specified", channel, mode);
1987c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
1997c478bd9Sstevel@tonic-gate }
2007c478bd9Sstevel@tonic-gate
2017c478bd9Sstevel@tonic-gate /*
2027c478bd9Sstevel@tonic-gate * XXX: no support yet for ibt_chan_open_flags_t - IBT_OCHAN_DUP
2037c478bd9Sstevel@tonic-gate */
2047c478bd9Sstevel@tonic-gate if (flags & IBT_OCHAN_DUP) {
2057c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
2067c478bd9Sstevel@tonic-gate "Unsupported Flags specified: 0x%X", channel, flags);
2077c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
2087c478bd9Sstevel@tonic-gate }
2097c478bd9Sstevel@tonic-gate
2107c478bd9Sstevel@tonic-gate if ((flags & IBT_OCHAN_REDIRECTED) &&
2117c478bd9Sstevel@tonic-gate (flags & IBT_OCHAN_PORT_REDIRECTED)) {
2127c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
2137c478bd9Sstevel@tonic-gate "Illegal to specify IBT_OCHAN_REDIRECTED and "
2147c478bd9Sstevel@tonic-gate "IBT_OCHAN_PORT_REDIRECTED flags together", channel);
2157c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
2167c478bd9Sstevel@tonic-gate }
2177c478bd9Sstevel@tonic-gate
2187c478bd9Sstevel@tonic-gate if (((flags & IBT_OCHAN_REDIRECTED) &&
2197c478bd9Sstevel@tonic-gate (chan_args->oc_cm_redirect_info == NULL)) ||
2207c478bd9Sstevel@tonic-gate ((flags & IBT_OCHAN_PORT_REDIRECTED) &&
2217c478bd9Sstevel@tonic-gate (chan_args->oc_cm_cep_path == NULL))) {
2227c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
2237c478bd9Sstevel@tonic-gate "Redirect flag specified, but respective arg is NULL",
2247c478bd9Sstevel@tonic-gate channel);
2257c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
2267c478bd9Sstevel@tonic-gate }
2277c478bd9Sstevel@tonic-gate
2287c478bd9Sstevel@tonic-gate if ((flags & IBT_OCHAN_REDIRECTED) &&
2297c478bd9Sstevel@tonic-gate (chan_args->oc_cm_redirect_info->rdi_dlid == 0) &&
2307c478bd9Sstevel@tonic-gate (chan_args->oc_cm_redirect_info->rdi_gid.gid_guid == 0)) {
2317c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
2327c478bd9Sstevel@tonic-gate "Either rdi_dlid or rdi_gid must be specified for"
2337c478bd9Sstevel@tonic-gate " IBT_OCHAN_REDIRECTED", channel);
2347c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
2357c478bd9Sstevel@tonic-gate }
2367c478bd9Sstevel@tonic-gate
2377c478bd9Sstevel@tonic-gate /* primary dlid and hca_port_num should never be zero */
2387c478bd9Sstevel@tonic-gate port_no = IBCM_PRIM_CEP_PATH(chan_args).cep_hca_port_num;
2397c478bd9Sstevel@tonic-gate
2407c478bd9Sstevel@tonic-gate if ((IBCM_PRIM_ADDS_VECT(chan_args).av_dlid == 0) && (port_no == 0)) {
2417c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
2427c478bd9Sstevel@tonic-gate "Primary Path's information is not valid", channel);
2437c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
2447c478bd9Sstevel@tonic-gate }
2457c478bd9Sstevel@tonic-gate
2467c478bd9Sstevel@tonic-gate /* validate SID */
2477c478bd9Sstevel@tonic-gate if (chan_args->oc_path->pi_sid == 0) {
2487c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
2497c478bd9Sstevel@tonic-gate "ERROR: Service ID in path information is 0", channel);
2507c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
2517c478bd9Sstevel@tonic-gate }
252d3a82192SShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibt_open_rc_channel: chan 0x%p SID %llX",
253d3a82192SShantkumar Hiremath channel, chan_args->oc_path->pi_sid);
2547c478bd9Sstevel@tonic-gate
2557c478bd9Sstevel@tonic-gate /* validate rnr_retry_cnt (enum has more than 3 bits) */
2567c478bd9Sstevel@tonic-gate if ((uint_t)chan_args->oc_path_rnr_retry_cnt > IBT_RNR_INFINITE_RETRY) {
2577c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
2587c478bd9Sstevel@tonic-gate "ERROR: oc_path_rnr_retry_cnt(%d) is out of range",
2597c478bd9Sstevel@tonic-gate channel, chan_args->oc_path_rnr_retry_cnt);
2607c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
2617c478bd9Sstevel@tonic-gate }
2627c478bd9Sstevel@tonic-gate
2637c478bd9Sstevel@tonic-gate /*
2647c478bd9Sstevel@tonic-gate * Ensure that client is not re-using a QP that is still associated
2657c478bd9Sstevel@tonic-gate * with a statep
2667c478bd9Sstevel@tonic-gate */
2677c478bd9Sstevel@tonic-gate IBCM_GET_CHAN_PRIVATE(channel, statep);
2687c478bd9Sstevel@tonic-gate if (statep != NULL) {
2697c478bd9Sstevel@tonic-gate IBCM_RELEASE_CHAN_PRIVATE(channel);
2707c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
2717c478bd9Sstevel@tonic-gate "Channel being re-used on active side", channel);
2727c478bd9Sstevel@tonic-gate return (IBT_CHAN_IN_USE);
2737c478bd9Sstevel@tonic-gate }
2747c478bd9Sstevel@tonic-gate
2757c478bd9Sstevel@tonic-gate /* Get GUID from Channel */
2767c478bd9Sstevel@tonic-gate hca_guid = ibt_channel_to_hca_guid(channel);
2777c478bd9Sstevel@tonic-gate
2787c478bd9Sstevel@tonic-gate /* validate QP's hca guid with that from primary path */
2797c478bd9Sstevel@tonic-gate if (hca_guid != chan_args->oc_path->pi_hca_guid) {
2807c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
2817c478bd9Sstevel@tonic-gate "GUID from Channel and primary path don't match", channel);
2827c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
2837c478bd9Sstevel@tonic-gate "Channel GUID %llX primary path GUID %llX", channel,
2847c478bd9Sstevel@tonic-gate hca_guid, chan_args->oc_path->pi_hca_guid);
2857c478bd9Sstevel@tonic-gate return (IBT_CHAN_HDL_INVALID);
2867c478bd9Sstevel@tonic-gate }
2877c478bd9Sstevel@tonic-gate
2887c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
2897c478bd9Sstevel@tonic-gate "Local HCA GUID %llX", channel, hca_guid);
2907c478bd9Sstevel@tonic-gate
2917c478bd9Sstevel@tonic-gate status = ibt_query_qp(channel, &qp_query_attr);
2927c478bd9Sstevel@tonic-gate if (status != IBT_SUCCESS) {
2937c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
2947c478bd9Sstevel@tonic-gate "ibt_query_qp failed %d", channel, status);
2957c478bd9Sstevel@tonic-gate return (status);
2967c478bd9Sstevel@tonic-gate }
2977c478bd9Sstevel@tonic-gate
2987c478bd9Sstevel@tonic-gate /* If client specified "no port change on QP" */
2997c478bd9Sstevel@tonic-gate if ((qp_query_attr.qp_info.qp_transport.rc.rc_path.cep_hca_port_num !=
3007c478bd9Sstevel@tonic-gate port_no) && (flags & IBT_OCHAN_PORT_FIXED)) {
3017c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
3027c478bd9Sstevel@tonic-gate "chan port %d and path port %d does not match", channel,
3037c478bd9Sstevel@tonic-gate qp_query_attr.qp_info.qp_transport.rc.rc_path. \
3047c478bd9Sstevel@tonic-gate cep_hca_port_num, port_no);
3057c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
3067c478bd9Sstevel@tonic-gate }
3077c478bd9Sstevel@tonic-gate
3087c478bd9Sstevel@tonic-gate if (qp_query_attr.qp_info.qp_trans != IBT_RC_SRV) {
3097c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
3107c478bd9Sstevel@tonic-gate "Invalid Channel type: Applicable only to RC Channel",
3117c478bd9Sstevel@tonic-gate channel);
3127c478bd9Sstevel@tonic-gate return (IBT_CHAN_SRV_TYPE_INVALID);
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate
3157c478bd9Sstevel@tonic-gate /* Check if QP is in INIT state or not */
3167c478bd9Sstevel@tonic-gate if (qp_query_attr.qp_info.qp_state != IBT_STATE_INIT) {
3177c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
3187c478bd9Sstevel@tonic-gate "QP is not in INIT state %x", channel,
3197c478bd9Sstevel@tonic-gate qp_query_attr.qp_info.qp_state);
3207c478bd9Sstevel@tonic-gate return (IBT_CHAN_STATE_INVALID);
3217c478bd9Sstevel@tonic-gate }
3227c478bd9Sstevel@tonic-gate
3237c478bd9Sstevel@tonic-gate local_qpn = qp_query_attr.qp_qpn;
3247c478bd9Sstevel@tonic-gate
3257c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p Active QPN 0x%x",
3267c478bd9Sstevel@tonic-gate channel, local_qpn);
3277c478bd9Sstevel@tonic-gate
3287c478bd9Sstevel@tonic-gate #ifdef NO_EEC_SUPPORT_YET
3297c478bd9Sstevel@tonic-gate
3307c478bd9Sstevel@tonic-gate if (flags & IBT_OCHAN_RDC_EXISTS) {
3317c478bd9Sstevel@tonic-gate ibt_eec_query_attr_t eec_query_attr;
3327c478bd9Sstevel@tonic-gate
3337c478bd9Sstevel@tonic-gate local_qkey = qp_query_attr.qp_info.qp_transport.rd_qkey;
3347c478bd9Sstevel@tonic-gate
3357c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: RD");
3367c478bd9Sstevel@tonic-gate
3377c478bd9Sstevel@tonic-gate status = ibt_query_eec(channel, &eec_query_attr);
3387c478bd9Sstevel@tonic-gate if (status != IBT_SUCCESS) {
3397c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p"
3407c478bd9Sstevel@tonic-gate " ibt_query_eec failed %d", channel, status);
3417c478bd9Sstevel@tonic-gate return (status);
3427c478bd9Sstevel@tonic-gate }
3437c478bd9Sstevel@tonic-gate local_eecn = eec_query_attr.eec_eecn;
3447c478bd9Sstevel@tonic-gate }
3457c478bd9Sstevel@tonic-gate
3467c478bd9Sstevel@tonic-gate #endif
3475c42ea03Shiremath if (chan_args->oc_path->pi_prim_pkt_lt > ibcm_max_ib_pkt_lt) {
3485c42ea03Shiremath IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
3495c42ea03Shiremath "Huge PktLifeTime %d, Max is %d", channel,
3505c42ea03Shiremath chan_args->oc_path->pi_prim_pkt_lt, ibcm_max_ib_pkt_lt);
3515c42ea03Shiremath return (IBT_PATH_PKT_LT_TOO_HIGH);
3525c42ea03Shiremath }
3537c478bd9Sstevel@tonic-gate
3547c478bd9Sstevel@tonic-gate /* If no HCA found return failure */
3557c478bd9Sstevel@tonic-gate if ((hcap = ibcm_find_hca_entry(hca_guid)) == NULL) {
3567c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
3577c478bd9Sstevel@tonic-gate "hcap is NULL. Probably hca is not in active state",
3587c478bd9Sstevel@tonic-gate channel);
3597c478bd9Sstevel@tonic-gate return (IBT_CHAN_HDL_INVALID);
3607c478bd9Sstevel@tonic-gate }
3617c478bd9Sstevel@tonic-gate
3627c478bd9Sstevel@tonic-gate rdma_out = chan_args->oc_rdma_ra_out;
3637c478bd9Sstevel@tonic-gate rdma_in = chan_args->oc_rdma_ra_in;
3647c478bd9Sstevel@tonic-gate
3657c478bd9Sstevel@tonic-gate if ((rdma_in > hcap->hca_max_rdma_in_qp) ||
3667c478bd9Sstevel@tonic-gate (rdma_out > hcap->hca_max_rdma_out_qp)) {
3677c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
3685c42ea03Shiremath "rdma in %d/out %d values exceed hca limits(%d/%d)",
3695c42ea03Shiremath channel, rdma_in, rdma_out, hcap->hca_max_rdma_in_qp,
3705c42ea03Shiremath hcap->hca_max_rdma_out_qp);
3717c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
3727c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
3737c478bd9Sstevel@tonic-gate }
3747c478bd9Sstevel@tonic-gate
3757c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
3767c478bd9Sstevel@tonic-gate "rdma_in %d rdma_out %d", channel, rdma_in, rdma_out);
3777c478bd9Sstevel@tonic-gate
3787c478bd9Sstevel@tonic-gate status = ibt_get_port_state_byguid(hcap->hca_guid, port_no,
3797c478bd9Sstevel@tonic-gate NULL, &base_lid);
3807c478bd9Sstevel@tonic-gate if (status != IBT_SUCCESS) {
3817c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
3827c478bd9Sstevel@tonic-gate "primary port_num %d not active", channel, port_no);
3837c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
3847c478bd9Sstevel@tonic-gate return (status);
3857c478bd9Sstevel@tonic-gate }
3867c478bd9Sstevel@tonic-gate
3877c478bd9Sstevel@tonic-gate /* Validate P_KEY Index */
3887c478bd9Sstevel@tonic-gate status = ibt_index2pkey_byguid(hcap->hca_guid, port_no,
3897c478bd9Sstevel@tonic-gate IBCM_PRIM_CEP_PATH(chan_args).cep_pkey_ix, &prim_pkey);
3907c478bd9Sstevel@tonic-gate if (status != IBT_SUCCESS) {
3917c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
3927c478bd9Sstevel@tonic-gate "Invalid Primary PKeyIx %x", channel,
3937c478bd9Sstevel@tonic-gate IBCM_PRIM_CEP_PATH(chan_args).cep_pkey_ix);
3947c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
3957c478bd9Sstevel@tonic-gate return (status);
3967c478bd9Sstevel@tonic-gate }
3977c478bd9Sstevel@tonic-gate
3987c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
3997c478bd9Sstevel@tonic-gate "primary_port_num %d primary_pkey 0x%x", channel, port_no,
4007c478bd9Sstevel@tonic-gate prim_pkey);
4017c478bd9Sstevel@tonic-gate
4027c478bd9Sstevel@tonic-gate if ((hcap->hca_port_info[port_no - 1].port_ibmf_hdl == NULL) &&
4037c478bd9Sstevel@tonic-gate ((status = ibcm_hca_reinit_port(hcap, port_no - 1))
4047c478bd9Sstevel@tonic-gate != IBT_SUCCESS)) {
4057c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
4067c478bd9Sstevel@tonic-gate "ibmf reg or callback setup failed during re-initialize",
4077c478bd9Sstevel@tonic-gate channel);
4087c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
4097c478bd9Sstevel@tonic-gate return (status);
4107c478bd9Sstevel@tonic-gate }
4117c478bd9Sstevel@tonic-gate
4127c478bd9Sstevel@tonic-gate ibmf_hdl = hcap->hca_port_info[port_no - 1].port_ibmf_hdl;
4137c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
4147c478bd9Sstevel@tonic-gate "primary ibmf_hdl = 0x%p", channel, ibmf_hdl);
4157c478bd9Sstevel@tonic-gate
4167c478bd9Sstevel@tonic-gate primary_slid = base_lid + IBCM_PRIM_ADDS_VECT(chan_args).av_src_path;
4177c478bd9Sstevel@tonic-gate
4187c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: channel 0x%p "
4197c478bd9Sstevel@tonic-gate "primary SLID = %x", channel, primary_slid);
4207c478bd9Sstevel@tonic-gate
4217c478bd9Sstevel@tonic-gate /* check first if alternate path exists or not as it is OPTIONAL */
4227c478bd9Sstevel@tonic-gate if (IBCM_ALT_CEP_PATH(chan_args).cep_hca_port_num != 0) {
4237c478bd9Sstevel@tonic-gate uint8_t alt_port_no;
4247c478bd9Sstevel@tonic-gate
4257c478bd9Sstevel@tonic-gate alt_port_no = IBCM_ALT_CEP_PATH(chan_args).cep_hca_port_num;
4267c478bd9Sstevel@tonic-gate
4277c478bd9Sstevel@tonic-gate if (chan_args->oc_path->pi_alt_pkt_lt > ibcm_max_ib_pkt_lt) {
4287c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
4297c478bd9Sstevel@tonic-gate "Huge Alt Pkt lt %d", channel,
4307c478bd9Sstevel@tonic-gate chan_args->oc_path->pi_alt_pkt_lt);
4317c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
4327c478bd9Sstevel@tonic-gate return (IBT_PATH_PKT_LT_TOO_HIGH);
4337c478bd9Sstevel@tonic-gate }
4347c478bd9Sstevel@tonic-gate
4357c478bd9Sstevel@tonic-gate if (port_no != alt_port_no) {
4367c478bd9Sstevel@tonic-gate
4377c478bd9Sstevel@tonic-gate status = ibt_get_port_state_byguid(hcap->hca_guid,
4387c478bd9Sstevel@tonic-gate alt_port_no, NULL, &base_lid);
4397c478bd9Sstevel@tonic-gate if (status != IBT_SUCCESS) {
4407c478bd9Sstevel@tonic-gate
4417c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: "
4427c478bd9Sstevel@tonic-gate "chan 0x%p alt_port_num %d inactive %d",
4437c478bd9Sstevel@tonic-gate channel, alt_port_no, status);
4447c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
4457c478bd9Sstevel@tonic-gate return (status);
4467c478bd9Sstevel@tonic-gate }
4477c478bd9Sstevel@tonic-gate
4487c478bd9Sstevel@tonic-gate }
4497c478bd9Sstevel@tonic-gate alternate_slid =
4507c478bd9Sstevel@tonic-gate base_lid + IBCM_ALT_ADDS_VECT(chan_args).av_src_path;
4517c478bd9Sstevel@tonic-gate
4525c42ea03Shiremath IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
4537c478bd9Sstevel@tonic-gate "alternate SLID = %x", channel, alternate_slid);
4547c478bd9Sstevel@tonic-gate }
4557c478bd9Sstevel@tonic-gate
4567c478bd9Sstevel@tonic-gate /*
4577c478bd9Sstevel@tonic-gate * only pkey needs to be zero'ed, because all other fields are set in
4587c478bd9Sstevel@tonic-gate * in ibcm_init_reply_addr. But, let's bzero the complete struct for
4597c478bd9Sstevel@tonic-gate * any future modifications.
4607c478bd9Sstevel@tonic-gate */
4617c478bd9Sstevel@tonic-gate bzero(&cm_reply_addr, sizeof (cm_reply_addr));
4627c478bd9Sstevel@tonic-gate
4637c478bd9Sstevel@tonic-gate /* Initialize the MAD destination address in stored_reply_addr */
4647c478bd9Sstevel@tonic-gate if ((status = ibcm_init_reply_addr(hcap, &cm_reply_addr, chan_args,
4657c478bd9Sstevel@tonic-gate flags, &cm_pkt_lt, primary_slid)) != IBT_SUCCESS) {
4667c478bd9Sstevel@tonic-gate
4677c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
4687c478bd9Sstevel@tonic-gate "ibcm_init_reply_addr failed status %d ", channel, status);
4697c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
4707c478bd9Sstevel@tonic-gate return (status);
4717c478bd9Sstevel@tonic-gate }
4727c478bd9Sstevel@tonic-gate
4737c478bd9Sstevel@tonic-gate
4747c478bd9Sstevel@tonic-gate /* Initialize the pkey for CM MAD communication */
4757c478bd9Sstevel@tonic-gate if (cm_reply_addr.rcvd_addr.ia_p_key == 0)
4767c478bd9Sstevel@tonic-gate cm_reply_addr.rcvd_addr.ia_p_key = prim_pkey;
4777c478bd9Sstevel@tonic-gate
4787c478bd9Sstevel@tonic-gate #ifdef DEBUG
4797c478bd9Sstevel@tonic-gate ibcm_print_reply_addr(channel, &cm_reply_addr);
4807c478bd9Sstevel@tonic-gate #endif
4817c478bd9Sstevel@tonic-gate
4827c478bd9Sstevel@tonic-gate /* Retrieve an ibmf qp for sending CM MADs */
4837c478bd9Sstevel@tonic-gate if ((cm_qp_entry = ibcm_find_qp(hcap, port_no,
4847c478bd9Sstevel@tonic-gate cm_reply_addr.rcvd_addr.ia_p_key)) == NULL) {
4857c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p "
4867c478bd9Sstevel@tonic-gate "unable to allocate ibmf qp for CM MADs", channel);
4877c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
4887c478bd9Sstevel@tonic-gate return (IBT_INSUFF_RESOURCE);
4897c478bd9Sstevel@tonic-gate }
4907c478bd9Sstevel@tonic-gate
4917c478bd9Sstevel@tonic-gate
4927c478bd9Sstevel@tonic-gate if (ibcm_alloc_comid(hcap, &local_comid) != IBCM_SUCCESS) {
4937c478bd9Sstevel@tonic-gate ibcm_release_qp(cm_qp_entry);
4947c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
4957c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan 0x%p"
4967c478bd9Sstevel@tonic-gate " Unable to allocate comid", channel);
4977c478bd9Sstevel@tonic-gate return (IBT_INSUFF_KERNEL_RESOURCE);
4987c478bd9Sstevel@tonic-gate }
4997c478bd9Sstevel@tonic-gate
500934f0bccShiremath /* allocate an IBMF mad buffer (REQ) */
5017c478bd9Sstevel@tonic-gate if ((status = ibcm_alloc_out_msg(ibmf_hdl, &ibmf_msg,
5027c478bd9Sstevel@tonic-gate MAD_METHOD_SEND)) != IBT_SUCCESS) {
5037c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: "
5047c478bd9Sstevel@tonic-gate "chan 0x%p ibcm_alloc_out_msg failed", channel);
5057c478bd9Sstevel@tonic-gate ibcm_release_qp(cm_qp_entry);
5067c478bd9Sstevel@tonic-gate ibcm_free_comid(hcap, local_comid);
5077c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
5087c478bd9Sstevel@tonic-gate return (status);
5097c478bd9Sstevel@tonic-gate }
5107c478bd9Sstevel@tonic-gate
511934f0bccShiremath /* allocate an IBMF mad buffer (DREQ) */
512934f0bccShiremath if ((status = ibcm_alloc_out_msg(ibmf_hdl, &ibmf_msg_dreq,
513934f0bccShiremath MAD_METHOD_SEND)) != IBT_SUCCESS) {
514934f0bccShiremath IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: "
515934f0bccShiremath "chan 0x%p ibcm_alloc_out_msg failed", channel);
516934f0bccShiremath (void) ibcm_free_out_msg(ibmf_hdl, &ibmf_msg);
517934f0bccShiremath ibcm_release_qp(cm_qp_entry);
518934f0bccShiremath ibcm_free_comid(hcap, local_comid);
519934f0bccShiremath ibcm_dec_hca_acc_cnt(hcap);
520934f0bccShiremath return (status);
521934f0bccShiremath }
522934f0bccShiremath
5237c478bd9Sstevel@tonic-gate /* Init to Init, if QP's port does not match with path information */
5247c478bd9Sstevel@tonic-gate if (qp_query_attr.qp_info.qp_transport.rc.rc_path.cep_hca_port_num !=
5257c478bd9Sstevel@tonic-gate IBCM_PRIM_CEP_PATH(chan_args).cep_hca_port_num) {
5267c478bd9Sstevel@tonic-gate
5277c478bd9Sstevel@tonic-gate ibt_qp_info_t qp_info;
5287c478bd9Sstevel@tonic-gate ibt_cep_modify_flags_t cep_flags;
5297c478bd9Sstevel@tonic-gate
5307c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: "
5317c478bd9Sstevel@tonic-gate "chan 0x%p chan port %d", channel,
5327c478bd9Sstevel@tonic-gate qp_query_attr.qp_info.qp_transport.rc.rc_path.\
5337c478bd9Sstevel@tonic-gate cep_hca_port_num);
5347c478bd9Sstevel@tonic-gate
5357c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: "
5367c478bd9Sstevel@tonic-gate "chan 0x%p path port %d", channel, port_no);
5377c478bd9Sstevel@tonic-gate
5387c478bd9Sstevel@tonic-gate bzero(&qp_info, sizeof (qp_info));
5397c478bd9Sstevel@tonic-gate /* For now, set it to RC type */
5407c478bd9Sstevel@tonic-gate
5417c478bd9Sstevel@tonic-gate qp_info.qp_trans = IBT_RC_SRV;
5427c478bd9Sstevel@tonic-gate qp_info.qp_state = IBT_STATE_INIT;
5437c478bd9Sstevel@tonic-gate qp_info.qp_transport.rc.rc_path.cep_hca_port_num = port_no;
5447c478bd9Sstevel@tonic-gate
5457c478bd9Sstevel@tonic-gate cep_flags = IBT_CEP_SET_STATE | IBT_CEP_SET_PORT;
5467c478bd9Sstevel@tonic-gate
5477c478bd9Sstevel@tonic-gate status = ibt_modify_qp(channel, cep_flags, &qp_info, NULL);
5487c478bd9Sstevel@tonic-gate
5497c478bd9Sstevel@tonic-gate if (status != IBT_SUCCESS) {
5507c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: "
5517c478bd9Sstevel@tonic-gate "chan 0x%p ibt_modify_qp() = %d", channel, status);
5527c478bd9Sstevel@tonic-gate ibcm_release_qp(cm_qp_entry);
5537c478bd9Sstevel@tonic-gate ibcm_free_comid(hcap, local_comid);
5547c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
5557c478bd9Sstevel@tonic-gate (void) ibcm_free_out_msg(ibmf_hdl, &ibmf_msg);
556934f0bccShiremath (void) ibcm_free_out_msg(ibmf_hdl, &ibmf_msg_dreq);
5577c478bd9Sstevel@tonic-gate return (status);
5587c478bd9Sstevel@tonic-gate } else
5597c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: "
5607c478bd9Sstevel@tonic-gate "chan 0x%p ibt_modify_qp() = %d", channel, status);
5617c478bd9Sstevel@tonic-gate }
5627c478bd9Sstevel@tonic-gate
5637c478bd9Sstevel@tonic-gate /* allocate ibcm_state_data_t before grabbing the WRITER lock */
5647c478bd9Sstevel@tonic-gate statep = kmem_zalloc(sizeof (ibcm_state_data_t), KM_SLEEP);
5657c478bd9Sstevel@tonic-gate rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
5667c478bd9Sstevel@tonic-gate lkup_status = ibcm_lookup_msg(IBCM_OUTGOING_REQ, local_comid, 0, 0,
5677c478bd9Sstevel@tonic-gate hcap, &statep);
5687c478bd9Sstevel@tonic-gate rw_exit(&hcap->hca_state_rwlock);
5697c478bd9Sstevel@tonic-gate
5707c478bd9Sstevel@tonic-gate /* CM should be seeing this for the first time */
5717c478bd9Sstevel@tonic-gate ASSERT(lkup_status == IBCM_LOOKUP_NEW);
5727c478bd9Sstevel@tonic-gate
5737c478bd9Sstevel@tonic-gate /* Increment the hca's resource count */
5747c478bd9Sstevel@tonic-gate ibcm_inc_hca_res_cnt(hcap);
5757c478bd9Sstevel@tonic-gate
5767c478bd9Sstevel@tonic-gate /* Once a resource created on hca, no need to hold the acc cnt */
5777c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
5787c478bd9Sstevel@tonic-gate
5797c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
5807c478bd9Sstevel@tonic-gate
5817c478bd9Sstevel@tonic-gate statep->timerid = 0;
5827c478bd9Sstevel@tonic-gate statep->local_hca_guid = hca_guid;
5837c478bd9Sstevel@tonic-gate statep->local_qpn = local_qpn;
5847c478bd9Sstevel@tonic-gate statep->stored_reply_addr.cm_qp_entry = cm_qp_entry;
5857c478bd9Sstevel@tonic-gate statep->prim_port = IBCM_PRIM_CEP_PATH(chan_args).cep_hca_port_num;
5867c478bd9Sstevel@tonic-gate statep->alt_port = IBCM_ALT_CEP_PATH(chan_args).cep_hca_port_num;
5877c478bd9Sstevel@tonic-gate
5887c478bd9Sstevel@tonic-gate
5897c478bd9Sstevel@tonic-gate /* Save "statep" as channel's CM private data. */
5907c478bd9Sstevel@tonic-gate statep->channel = channel;
5917c478bd9Sstevel@tonic-gate IBCM_SET_CHAN_PRIVATE(statep->channel, statep);
5927c478bd9Sstevel@tonic-gate
5937c478bd9Sstevel@tonic-gate statep->stored_msg = ibmf_msg;
594934f0bccShiremath statep->dreq_msg = ibmf_msg_dreq;
5957c478bd9Sstevel@tonic-gate
5967c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*req_msgp))
5977c478bd9Sstevel@tonic-gate
5987c478bd9Sstevel@tonic-gate /* Start filling in the REQ MAD */
5997c478bd9Sstevel@tonic-gate req_msgp = (ibcm_req_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
6007c478bd9Sstevel@tonic-gate req_msgp->req_local_comm_id = h2b32(local_comid);
6017c478bd9Sstevel@tonic-gate req_msgp->req_svc_id = h2b64(chan_args->oc_path->pi_sid);
6027c478bd9Sstevel@tonic-gate req_msgp->req_local_ca_guid = h2b64(hca_guid);
6037c478bd9Sstevel@tonic-gate req_msgp->req_local_qkey = h2b32(local_qkey); /* for EEC/RD */
6047c478bd9Sstevel@tonic-gate
6057c478bd9Sstevel@tonic-gate /* Bytes 32-35 are req_local_qpn and req_off_resp_resources */
6067c478bd9Sstevel@tonic-gate req_msgp->req_local_qpn_plus = h2b32(local_qpn << 8 | rdma_in);
6077c478bd9Sstevel@tonic-gate
6087c478bd9Sstevel@tonic-gate /* Bytes 36-39 are req_local_eec_no and req_off_initiator_depth */
6097c478bd9Sstevel@tonic-gate req_msgp->req_local_eec_no_plus = h2b32(local_eecn << 8 | rdma_out);
6107c478bd9Sstevel@tonic-gate
6117c478bd9Sstevel@tonic-gate if (flags & IBT_OCHAN_REMOTE_CM_TM)
6127c478bd9Sstevel@tonic-gate remote_cm_resp_time = chan_args->oc_remote_cm_time;
6137c478bd9Sstevel@tonic-gate else
6147c478bd9Sstevel@tonic-gate remote_cm_resp_time = ibcm_remote_response_time;
6157c478bd9Sstevel@tonic-gate
6167c478bd9Sstevel@tonic-gate /*
6177c478bd9Sstevel@tonic-gate * Bytes 40-43 - remote_eecn, remote_cm_resp_time, tran_type,
6187c478bd9Sstevel@tonic-gate * IBT_CM_FLOW_CONTROL is always set by default.
6197c478bd9Sstevel@tonic-gate */
6207c478bd9Sstevel@tonic-gate req_msgp->req_remote_eecn_plus = h2b32(
6217c478bd9Sstevel@tonic-gate remote_eecn << 8 | (ibt_usec2ib(remote_cm_resp_time) & 0x1f) << 3 |
6227c478bd9Sstevel@tonic-gate IBT_RC_SRV << 1 | IBT_CM_FLOW_CONTROL);
6237c478bd9Sstevel@tonic-gate
6247c478bd9Sstevel@tonic-gate if (flags & IBT_OCHAN_LOCAL_CM_TM)
6257c478bd9Sstevel@tonic-gate local_cm_proc_time = chan_args->oc_local_cm_time;
6267c478bd9Sstevel@tonic-gate else
6277c478bd9Sstevel@tonic-gate local_cm_proc_time = ibcm_local_processing_time;
6287c478bd9Sstevel@tonic-gate
6297c478bd9Sstevel@tonic-gate local_cm_resp_time = ibt_usec2ib(local_cm_proc_time +
6307c478bd9Sstevel@tonic-gate 2 * ibt_ib2usec(chan_args->oc_path->pi_prim_pkt_lt) +
6317c478bd9Sstevel@tonic-gate ibcm_sw_delay);
6327c478bd9Sstevel@tonic-gate
6337c478bd9Sstevel@tonic-gate /* save retry count */
6347c478bd9Sstevel@tonic-gate statep->cep_retry_cnt = chan_args->oc_path_retry_cnt;
6357c478bd9Sstevel@tonic-gate
6367c478bd9Sstevel@tonic-gate if (flags & IBT_OCHAN_STARTING_PSN)
6377c478bd9Sstevel@tonic-gate starting_psn = chan_args->oc_starting_psn;
6387c478bd9Sstevel@tonic-gate
6397c478bd9Sstevel@tonic-gate if (local_cm_resp_time > 0x1f)
6407c478bd9Sstevel@tonic-gate local_cm_resp_time = 0x1f;
6417c478bd9Sstevel@tonic-gate
6427c478bd9Sstevel@tonic-gate /* Bytes 44-47 are req_starting_psn, local_cm_resp_time and retry_cnt */
6437c478bd9Sstevel@tonic-gate req_msgp->req_starting_psn_plus = h2b32(starting_psn << 8 |
6447c478bd9Sstevel@tonic-gate local_cm_resp_time << 3 | statep->cep_retry_cnt);
6457c478bd9Sstevel@tonic-gate
6467c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
6477c478bd9Sstevel@tonic-gate "Prim Pkt lt (IB time) 0x%x", channel,
6487c478bd9Sstevel@tonic-gate chan_args->oc_path->pi_prim_pkt_lt);
6497c478bd9Sstevel@tonic-gate
6507c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
6517c478bd9Sstevel@tonic-gate "local_cm_proc_time(usec) %d ", channel, local_cm_proc_time);
6527c478bd9Sstevel@tonic-gate
6537c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
6547c478bd9Sstevel@tonic-gate "local_cm_resp_time(ib_time) %d", channel, local_cm_resp_time);
6557c478bd9Sstevel@tonic-gate
6567c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
6577c478bd9Sstevel@tonic-gate "remote_cm_resp_time (usec) %d", channel, remote_cm_resp_time);
6587c478bd9Sstevel@tonic-gate
6597c478bd9Sstevel@tonic-gate statep->starting_psn = starting_psn;
6607c478bd9Sstevel@tonic-gate
6617c478bd9Sstevel@tonic-gate /* Pkey - bytes 48-49 */
6627c478bd9Sstevel@tonic-gate req_msgp->req_part_key = h2b16(prim_pkey);
6637c478bd9Sstevel@tonic-gate
6647c478bd9Sstevel@tonic-gate if (flags & IBT_OCHAN_CM_RETRY)
6657c478bd9Sstevel@tonic-gate cm_retries = chan_args->oc_cm_retry_cnt;
6667c478bd9Sstevel@tonic-gate else
6677c478bd9Sstevel@tonic-gate cm_retries = ibcm_max_retries;
6687c478bd9Sstevel@tonic-gate
6697c478bd9Sstevel@tonic-gate statep->max_cm_retries = statep->remaining_retry_cnt = cm_retries;
6707c478bd9Sstevel@tonic-gate req_msgp->req_max_cm_retries_plus = statep->max_cm_retries << 4;
6717c478bd9Sstevel@tonic-gate
6727c478bd9Sstevel@tonic-gate /*
6737c478bd9Sstevel@tonic-gate * Check whether SRQ is associated with this Channel, if yes, then
6747c478bd9Sstevel@tonic-gate * set the SRQ Exists bit in the REQ.
6757c478bd9Sstevel@tonic-gate */
6767c478bd9Sstevel@tonic-gate if (qp_query_attr.qp_srq != NULL) {
6777c478bd9Sstevel@tonic-gate req_msgp->req_max_cm_retries_plus |= (1 << 3);
6787c478bd9Sstevel@tonic-gate }
6797c478bd9Sstevel@tonic-gate
680934f0bccShiremath /*
681934f0bccShiremath * By default on Tavor, we override the PathMTU to 1K.
682934f0bccShiremath * To turn this off, set ibcm_override_path_mtu = 0.
683934f0bccShiremath */
684934f0bccShiremath if (ibcm_override_path_mtu && IBCM_IS_HCA_TAVOR(hcap) &&
685934f0bccShiremath (chan_args->oc_path->pi_path_mtu > IB_MTU_1K)) {
686934f0bccShiremath req_msgp->req_mtu_plus = IB_MTU_1K << 4 |
687934f0bccShiremath chan_args->oc_path_rnr_retry_cnt;
688934f0bccShiremath IBTF_DPRINTF_L3(cmlog, "ibt_open_rc_channel: chan 0x%p PathMTU"
689f07a6d2aSShantkumar Hiremath " overridden to IB_MTU_1K(%d) from %d", channel, IB_MTU_1K,
690934f0bccShiremath chan_args->oc_path->pi_path_mtu);
691934f0bccShiremath } else
6927c478bd9Sstevel@tonic-gate req_msgp->req_mtu_plus = chan_args->oc_path->pi_path_mtu << 4 |
6937c478bd9Sstevel@tonic-gate chan_args->oc_path_rnr_retry_cnt;
6947c478bd9Sstevel@tonic-gate
6957c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p CM retry cnt %d"
6967c478bd9Sstevel@tonic-gate " staring PSN %x", channel, cm_retries, starting_psn);
6977c478bd9Sstevel@tonic-gate
6987c478bd9Sstevel@tonic-gate
6997c478bd9Sstevel@tonic-gate #ifdef NO_EEC_SUPPORT_YET
7007c478bd9Sstevel@tonic-gate if (flags & IBT_OCHAN_RDC_EXISTS)
7017c478bd9Sstevel@tonic-gate req_msgp->req_mtu_plus |= 8;
7027c478bd9Sstevel@tonic-gate #endif
7037c478bd9Sstevel@tonic-gate
7047c478bd9Sstevel@tonic-gate /* Initialize the "primary" port stuff next - bytes 52-95 */
7057c478bd9Sstevel@tonic-gate req_msgp->req_primary_l_port_lid = h2b16(primary_slid);
7067c478bd9Sstevel@tonic-gate req_msgp->req_primary_r_port_lid =
7077c478bd9Sstevel@tonic-gate h2b16(IBCM_PRIM_ADDS_VECT(chan_args).av_dlid);
7087c478bd9Sstevel@tonic-gate req_msgp->req_primary_l_port_gid.gid_prefix =
7097c478bd9Sstevel@tonic-gate h2b64(IBCM_PRIM_ADDS_VECT(chan_args).av_sgid.gid_prefix);
7107c478bd9Sstevel@tonic-gate req_msgp->req_primary_l_port_gid.gid_guid =
7117c478bd9Sstevel@tonic-gate h2b64(IBCM_PRIM_ADDS_VECT(chan_args).av_sgid.gid_guid);
7127c478bd9Sstevel@tonic-gate req_msgp->req_primary_r_port_gid.gid_prefix =
7137c478bd9Sstevel@tonic-gate h2b64(IBCM_PRIM_ADDS_VECT(chan_args).av_dgid.gid_prefix);
7147c478bd9Sstevel@tonic-gate req_msgp->req_primary_r_port_gid.gid_guid =
7157c478bd9Sstevel@tonic-gate h2b64(IBCM_PRIM_ADDS_VECT(chan_args).av_dgid.gid_guid);
7167c478bd9Sstevel@tonic-gate primary_grh = IBCM_PRIM_ADDS_VECT(chan_args).av_send_grh;
7177c478bd9Sstevel@tonic-gate
7189d3d2ed0Shiremath statep->remote_hca_guid = /* not correct, but helpful for debugging */
7199d3d2ed0Shiremath IBCM_PRIM_ADDS_VECT(chan_args).av_dgid.gid_guid;
7209d3d2ed0Shiremath
7217c478bd9Sstevel@tonic-gate /* Bytes 88-91 - primary_flowlbl, and primary_srate */
7227c478bd9Sstevel@tonic-gate req_msgp->req_primary_flow_label_plus =
7237c478bd9Sstevel@tonic-gate h2b32(((primary_grh == B_TRUE) ?
7247c478bd9Sstevel@tonic-gate (IBCM_PRIM_ADDS_VECT(chan_args).av_flow << 12) : 0) |
7257c478bd9Sstevel@tonic-gate IBCM_PRIM_ADDS_VECT(chan_args).av_srate);
7267c478bd9Sstevel@tonic-gate req_msgp->req_primary_traffic_class = (primary_grh == B_TRUE) ?
7277c478bd9Sstevel@tonic-gate IBCM_PRIM_ADDS_VECT(chan_args).av_tclass : 0;
7287c478bd9Sstevel@tonic-gate req_msgp->req_primary_hop_limit = (primary_grh == B_TRUE) ?
7296db9c6ddShiremath IBCM_PRIM_ADDS_VECT(chan_args).av_hop : 1;
7307c478bd9Sstevel@tonic-gate req_msgp->req_primary_sl_plus =
7317c478bd9Sstevel@tonic-gate IBCM_PRIM_ADDS_VECT(chan_args).av_srvl << 4 |
7327c478bd9Sstevel@tonic-gate ((primary_grh == B_TRUE) ? 0 : 8);
7337c478bd9Sstevel@tonic-gate
7347c478bd9Sstevel@tonic-gate req_msgp->req_primary_localtime_plus =
7357c478bd9Sstevel@tonic-gate ibt_usec2ib((2 * ibt_ib2usec(chan_args->oc_path->pi_prim_pkt_lt)) +
7367c478bd9Sstevel@tonic-gate ibt_ib2usec(hcap->hca_ack_delay)) << 3;
7377c478bd9Sstevel@tonic-gate
7387c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_open_rc_channel: chan %p statep %p",
7397c478bd9Sstevel@tonic-gate channel, statep);
7407c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
7417c478bd9Sstevel@tonic-gate "active hca_ack_delay (usec) %d", channel,
7427c478bd9Sstevel@tonic-gate req_msgp->req_primary_localtime_plus);
7437c478bd9Sstevel@tonic-gate
7447c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
7457c478bd9Sstevel@tonic-gate "Sent primary cep timeout (IB Time) %d", channel,
7467c478bd9Sstevel@tonic-gate hcap->hca_ack_delay);
7477c478bd9Sstevel@tonic-gate
7487c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p prim_dlid %x ",
7497c478bd9Sstevel@tonic-gate channel, IBCM_PRIM_ADDS_VECT(chan_args).av_dlid);
7507c478bd9Sstevel@tonic-gate
7517c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
7529d3d2ed0Shiremath "prim GID %llX:%llX", channel,
7539d3d2ed0Shiremath IBCM_PRIM_ADDS_VECT(chan_args).av_dgid.gid_prefix,
7547c478bd9Sstevel@tonic-gate IBCM_PRIM_ADDS_VECT(chan_args).av_dgid.gid_guid);
7557c478bd9Sstevel@tonic-gate
7567c478bd9Sstevel@tonic-gate /* Initialize the "alternate" port stuff - optional */
7577c478bd9Sstevel@tonic-gate if (chan_args->oc_path->pi_alt_cep_path.cep_hca_port_num != 0) {
7587c478bd9Sstevel@tonic-gate ib_gid_t tmp_gid;
7597c478bd9Sstevel@tonic-gate
7607c478bd9Sstevel@tonic-gate req_msgp->req_alt_l_port_lid = h2b16(alternate_slid);
7617c478bd9Sstevel@tonic-gate req_msgp->req_alt_r_port_lid =
7627c478bd9Sstevel@tonic-gate h2b16(IBCM_ALT_ADDS_VECT(chan_args).av_dlid);
7637c478bd9Sstevel@tonic-gate /*
7647c478bd9Sstevel@tonic-gate * doing all this as req_alt_r/l_port_gid is at offset
7657c478bd9Sstevel@tonic-gate * 100, 116 which is not divisible by 8
7667c478bd9Sstevel@tonic-gate */
7677c478bd9Sstevel@tonic-gate
7687c478bd9Sstevel@tonic-gate tmp_gid.gid_prefix =
7697c478bd9Sstevel@tonic-gate h2b64(IBCM_ALT_ADDS_VECT(chan_args).av_dgid.gid_prefix);
7707c478bd9Sstevel@tonic-gate tmp_gid.gid_guid =
7717c478bd9Sstevel@tonic-gate h2b64(IBCM_ALT_ADDS_VECT(chan_args).av_dgid.gid_guid);
7727c478bd9Sstevel@tonic-gate bcopy(&tmp_gid, &req_msgp->req_alt_r_port_gid[0],
7737c478bd9Sstevel@tonic-gate sizeof (ib_gid_t));
7747c478bd9Sstevel@tonic-gate tmp_gid.gid_prefix =
7757c478bd9Sstevel@tonic-gate h2b64(IBCM_ALT_ADDS_VECT(chan_args).av_sgid.gid_prefix);
7767c478bd9Sstevel@tonic-gate tmp_gid.gid_guid =
7777c478bd9Sstevel@tonic-gate h2b64(IBCM_ALT_ADDS_VECT(chan_args).av_sgid.gid_guid);
7787c478bd9Sstevel@tonic-gate
7797c478bd9Sstevel@tonic-gate bcopy(&tmp_gid, &req_msgp->req_alt_l_port_gid[0],
7807c478bd9Sstevel@tonic-gate sizeof (ib_gid_t));
7817c478bd9Sstevel@tonic-gate alternate_grh = IBCM_ALT_ADDS_VECT(chan_args).av_send_grh;
7827c478bd9Sstevel@tonic-gate
7837c478bd9Sstevel@tonic-gate /* Bytes 132-135 - alternate_flow_label, and alternate srate */
7847c478bd9Sstevel@tonic-gate req_msgp->req_alt_flow_label_plus = h2b32(
7857c478bd9Sstevel@tonic-gate (((alternate_grh == B_TRUE) ?
7867c478bd9Sstevel@tonic-gate (IBCM_ALT_ADDS_VECT(chan_args).av_flow << 12) : 0) |
7877c478bd9Sstevel@tonic-gate IBCM_ALT_ADDS_VECT(chan_args).av_srate));
7887c478bd9Sstevel@tonic-gate req_msgp->req_alt_traffic_class = (alternate_grh == B_TRUE) ?
7897c478bd9Sstevel@tonic-gate IBCM_ALT_ADDS_VECT(chan_args).av_tclass : 0;
7907c478bd9Sstevel@tonic-gate req_msgp->req_alt_hop_limit = (alternate_grh == B_TRUE) ?
7916db9c6ddShiremath IBCM_ALT_ADDS_VECT(chan_args).av_hop : 1;
7927c478bd9Sstevel@tonic-gate req_msgp->req_alt_sl_plus =
7937c478bd9Sstevel@tonic-gate IBCM_ALT_ADDS_VECT(chan_args).av_srvl << 4 |
7947c478bd9Sstevel@tonic-gate ((alternate_grh == B_TRUE) ? 0 : 8);
7957c478bd9Sstevel@tonic-gate req_msgp->req_alt_localtime_plus = ibt_usec2ib((2 *
7967c478bd9Sstevel@tonic-gate ibt_ib2usec(chan_args->oc_path->pi_alt_pkt_lt)) +
7977c478bd9Sstevel@tonic-gate ibt_ib2usec(hcap->hca_ack_delay)) << 3;
7987c478bd9Sstevel@tonic-gate
7997c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
8007c478bd9Sstevel@tonic-gate "alt_dlid %x ", channel,
8017c478bd9Sstevel@tonic-gate IBCM_ALT_ADDS_VECT(chan_args).av_dlid);
8027c478bd9Sstevel@tonic-gate
8037c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
8049d3d2ed0Shiremath "alt GID %llX:%llX", channel,
8059d3d2ed0Shiremath IBCM_ALT_ADDS_VECT(chan_args).av_dgid.gid_prefix,
8067c478bd9Sstevel@tonic-gate IBCM_ALT_ADDS_VECT(chan_args).av_dgid.gid_guid);
8077c478bd9Sstevel@tonic-gate }
8087c478bd9Sstevel@tonic-gate
8097c478bd9Sstevel@tonic-gate len = min(chan_args->oc_priv_data_len, IBT_REQ_PRIV_DATA_SZ);
8107c478bd9Sstevel@tonic-gate if ((len > 0) && chan_args->oc_priv_data)
8117c478bd9Sstevel@tonic-gate bcopy(chan_args->oc_priv_data, req_msgp->req_private_data, len);
8127c478bd9Sstevel@tonic-gate
8137c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*req_msgp))
8147c478bd9Sstevel@tonic-gate
8157c478bd9Sstevel@tonic-gate /* return_data is filled up in the state machine code */
8167c478bd9Sstevel@tonic-gate if (ret_args != NULL) {
8177c478bd9Sstevel@tonic-gate statep->open_return_data = ret_args;
8187c478bd9Sstevel@tonic-gate }
8197c478bd9Sstevel@tonic-gate
8207c478bd9Sstevel@tonic-gate /* initialize some statep fields here */
8217c478bd9Sstevel@tonic-gate statep->mode = IBCM_ACTIVE_MODE;
8227c478bd9Sstevel@tonic-gate statep->hcap = hcap;
8237c478bd9Sstevel@tonic-gate
8247c478bd9Sstevel@tonic-gate statep->cm_handler = chan_args->oc_cm_handler;
8257c478bd9Sstevel@tonic-gate statep->state_cm_private = chan_args->oc_cm_clnt_private;
8267c478bd9Sstevel@tonic-gate
8277c478bd9Sstevel@tonic-gate statep->pkt_life_time =
8287c478bd9Sstevel@tonic-gate ibt_ib2usec(chan_args->oc_path->pi_prim_pkt_lt);
8297c478bd9Sstevel@tonic-gate
8309d3d2ed0Shiremath statep->timer_value = ibt_ib2usec(ibt_usec2ib(
8319d3d2ed0Shiremath 2 * ibt_ib2usec(cm_pkt_lt) + remote_cm_resp_time));
8327c478bd9Sstevel@tonic-gate
8337c478bd9Sstevel@tonic-gate /* Initialize statep->stored_reply_addr */
8347c478bd9Sstevel@tonic-gate statep->stored_reply_addr.ibmf_hdl = ibmf_hdl;
8357c478bd9Sstevel@tonic-gate
8367c478bd9Sstevel@tonic-gate /* Initialize stored reply addr fields */
8377c478bd9Sstevel@tonic-gate statep->stored_reply_addr.grh_hdr = cm_reply_addr.grh_hdr;
8387c478bd9Sstevel@tonic-gate statep->stored_reply_addr.rcvd_addr = cm_reply_addr.rcvd_addr;
8397c478bd9Sstevel@tonic-gate statep->stored_reply_addr.grh_exists = cm_reply_addr.grh_exists;
8407c478bd9Sstevel@tonic-gate statep->stored_reply_addr.port_num = cm_reply_addr.port_num;
8417c478bd9Sstevel@tonic-gate
8427c478bd9Sstevel@tonic-gate /*
8437c478bd9Sstevel@tonic-gate * The IPD on local/active side is calculated by path functions,
8447c478bd9Sstevel@tonic-gate * hence available in the args of ibt_open_rc_channel
8457c478bd9Sstevel@tonic-gate */
8467c478bd9Sstevel@tonic-gate statep->local_srate = IBCM_PRIM_ADDS_VECT(chan_args).av_srate;
8477c478bd9Sstevel@tonic-gate statep->local_alt_srate = IBCM_ALT_ADDS_VECT(chan_args).av_srate;
8487c478bd9Sstevel@tonic-gate
8497c478bd9Sstevel@tonic-gate /* Store the source path bits for primary and alt paths */
8507c478bd9Sstevel@tonic-gate statep->prim_src_path_bits = IBCM_PRIM_ADDS_VECT(chan_args).av_src_path;
8517c478bd9Sstevel@tonic-gate statep->alt_src_path_bits = IBCM_ALT_ADDS_VECT(chan_args).av_src_path;
8527c478bd9Sstevel@tonic-gate
8539d3d2ed0Shiremath statep->open_flow = 1;
8547c478bd9Sstevel@tonic-gate statep->open_done = B_FALSE;
8557c478bd9Sstevel@tonic-gate statep->state = statep->timer_stored_state = IBCM_STATE_REQ_SENT;
8569d3d2ed0Shiremath IBCM_REF_CNT_INCR(statep); /* Decremented before return */
8579d3d2ed0Shiremath IBCM_REF_CNT_INCR(statep); /* Decremented after REQ is posted */
8587c478bd9Sstevel@tonic-gate statep->send_mad_flags |= IBCM_REQ_POST_BUSY;
8597c478bd9Sstevel@tonic-gate
8609c468ea9SPramod Gunjikar /*
8619c468ea9SPramod Gunjikar * Skip moving channel to error state during close, for OFUV clients.
8629c468ea9SPramod Gunjikar * OFUV clients transition the channel to error state by itself.
8639c468ea9SPramod Gunjikar */
8649c468ea9SPramod Gunjikar if (flags & IBT_OCHAN_OFUV)
8659c468ea9SPramod Gunjikar statep->is_this_ofuv_chan = B_TRUE;
8669c468ea9SPramod Gunjikar
8677c478bd9Sstevel@tonic-gate IBCM_OUT_HDRP(statep->stored_msg)->AttributeID =
8687c478bd9Sstevel@tonic-gate h2b16(IBCM_INCOMING_REQ + IBCM_ATTR_BASE_ID);
8697c478bd9Sstevel@tonic-gate
8707c478bd9Sstevel@tonic-gate IBCM_OUT_HDRP(statep->stored_msg)->TransactionID =
8717c478bd9Sstevel@tonic-gate h2b64(ibcm_generate_tranid(IBCM_INCOMING_REQ, statep->local_comid,
8727c478bd9Sstevel@tonic-gate 0));
8737c478bd9Sstevel@tonic-gate
8747c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*statep))
8757c478bd9Sstevel@tonic-gate
8769c468ea9SPramod Gunjikar ibtl_cm_chan_is_opening(channel);
8779c468ea9SPramod Gunjikar
8789d3d2ed0Shiremath ibcm_open_enqueue(statep);
8797c478bd9Sstevel@tonic-gate
8807c478bd9Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
8817c478bd9Sstevel@tonic-gate
8827c478bd9Sstevel@tonic-gate if (mode == IBT_BLOCKING) {
8837c478bd9Sstevel@tonic-gate
8847c478bd9Sstevel@tonic-gate /* wait for REQ/REP/RTU */
8857c478bd9Sstevel@tonic-gate while (statep->open_done != B_TRUE) {
8867c478bd9Sstevel@tonic-gate cv_wait(&statep->block_client_cv, &statep->state_mutex);
8877c478bd9Sstevel@tonic-gate }
8887c478bd9Sstevel@tonic-gate
8897c478bd9Sstevel@tonic-gate /*
8907c478bd9Sstevel@tonic-gate * In the case that open_channel() fails because of a
8917c478bd9Sstevel@tonic-gate * REJ or timeout, change retval to IBT_CM_FAILURE
8927c478bd9Sstevel@tonic-gate */
8932c2d21e9SRichard Lowe if (statep->open_return_data->rc_status != IBT_CM_SUCCESS) {
8947c478bd9Sstevel@tonic-gate status = IBT_CM_FAILURE;
895a23420cfSShantkumar Hiremath ibtl_cm_chan_open_is_aborted(channel);
896a23420cfSShantkumar Hiremath }
8977c478bd9Sstevel@tonic-gate
8987c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_open_rc_channel: chan 0x%p "
8997c478bd9Sstevel@tonic-gate "ret status %d cm status %d", channel, status,
9007c478bd9Sstevel@tonic-gate statep->open_return_data->rc_status);
9017c478bd9Sstevel@tonic-gate }
9027c478bd9Sstevel@tonic-gate
9037c478bd9Sstevel@tonic-gate /* decrement the ref-count before leaving here */
9047c478bd9Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
9057c478bd9Sstevel@tonic-gate
9067c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
9077c478bd9Sstevel@tonic-gate
9087c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_open_rc_channel: chan 0x%p done", channel);
9097c478bd9Sstevel@tonic-gate return (status);
9107c478bd9Sstevel@tonic-gate }
9117c478bd9Sstevel@tonic-gate
9127c478bd9Sstevel@tonic-gate /*
9137c478bd9Sstevel@tonic-gate * ibcm_init_reply_addr:
9147c478bd9Sstevel@tonic-gate *
9157c478bd9Sstevel@tonic-gate * The brief description of functionality below.
9167c478bd9Sstevel@tonic-gate *
9177c478bd9Sstevel@tonic-gate * For IBT_OCHAN_PORT_REDIRECTED (ie., port redirected case):
9187c478bd9Sstevel@tonic-gate * Build CM path from chan_args->oc_cm_cep_path
9197c478bd9Sstevel@tonic-gate * Set CM pkt lt (ie.,life time) to chan_args->oc_cm_pkt_lt
9207c478bd9Sstevel@tonic-gate *
9217c478bd9Sstevel@tonic-gate * For IBT_OCHAN_REDIRECTED (ie., port and CM redirected case):
9227c478bd9Sstevel@tonic-gate * If Redirect LID is specified,
9237c478bd9Sstevel@tonic-gate * If Redirect GID is not specified or specified to be on the same
9247c478bd9Sstevel@tonic-gate * subnet, then
9257c478bd9Sstevel@tonic-gate * Build CM path from chan_args->oc_cm_redirect_info
9267c478bd9Sstevel@tonic-gate * Set CM pkt lt to subnet timeout
9277c478bd9Sstevel@tonic-gate * Else (ie., GID specified, but on a different subnet)
9287c478bd9Sstevel@tonic-gate * Do a path lookup to build CM Path and set CM pkt lt
9297c478bd9Sstevel@tonic-gate *
9307c478bd9Sstevel@tonic-gate */
9317c478bd9Sstevel@tonic-gate static ibt_status_t
ibcm_init_reply_addr(ibcm_hca_info_t * hcap,ibcm_mad_addr_t * reply_addr,ibt_chan_open_args_t * chan_args,ibt_chan_open_flags_t flags,ib_time_t * cm_pkt_lt,ib_lid_t prim_slid)9327c478bd9Sstevel@tonic-gate ibcm_init_reply_addr(ibcm_hca_info_t *hcap, ibcm_mad_addr_t *reply_addr,
9337c478bd9Sstevel@tonic-gate ibt_chan_open_args_t *chan_args, ibt_chan_open_flags_t flags,
9347c478bd9Sstevel@tonic-gate ib_time_t *cm_pkt_lt, ib_lid_t prim_slid)
9357c478bd9Sstevel@tonic-gate {
9367c478bd9Sstevel@tonic-gate ibt_adds_vect_t *cm_adds;
9377c478bd9Sstevel@tonic-gate ibt_path_info_t path;
9387c478bd9Sstevel@tonic-gate boolean_t cm_grh;
9397c478bd9Sstevel@tonic-gate ibt_status_t status;
9407c478bd9Sstevel@tonic-gate
9417c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_init_reply_addr:");
9427c478bd9Sstevel@tonic-gate
9437c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*reply_addr))
9447c478bd9Sstevel@tonic-gate
9457c478bd9Sstevel@tonic-gate /*
9467c478bd9Sstevel@tonic-gate * sending side CM lid/gid/port num are not based on any redirect
9477c478bd9Sstevel@tonic-gate * params. These values are set to primary RC path lid/gid/port num.
9487c478bd9Sstevel@tonic-gate * In the future, these values can be set based on framework policy
9497c478bd9Sstevel@tonic-gate * decisions ensuring reachability.
9507c478bd9Sstevel@tonic-gate */
9517c478bd9Sstevel@tonic-gate reply_addr->grh_hdr.ig_sender_gid =
9527c478bd9Sstevel@tonic-gate IBCM_PRIM_ADDS_VECT(chan_args).av_sgid;
9537c478bd9Sstevel@tonic-gate reply_addr->rcvd_addr.ia_local_lid = prim_slid;
9547c478bd9Sstevel@tonic-gate reply_addr->port_num = IBCM_PRIM_CEP_PATH(chan_args).cep_hca_port_num;
9557c478bd9Sstevel@tonic-gate
9567c478bd9Sstevel@tonic-gate if (flags & IBT_OCHAN_PORT_REDIRECTED) {
9577c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_init_rely_addr: "
9587c478bd9Sstevel@tonic-gate "IBT_OCHAN_PORT_REDIRECTED specified");
9597c478bd9Sstevel@tonic-gate
9607c478bd9Sstevel@tonic-gate status = ibt_index2pkey_byguid(hcap->hca_guid,
9617c478bd9Sstevel@tonic-gate chan_args->oc_cm_cep_path->cep_hca_port_num,
9627c478bd9Sstevel@tonic-gate chan_args->oc_cm_cep_path->cep_pkey_ix,
9637c478bd9Sstevel@tonic-gate &reply_addr->rcvd_addr.ia_p_key);
9647c478bd9Sstevel@tonic-gate
9657c478bd9Sstevel@tonic-gate if (status != IBT_SUCCESS) {
9667c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_init_rely_addr: Invalid "
9677c478bd9Sstevel@tonic-gate "CM PKeyIx %x port_num %x",
9687c478bd9Sstevel@tonic-gate chan_args->oc_cm_cep_path->cep_pkey_ix,
9697c478bd9Sstevel@tonic-gate chan_args->oc_cm_cep_path->cep_hca_port_num);
9707c478bd9Sstevel@tonic-gate return (status);
9717c478bd9Sstevel@tonic-gate }
9727c478bd9Sstevel@tonic-gate
9737c478bd9Sstevel@tonic-gate cm_adds = &(chan_args->oc_cm_cep_path->cep_adds_vect);
9747c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_init_rely_addr: dlid = %x",
9757c478bd9Sstevel@tonic-gate cm_adds->av_dlid);
9767c478bd9Sstevel@tonic-gate
9777c478bd9Sstevel@tonic-gate reply_addr->rcvd_addr.ia_q_key = IB_GSI_QKEY;
9787c478bd9Sstevel@tonic-gate reply_addr->rcvd_addr.ia_remote_qno = 1;
9797c478bd9Sstevel@tonic-gate *cm_pkt_lt = chan_args->oc_cm_pkt_lt;
9807c478bd9Sstevel@tonic-gate
9817c478bd9Sstevel@tonic-gate } else if (flags & IBT_OCHAN_REDIRECTED) {
9827c478bd9Sstevel@tonic-gate ibt_redirect_info_t *redirect_info;
9837c478bd9Sstevel@tonic-gate ibt_hca_portinfo_t *port_infop;
9847c478bd9Sstevel@tonic-gate uint_t psize, nports;
9857c478bd9Sstevel@tonic-gate
9867c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_init_rely_addr: "
9877c478bd9Sstevel@tonic-gate "IBT_OCHAN_REDIRECTED specified");
9887c478bd9Sstevel@tonic-gate
9897c478bd9Sstevel@tonic-gate redirect_info = chan_args->oc_cm_redirect_info;
9907c478bd9Sstevel@tonic-gate
9919d3d2ed0Shiremath if ((redirect_info->rdi_gid.gid_prefix == 0) ||
9929d3d2ed0Shiremath (redirect_info->rdi_gid.gid_guid == 0)) {
9939d3d2ed0Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_init_reply_addr: "
9949d3d2ed0Shiremath "ERROR: Re-direct GID value NOT Provided.");
9959d3d2ed0Shiremath return (IBT_INVALID_PARAM);
9969d3d2ed0Shiremath }
9979d3d2ed0Shiremath
9987c478bd9Sstevel@tonic-gate /* As per spec definition 1.1, it's always IB_GSI_QKEY */
9997c478bd9Sstevel@tonic-gate reply_addr->rcvd_addr.ia_q_key = redirect_info->rdi_qkey;
10007c478bd9Sstevel@tonic-gate reply_addr->rcvd_addr.ia_remote_qno = redirect_info->rdi_qpn;
10017c478bd9Sstevel@tonic-gate reply_addr->rcvd_addr.ia_p_key = redirect_info->rdi_pkey;
10027c478bd9Sstevel@tonic-gate
10037c478bd9Sstevel@tonic-gate /*
10049d3d2ed0Shiremath * if LID is non-zero in classportinfo then use classportinfo
10059d3d2ed0Shiremath * fields to form CM MAD destination address.
10067c478bd9Sstevel@tonic-gate */
10079d3d2ed0Shiremath if (redirect_info->rdi_dlid != 0) {
10087c478bd9Sstevel@tonic-gate status = ibtl_cm_query_hca_ports_byguid(hcap->hca_guid,
10097c478bd9Sstevel@tonic-gate reply_addr->port_num, &port_infop, &nports, &psize);
10107c478bd9Sstevel@tonic-gate if ((status != IBT_SUCCESS) || (nports == 0)) {
10117c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_init_reply_addr: "
10127c478bd9Sstevel@tonic-gate "Query Ports Failed: %d", status);
10137c478bd9Sstevel@tonic-gate return (status);
10147c478bd9Sstevel@tonic-gate } else if (port_infop->p_subnet_timeout >
1015bbd67193Shiremath ibcm_max_ib_pkt_lt) {
10167c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_init_reply_addr: "
10177c478bd9Sstevel@tonic-gate "large subnet timeout %x port_no %x",
10187c478bd9Sstevel@tonic-gate port_infop->p_subnet_timeout,
10197c478bd9Sstevel@tonic-gate reply_addr->port_num);
10207c478bd9Sstevel@tonic-gate ibt_free_portinfo(port_infop, psize);
10217c478bd9Sstevel@tonic-gate return (IBT_PATH_PKT_LT_TOO_HIGH);
10227c478bd9Sstevel@tonic-gate } else {
10237c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_init_reply_addr: "
10247c478bd9Sstevel@tonic-gate "subnet timeout %x port_no %x",
10257c478bd9Sstevel@tonic-gate port_infop->p_subnet_timeout,
10267c478bd9Sstevel@tonic-gate reply_addr->port_num);
10277c478bd9Sstevel@tonic-gate
10287c478bd9Sstevel@tonic-gate *cm_pkt_lt =
10297c478bd9Sstevel@tonic-gate ibt_ib2usec(min(ibcm_max_ib_mad_pkt_lt,
10307c478bd9Sstevel@tonic-gate port_infop->p_subnet_timeout));
10317c478bd9Sstevel@tonic-gate
10327c478bd9Sstevel@tonic-gate ibt_free_portinfo(port_infop, psize);
10337c478bd9Sstevel@tonic-gate }
10347c478bd9Sstevel@tonic-gate
10357c478bd9Sstevel@tonic-gate reply_addr->rcvd_addr.ia_remote_lid =
10367c478bd9Sstevel@tonic-gate redirect_info->rdi_dlid;
10377c478bd9Sstevel@tonic-gate reply_addr->rcvd_addr.ia_service_level =
10387c478bd9Sstevel@tonic-gate redirect_info->rdi_sl;
10397c478bd9Sstevel@tonic-gate reply_addr->grh_exists = B_TRUE;
10407c478bd9Sstevel@tonic-gate reply_addr->grh_hdr.ig_recver_gid =
10417c478bd9Sstevel@tonic-gate redirect_info->rdi_gid;
10427c478bd9Sstevel@tonic-gate reply_addr->grh_hdr.ig_tclass =
10437c478bd9Sstevel@tonic-gate redirect_info->rdi_tclass;
10447c478bd9Sstevel@tonic-gate reply_addr->grh_hdr.ig_flow_label =
10457c478bd9Sstevel@tonic-gate redirect_info->rdi_flow;
10467c478bd9Sstevel@tonic-gate
10477c478bd9Sstevel@tonic-gate /* Classportinfo doesn't have hoplimit field */
10486db9c6ddShiremath reply_addr->grh_hdr.ig_hop_limit = 1;
10497c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
10507c478bd9Sstevel@tonic-gate
10519d3d2ed0Shiremath } else {
10527c478bd9Sstevel@tonic-gate ibt_path_attr_t path_attr;
10537c478bd9Sstevel@tonic-gate ib_gid_t path_dgid[1];
10547c478bd9Sstevel@tonic-gate
10557c478bd9Sstevel@tonic-gate /*
10567c478bd9Sstevel@tonic-gate * If GID is specified, and LID is zero in classportinfo
10579d3d2ed0Shiremath * do a path lookup using specified GID, Pkey,
10587c478bd9Sstevel@tonic-gate * in classportinfo
10597c478bd9Sstevel@tonic-gate */
10607c478bd9Sstevel@tonic-gate
10617c478bd9Sstevel@tonic-gate bzero(&path_attr, sizeof (path_attr));
10627c478bd9Sstevel@tonic-gate
10637c478bd9Sstevel@tonic-gate path_attr.pa_dgids = &path_dgid[0];
10647c478bd9Sstevel@tonic-gate path_attr.pa_dgids[0] = redirect_info->rdi_gid;
10657c478bd9Sstevel@tonic-gate
10667c478bd9Sstevel@tonic-gate /*
10677c478bd9Sstevel@tonic-gate * use reply_addr below, as sender_gid in reply_addr
10687c478bd9Sstevel@tonic-gate * may have been set above based on some policy decision
10697c478bd9Sstevel@tonic-gate * for originating end point for CM MADs above
10707c478bd9Sstevel@tonic-gate */
10717c478bd9Sstevel@tonic-gate path_attr.pa_sgid = reply_addr->grh_hdr.ig_sender_gid;
10727c478bd9Sstevel@tonic-gate path_attr.pa_num_dgids = 1;
10737c478bd9Sstevel@tonic-gate path_attr.pa_pkey = redirect_info->rdi_pkey;
10747c478bd9Sstevel@tonic-gate
10757c478bd9Sstevel@tonic-gate if ((status = ibt_get_paths(ibcm_ibt_handle,
10769d3d2ed0Shiremath IBT_PATH_PKEY, &path_attr, 1, &path, NULL)) !=
10777c478bd9Sstevel@tonic-gate IBT_SUCCESS)
10787c478bd9Sstevel@tonic-gate return (status);
10797c478bd9Sstevel@tonic-gate
10807c478bd9Sstevel@tonic-gate /* Initialize cm_adds */
10817c478bd9Sstevel@tonic-gate cm_adds = &path.pi_prim_cep_path.cep_adds_vect;
10827c478bd9Sstevel@tonic-gate *cm_pkt_lt = path.pi_prim_pkt_lt;
10837c478bd9Sstevel@tonic-gate }
10847c478bd9Sstevel@tonic-gate
10857c478bd9Sstevel@tonic-gate } else { /* cm_pkey initialized in ibt_open_rc_channel */
10867c478bd9Sstevel@tonic-gate reply_addr->rcvd_addr.ia_q_key = IB_GSI_QKEY;
10877c478bd9Sstevel@tonic-gate reply_addr->rcvd_addr.ia_remote_qno = 1;
10887c478bd9Sstevel@tonic-gate *cm_pkt_lt = chan_args->oc_path->pi_prim_pkt_lt;
10897c478bd9Sstevel@tonic-gate cm_adds = &(IBCM_PRIM_ADDS_VECT(chan_args));
10907c478bd9Sstevel@tonic-gate }
10917c478bd9Sstevel@tonic-gate
10927c478bd9Sstevel@tonic-gate
10937c478bd9Sstevel@tonic-gate cm_grh = cm_adds->av_send_grh;
10947c478bd9Sstevel@tonic-gate reply_addr->grh_exists = cm_grh;
10957c478bd9Sstevel@tonic-gate
10967c478bd9Sstevel@tonic-gate reply_addr->rcvd_addr.ia_remote_lid =
10977c478bd9Sstevel@tonic-gate cm_adds->av_dlid;
10987c478bd9Sstevel@tonic-gate reply_addr->grh_hdr.ig_recver_gid =
10997c478bd9Sstevel@tonic-gate cm_adds->av_dgid;
11007c478bd9Sstevel@tonic-gate reply_addr->grh_hdr.ig_flow_label =
11017c478bd9Sstevel@tonic-gate cm_adds->av_flow & IB_GRH_FLOW_LABEL_MASK;
11027c478bd9Sstevel@tonic-gate reply_addr->grh_hdr.ig_tclass =
11037c478bd9Sstevel@tonic-gate (cm_grh == B_TRUE) ? cm_adds->av_tclass : 0;
11047c478bd9Sstevel@tonic-gate reply_addr->grh_hdr.ig_hop_limit =
11056db9c6ddShiremath (cm_grh == B_TRUE) ? cm_adds->av_hop : 1;
11067c478bd9Sstevel@tonic-gate reply_addr->rcvd_addr.ia_service_level =
11077c478bd9Sstevel@tonic-gate cm_adds->av_srvl;
11087c478bd9Sstevel@tonic-gate
11097c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*reply_addr))
11107c478bd9Sstevel@tonic-gate
11117c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
11127c478bd9Sstevel@tonic-gate }
11137c478bd9Sstevel@tonic-gate
11147c478bd9Sstevel@tonic-gate
11157c478bd9Sstevel@tonic-gate /*
11167c478bd9Sstevel@tonic-gate * ibt_prime_close_rc_channel()
11177c478bd9Sstevel@tonic-gate * It allocates resources required for close channel operation, so
11187c478bd9Sstevel@tonic-gate * ibt_close_rc_channel can be called from interrupt routine.
11197c478bd9Sstevel@tonic-gate *
11207c478bd9Sstevel@tonic-gate * INPUTS:
11217c478bd9Sstevel@tonic-gate * channel The address of an ibt_channel_t struct that
11227c478bd9Sstevel@tonic-gate * specifies the channel to open.
11237c478bd9Sstevel@tonic-gate *
11247c478bd9Sstevel@tonic-gate * RETURN VALUES:
11257c478bd9Sstevel@tonic-gate * IBT_SUCCESS on success(or respective failure on error)
11267c478bd9Sstevel@tonic-gate *
11277c478bd9Sstevel@tonic-gate * Clients are typically expected to call this function in established state
11287c478bd9Sstevel@tonic-gate */
11297c478bd9Sstevel@tonic-gate ibt_status_t
ibt_prime_close_rc_channel(ibt_channel_hdl_t channel)11307c478bd9Sstevel@tonic-gate ibt_prime_close_rc_channel(ibt_channel_hdl_t channel)
11317c478bd9Sstevel@tonic-gate {
11327c478bd9Sstevel@tonic-gate ibcm_state_data_t *statep;
11337c478bd9Sstevel@tonic-gate ibt_status_t status = IBT_SUCCESS;
11347c478bd9Sstevel@tonic-gate
11357c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_prime_close_rc_channel(%p)", channel);
11367c478bd9Sstevel@tonic-gate
11377c478bd9Sstevel@tonic-gate /* validate channel, first */
11387c478bd9Sstevel@tonic-gate if (IBCM_INVALID_CHANNEL(channel)) {
11397c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_prime_close_rc_channel: chan 0x%p "
11407c478bd9Sstevel@tonic-gate "invalid channel", channel);
11417c478bd9Sstevel@tonic-gate return (IBT_CHAN_HDL_INVALID);
11427c478bd9Sstevel@tonic-gate }
11437c478bd9Sstevel@tonic-gate
11447c478bd9Sstevel@tonic-gate if (ibtl_cm_get_chan_type(channel) != IBT_RC_SRV) {
11457c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_prime_close_rc_channel: chan 0x%p "
11467c478bd9Sstevel@tonic-gate "Invalid Channel type: Applicable only to RC Channel",
11477c478bd9Sstevel@tonic-gate channel);
11487c478bd9Sstevel@tonic-gate return (IBT_CHAN_SRV_TYPE_INVALID);
11497c478bd9Sstevel@tonic-gate }
11507c478bd9Sstevel@tonic-gate
11517c478bd9Sstevel@tonic-gate /* get the statep */
11527c478bd9Sstevel@tonic-gate IBCM_GET_CHAN_PRIVATE(channel, statep);
11537c478bd9Sstevel@tonic-gate
11547c478bd9Sstevel@tonic-gate /*
11557c478bd9Sstevel@tonic-gate * This can happen, if the statep is already gone by a DREQ from
11567c478bd9Sstevel@tonic-gate * the remote side
11577c478bd9Sstevel@tonic-gate */
11587c478bd9Sstevel@tonic-gate
11597c478bd9Sstevel@tonic-gate if (statep == NULL) {
11607c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_prime_close_rc_channel: chan 0x%p "
11617c478bd9Sstevel@tonic-gate "statep NULL", channel);
11627c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
11637c478bd9Sstevel@tonic-gate }
11647c478bd9Sstevel@tonic-gate
11657c478bd9Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
11667c478bd9Sstevel@tonic-gate IBCM_RELEASE_CHAN_PRIVATE(channel);
11677c478bd9Sstevel@tonic-gate if (statep->state != IBCM_STATE_ESTABLISHED) {
11687c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
11697c478bd9Sstevel@tonic-gate return (IBT_CHAN_STATE_INVALID);
11707c478bd9Sstevel@tonic-gate }
11717c478bd9Sstevel@tonic-gate IBCM_REF_CNT_INCR(statep);
11727c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_prime_close_rc_channel: chan 0x%p statep %p"
11737c478bd9Sstevel@tonic-gate " state %x", channel, statep, statep->state);
11747c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
11757c478bd9Sstevel@tonic-gate
11767c478bd9Sstevel@tonic-gate /* clients could pre-allocate dreq mad, even before connection est */
11777c478bd9Sstevel@tonic-gate if (statep->dreq_msg == NULL)
11787c478bd9Sstevel@tonic-gate status = ibcm_alloc_out_msg(statep->stored_reply_addr.ibmf_hdl,
11797c478bd9Sstevel@tonic-gate &statep->dreq_msg, MAD_METHOD_SEND);
11807c478bd9Sstevel@tonic-gate
11817c478bd9Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
11827c478bd9Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
11837c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
11847c478bd9Sstevel@tonic-gate
11857c478bd9Sstevel@tonic-gate if (status != IBT_SUCCESS) {
11867c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_prime_close_rc_channel: chan 0x%p "
11877c478bd9Sstevel@tonic-gate "ibcm_alloc_out_msg failed ", channel);
11887c478bd9Sstevel@tonic-gate return (status);
11897c478bd9Sstevel@tonic-gate }
11907c478bd9Sstevel@tonic-gate
11917c478bd9Sstevel@tonic-gate /* If this message isn't seen then ibt_prime_close_rc_channel failed */
11927c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_prime_close_rc_channel: chan 0x%p done",
11937c478bd9Sstevel@tonic-gate channel);
11947c478bd9Sstevel@tonic-gate
11957c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
11967c478bd9Sstevel@tonic-gate }
11977c478bd9Sstevel@tonic-gate
11987c478bd9Sstevel@tonic-gate /*
11997c478bd9Sstevel@tonic-gate * ibt_close_rc_channel()
12007c478bd9Sstevel@tonic-gate * It closes an established channel.
12017c478bd9Sstevel@tonic-gate *
12027c478bd9Sstevel@tonic-gate * RETURN VALUES:
12037c478bd9Sstevel@tonic-gate * IBT_SUCCESS on success(or respective failure on error)
12047c478bd9Sstevel@tonic-gate */
12057c478bd9Sstevel@tonic-gate ibt_status_t
ibt_close_rc_channel(ibt_channel_hdl_t channel,ibt_execution_mode_t mode,void * priv_data,ibt_priv_data_len_t priv_data_len,uint8_t * ret_status,void * ret_priv_data,ibt_priv_data_len_t * ret_priv_data_len_p)12067c478bd9Sstevel@tonic-gate ibt_close_rc_channel(ibt_channel_hdl_t channel, ibt_execution_mode_t mode,
12077c478bd9Sstevel@tonic-gate void *priv_data, ibt_priv_data_len_t priv_data_len, uint8_t *ret_status,
12087c478bd9Sstevel@tonic-gate void *ret_priv_data, ibt_priv_data_len_t *ret_priv_data_len_p)
12097c478bd9Sstevel@tonic-gate {
12107c478bd9Sstevel@tonic-gate ibcm_state_data_t *statep;
12117c478bd9Sstevel@tonic-gate
12127c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_close_rc_channel(%p, %x, %p, %d, %p)",
12137c478bd9Sstevel@tonic-gate channel, mode, priv_data, priv_data_len,
12147c478bd9Sstevel@tonic-gate (ret_priv_data_len_p == NULL) ? 0 : *ret_priv_data_len_p);
12157c478bd9Sstevel@tonic-gate
12167c478bd9Sstevel@tonic-gate /* validate channel, first */
12177c478bd9Sstevel@tonic-gate if (IBCM_INVALID_CHANNEL(channel)) {
12187c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_close_rc_channel: chan 0x%p "
12197c478bd9Sstevel@tonic-gate "invalid channel", channel);
12207c478bd9Sstevel@tonic-gate return (IBT_CHAN_HDL_INVALID);
12217c478bd9Sstevel@tonic-gate }
12227c478bd9Sstevel@tonic-gate
12237c478bd9Sstevel@tonic-gate if (ibtl_cm_get_chan_type(channel) != IBT_RC_SRV) {
12247c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_close_rc_channel: chan 0x%p "
12257c478bd9Sstevel@tonic-gate "Invalid Channel type: Applicable only to RC Channel",
12267c478bd9Sstevel@tonic-gate channel);
12277c478bd9Sstevel@tonic-gate return (IBT_CHAN_SRV_TYPE_INVALID);
12287c478bd9Sstevel@tonic-gate }
12297c478bd9Sstevel@tonic-gate
12307c478bd9Sstevel@tonic-gate if (mode == IBT_BLOCKING) {
12317c478bd9Sstevel@tonic-gate /* valid only for BLOCKING MODE */
12327c478bd9Sstevel@tonic-gate if ((ret_priv_data_len_p != NULL) &&
12337c478bd9Sstevel@tonic-gate (*ret_priv_data_len_p > IBT_DREP_PRIV_DATA_SZ)) {
12347c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_close_rc_channel: chan 0x%p"
12357c478bd9Sstevel@tonic-gate " private data len %d is too large", channel,
12367c478bd9Sstevel@tonic-gate *ret_priv_data_len_p);
12377c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
12387c478bd9Sstevel@tonic-gate }
12397c478bd9Sstevel@tonic-gate } else if ((mode != IBT_NONBLOCKING) && (mode != IBT_NOCALLBACKS)) {
12407c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_close_rc_channel: chan 0x%p "
12417c478bd9Sstevel@tonic-gate "invalid mode %x specified", channel, mode);
12427c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
12437c478bd9Sstevel@tonic-gate }
12447c478bd9Sstevel@tonic-gate
12457c478bd9Sstevel@tonic-gate if (ibtl_cm_is_chan_closing(channel) ||
12467c478bd9Sstevel@tonic-gate ibtl_cm_is_chan_closed(channel)) {
12477c478bd9Sstevel@tonic-gate if (ret_status)
12487c478bd9Sstevel@tonic-gate *ret_status = IBT_CM_CLOSED_ALREADY;
12497c478bd9Sstevel@tonic-gate
12507c478bd9Sstevel@tonic-gate /* No private data to return to the client */
12517c478bd9Sstevel@tonic-gate if (ret_priv_data_len_p != NULL)
12527c478bd9Sstevel@tonic-gate *ret_priv_data_len_p = 0;
12537c478bd9Sstevel@tonic-gate
12542e8bde70Sagiri if ((mode == IBT_BLOCKING) ||
12552e8bde70Sagiri (mode == IBT_NOCALLBACKS)) {
12562e8bde70Sagiri IBCM_GET_CHAN_PRIVATE(channel, statep);
12572e8bde70Sagiri if (statep == NULL)
12582e8bde70Sagiri return (IBT_SUCCESS);
12592e8bde70Sagiri mutex_enter(&statep->state_mutex);
12602e8bde70Sagiri IBCM_RELEASE_CHAN_PRIVATE(channel);
12612e8bde70Sagiri IBCM_REF_CNT_INCR(statep);
12622e8bde70Sagiri while (statep->close_done != B_TRUE)
12632e8bde70Sagiri cv_wait(&statep->block_client_cv,
12642e8bde70Sagiri &statep->state_mutex);
12652e8bde70Sagiri IBCM_REF_CNT_DECR(statep);
12662e8bde70Sagiri mutex_exit(&statep->state_mutex);
12672e8bde70Sagiri }
12682e8bde70Sagiri
1269934f0bccShiremath IBTF_DPRINTF_L3(cmlog, "ibt_close_rc_channel: chan 0x%p "
1270934f0bccShiremath "already marked for closing", channel);
1271934f0bccShiremath
12727c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
12737c478bd9Sstevel@tonic-gate }
1274934f0bccShiremath
1275934f0bccShiremath /* get the statep */
1276934f0bccShiremath IBCM_GET_CHAN_PRIVATE(channel, statep);
1277934f0bccShiremath if (statep == NULL) {
1278934f0bccShiremath IBTF_DPRINTF_L2(cmlog, "ibt_close_rc_channel: chan 0x%p "
1279934f0bccShiremath "statep NULL", channel);
12807c478bd9Sstevel@tonic-gate return (IBT_CHAN_STATE_INVALID);
12817c478bd9Sstevel@tonic-gate }
12827c478bd9Sstevel@tonic-gate
12837c478bd9Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
1284934f0bccShiremath
1285934f0bccShiremath if (statep->dreq_msg == NULL) {
1286015f8fffShiremath IBTF_DPRINTF_L2(cmlog, "ibt_close_rc_channel: chan 0x%p "
1287934f0bccShiremath "Fatal Error: dreq_msg is NULL", channel);
1288934f0bccShiremath IBCM_RELEASE_CHAN_PRIVATE(channel);
1289934f0bccShiremath mutex_exit(&statep->state_mutex);
1290934f0bccShiremath return (IBT_CHAN_STATE_INVALID);
1291934f0bccShiremath }
1292934f0bccShiremath
1293934f0bccShiremath if ((ret_priv_data == NULL) || (ret_priv_data_len_p == NULL)) {
1294934f0bccShiremath statep->close_ret_priv_data = NULL;
1295934f0bccShiremath statep->close_ret_priv_data_len = NULL;
1296934f0bccShiremath } else {
1297934f0bccShiremath statep->close_ret_priv_data = ret_priv_data;
1298934f0bccShiremath statep->close_ret_priv_data_len = ret_priv_data_len_p;
1299934f0bccShiremath }
1300934f0bccShiremath
1301934f0bccShiremath priv_data_len = min(priv_data_len, IBT_DREQ_PRIV_DATA_SZ);
1302934f0bccShiremath if ((priv_data != NULL) && (priv_data_len > 0)) {
1303934f0bccShiremath bcopy(priv_data, ((ibcm_dreq_msg_t *)
1304934f0bccShiremath IBCM_OUT_MSGP(statep->dreq_msg))->dreq_private_data,
1305934f0bccShiremath priv_data_len);
1306934f0bccShiremath }
1307934f0bccShiremath statep->close_ret_status = ret_status;
1308934f0bccShiremath
13097c478bd9Sstevel@tonic-gate IBCM_RELEASE_CHAN_PRIVATE(channel);
13107c478bd9Sstevel@tonic-gate IBCM_REF_CNT_INCR(statep);
1311934f0bccShiremath
1312934f0bccShiremath if (mode != IBT_NONBLOCKING) {
1313934f0bccShiremath return (ibcm_close_rc_channel(channel, statep, mode));
1314934f0bccShiremath }
1315934f0bccShiremath
1316934f0bccShiremath /* IBT_NONBLOCKING */
1317934f0bccShiremath ibcm_close_enqueue(statep);
13187c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
13197c478bd9Sstevel@tonic-gate
1320934f0bccShiremath return (IBT_SUCCESS);
1321934f0bccShiremath }
1322934f0bccShiremath
1323934f0bccShiremath void
ibcm_close_start(ibcm_state_data_t * statep)1324934f0bccShiremath ibcm_close_start(ibcm_state_data_t *statep)
1325934f0bccShiremath {
1326934f0bccShiremath mutex_enter(&statep->state_mutex);
1327934f0bccShiremath (void) ibcm_close_rc_channel(statep->channel, statep, IBT_NONBLOCKING);
1328934f0bccShiremath }
1329934f0bccShiremath
1330934f0bccShiremath static
1331934f0bccShiremath ibt_status_t
ibcm_close_rc_channel(ibt_channel_hdl_t channel,ibcm_state_data_t * statep,ibt_execution_mode_t mode)1332934f0bccShiremath ibcm_close_rc_channel(ibt_channel_hdl_t channel, ibcm_state_data_t *statep,
1333934f0bccShiremath ibt_execution_mode_t mode)
1334934f0bccShiremath {
1335934f0bccShiremath ibcm_hca_info_t *hcap;
1336934f0bccShiremath
1337934f0bccShiremath _NOTE(LOCK_RELEASED_AS_SIDE_EFFECT(&statep->state_mutex));
1338934f0bccShiremath ASSERT(MUTEX_HELD(&statep->state_mutex));
1339934f0bccShiremath
1340934f0bccShiremath IBTF_DPRINTF_L3(cmlog, "ibcm_close_rc_channel: chan 0x%p statep %p",
13417c478bd9Sstevel@tonic-gate channel, statep);
13427c478bd9Sstevel@tonic-gate
13437c478bd9Sstevel@tonic-gate hcap = statep->hcap;
13447c478bd9Sstevel@tonic-gate
13457c478bd9Sstevel@tonic-gate /* HCA must have been in active state. If not, it's a client bug */
13467c478bd9Sstevel@tonic-gate if (!IBCM_ACCESS_HCA_OK(hcap)) {
1347934f0bccShiremath IBTF_DPRINTF_L2(cmlog, "ibcm_close_rc_channel: chan 0x%p "
13487c478bd9Sstevel@tonic-gate "hcap 0x%p not active", channel, hcap);
13497c478bd9Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
13507c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
13517c478bd9Sstevel@tonic-gate return (IBT_CHAN_HDL_INVALID);
13527c478bd9Sstevel@tonic-gate }
13537c478bd9Sstevel@tonic-gate
13547c478bd9Sstevel@tonic-gate if (statep->state == IBCM_STATE_TRANSIENT_ESTABLISHED) {
13557c478bd9Sstevel@tonic-gate while (statep->cep_in_rts == IBCM_BLOCK)
13567c478bd9Sstevel@tonic-gate cv_wait(&statep->block_mad_cv, &statep->state_mutex);
13577c478bd9Sstevel@tonic-gate }
13587c478bd9Sstevel@tonic-gate
13597c478bd9Sstevel@tonic-gate /* Do TRANSIENT_DREQ check after TRANSIENT_ESTABLISHED check */
13607c478bd9Sstevel@tonic-gate while (statep->state == IBCM_STATE_TRANSIENT_DREQ_SENT)
13617c478bd9Sstevel@tonic-gate cv_wait(&statep->block_mad_cv, &statep->state_mutex);
13627c478bd9Sstevel@tonic-gate
1363934f0bccShiremath IBTF_DPRINTF_L4(cmlog, "ibcm_close_rc_channel: chan 0x%p "
13647c478bd9Sstevel@tonic-gate "connection state is %x", channel, statep->state);
13657c478bd9Sstevel@tonic-gate
13667c478bd9Sstevel@tonic-gate /* If state is in pre-established states, abort the connection est */
13677c478bd9Sstevel@tonic-gate if (statep->state != IBCM_STATE_ESTABLISHED) {
13689d3d2ed0Shiremath statep->cm_retries++; /* ensure connection trace is dumped */
13697c478bd9Sstevel@tonic-gate
13707c478bd9Sstevel@tonic-gate /* No DREP private data possible */
1371934f0bccShiremath if (statep->close_ret_priv_data_len != NULL)
1372934f0bccShiremath *statep->close_ret_priv_data_len = 0;
13737c478bd9Sstevel@tonic-gate
13747c478bd9Sstevel@tonic-gate /*
13757c478bd9Sstevel@tonic-gate * If waiting for a response mad, then cancel the timer,
13767c478bd9Sstevel@tonic-gate * and delete the connection
13777c478bd9Sstevel@tonic-gate */
13787c478bd9Sstevel@tonic-gate if (statep->state == IBCM_STATE_REQ_SENT ||
13797c478bd9Sstevel@tonic-gate statep->state == IBCM_STATE_REP_SENT ||
13807c478bd9Sstevel@tonic-gate statep->state == IBCM_STATE_REP_WAIT ||
13817c478bd9Sstevel@tonic-gate statep->state == IBCM_STATE_MRA_REP_RCVD) {
13827c478bd9Sstevel@tonic-gate timeout_id_t timer_val = statep->timerid;
13837c478bd9Sstevel@tonic-gate ibcm_conn_state_t old_state;
13847c478bd9Sstevel@tonic-gate
1385934f0bccShiremath IBTF_DPRINTF_L4(cmlog, "ibcm_close_rc_channel: "
13867c478bd9Sstevel@tonic-gate "chan 0x%p connection aborted in state %x", channel,
13877c478bd9Sstevel@tonic-gate statep->state);
13887c478bd9Sstevel@tonic-gate
13897c478bd9Sstevel@tonic-gate old_state = statep->state;
13907c478bd9Sstevel@tonic-gate statep->state = IBCM_STATE_DELETE;
13917c478bd9Sstevel@tonic-gate
13927c478bd9Sstevel@tonic-gate if (mode == IBT_NONBLOCKING) {
13937c478bd9Sstevel@tonic-gate if (taskq_dispatch(ibcm_taskq,
13947c478bd9Sstevel@tonic-gate ibcm_process_abort_via_taskq, statep,
1395*fc8ae2ecSToomas Soome TQ_NOSLEEP) == TASKQID_INVALID) {
13967c478bd9Sstevel@tonic-gate
13977c478bd9Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
13987c478bd9Sstevel@tonic-gate statep->state = old_state;
13997c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
14007c478bd9Sstevel@tonic-gate return (IBT_INSUFF_KERNEL_RESOURCE);
14017c478bd9Sstevel@tonic-gate } /* if taskq_dispatch succeeds */
14027c478bd9Sstevel@tonic-gate /* Cancel the timer */
14037c478bd9Sstevel@tonic-gate statep->timerid = 0;
14047c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
14057c478bd9Sstevel@tonic-gate } else {
14067c478bd9Sstevel@tonic-gate /* Cancel the timer */
14077c478bd9Sstevel@tonic-gate statep->timerid = 0;
14087c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
14097c478bd9Sstevel@tonic-gate (void) taskq_dispatch(ibcm_taskq,
14107c478bd9Sstevel@tonic-gate ibcm_process_abort_via_taskq, statep,
14117c478bd9Sstevel@tonic-gate TQ_SLEEP);
14127c478bd9Sstevel@tonic-gate }
14137c478bd9Sstevel@tonic-gate
14147c478bd9Sstevel@tonic-gate /* cancel the currently running timer */
14157c478bd9Sstevel@tonic-gate if (timer_val != 0)
14167c478bd9Sstevel@tonic-gate (void) untimeout(timer_val);
14177c478bd9Sstevel@tonic-gate
14187c478bd9Sstevel@tonic-gate /* wait until cm handler returns for BLOCKING cases */
1419934f0bccShiremath mutex_enter(&statep->state_mutex);
14207c478bd9Sstevel@tonic-gate if ((mode == IBT_BLOCKING) ||
14217c478bd9Sstevel@tonic-gate (mode == IBT_NOCALLBACKS)) {
14227c478bd9Sstevel@tonic-gate while (statep->close_done != B_TRUE)
14237c478bd9Sstevel@tonic-gate cv_wait(&statep->block_client_cv,
14247c478bd9Sstevel@tonic-gate &statep->state_mutex);
14257c478bd9Sstevel@tonic-gate }
14267c478bd9Sstevel@tonic-gate
1427934f0bccShiremath if (statep->close_ret_status)
1428934f0bccShiremath *statep->close_ret_status = IBT_CM_CLOSED_ABORT;
1429934f0bccShiremath mutex_exit(&statep->state_mutex);
14307c478bd9Sstevel@tonic-gate
14317c478bd9Sstevel@tonic-gate /*
14327c478bd9Sstevel@tonic-gate * It would ideal to post a REJ MAD, but that would
14337c478bd9Sstevel@tonic-gate * be non-conformance to spec. Hence, delete the state
14347c478bd9Sstevel@tonic-gate * data. Assuming that happens quickly, any retransmits
14357c478bd9Sstevel@tonic-gate * from the remote are replied by CM with reject
14367c478bd9Sstevel@tonic-gate * reason " no valid com id". That would stop remote
14377c478bd9Sstevel@tonic-gate * sending any more MADs.
14387c478bd9Sstevel@tonic-gate */
14397c478bd9Sstevel@tonic-gate ibcm_delete_state_data(statep);
14407c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
14417c478bd9Sstevel@tonic-gate
14427c478bd9Sstevel@tonic-gate /* if CM busy in cm handler, wait until cm handler returns */
14437c478bd9Sstevel@tonic-gate } else if (statep->state == IBCM_STATE_REQ_RCVD ||
14447c478bd9Sstevel@tonic-gate statep->state == IBCM_STATE_REP_RCVD ||
14457c478bd9Sstevel@tonic-gate statep->state == IBCM_STATE_MRA_SENT ||
14467c478bd9Sstevel@tonic-gate statep->state == IBCM_STATE_MRA_REP_SENT) {
14477c478bd9Sstevel@tonic-gate
14487c478bd9Sstevel@tonic-gate /* take control of statep */
14497c478bd9Sstevel@tonic-gate statep->abort_flag |= IBCM_ABORT_CLIENT;
14507c478bd9Sstevel@tonic-gate
1451934f0bccShiremath IBTF_DPRINTF_L4(cmlog, "ibcm_close_rc_channel: "
14527c478bd9Sstevel@tonic-gate "chan 0x%p connection aborted in state = %x",
14537c478bd9Sstevel@tonic-gate channel, statep->state);
14547c478bd9Sstevel@tonic-gate
14557c478bd9Sstevel@tonic-gate /*
14567c478bd9Sstevel@tonic-gate * wait until state machine modifies qp state to error,
14577c478bd9Sstevel@tonic-gate * including disassociating statep and QP
14587c478bd9Sstevel@tonic-gate */
14597c478bd9Sstevel@tonic-gate if ((mode == IBT_BLOCKING) || (mode == IBT_NOCALLBACKS))
14607c478bd9Sstevel@tonic-gate while (statep->close_done != B_TRUE)
14617c478bd9Sstevel@tonic-gate cv_wait(&statep->block_client_cv,
14627c478bd9Sstevel@tonic-gate &statep->state_mutex);
14637c478bd9Sstevel@tonic-gate
14647c478bd9Sstevel@tonic-gate /* a sanity setting */
14657c478bd9Sstevel@tonic-gate if (mode == IBT_NOCALLBACKS)
14667c478bd9Sstevel@tonic-gate statep->cm_handler = NULL;
14677c478bd9Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
14687c478bd9Sstevel@tonic-gate
14697c478bd9Sstevel@tonic-gate /*
14707c478bd9Sstevel@tonic-gate * In rare situations, connection attempt could be
14717c478bd9Sstevel@tonic-gate * terminated for some other reason, before abort is
14727c478bd9Sstevel@tonic-gate * processed, but CM still returns ret_status as abort
14737c478bd9Sstevel@tonic-gate */
1474934f0bccShiremath if (statep->close_ret_status)
1475934f0bccShiremath *statep->close_ret_status = IBT_CM_CLOSED_ABORT;
1476934f0bccShiremath mutex_exit(&statep->state_mutex);
14777c478bd9Sstevel@tonic-gate
14787c478bd9Sstevel@tonic-gate /*
14797c478bd9Sstevel@tonic-gate * REJ MAD is posted by the CM state machine for this
14807c478bd9Sstevel@tonic-gate * case, hence state structure is deleted in the
14817c478bd9Sstevel@tonic-gate * state machine processing.
14827c478bd9Sstevel@tonic-gate */
14837c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
14847c478bd9Sstevel@tonic-gate
14857c478bd9Sstevel@tonic-gate } else if ((statep->state == IBCM_STATE_TIMEWAIT) ||
14867c478bd9Sstevel@tonic-gate (statep->state == IBCM_STATE_DELETE)) {
14877c478bd9Sstevel@tonic-gate
14887c478bd9Sstevel@tonic-gate /* State already in timewait, so no return priv data */
14897c478bd9Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
14907c478bd9Sstevel@tonic-gate
14917c478bd9Sstevel@tonic-gate /* The teardown has already been done */
1492934f0bccShiremath if (statep->close_ret_status)
1493934f0bccShiremath *statep->close_ret_status =
1494934f0bccShiremath IBT_CM_CLOSED_ALREADY;
1495934f0bccShiremath mutex_exit(&statep->state_mutex);
14967c478bd9Sstevel@tonic-gate
14977c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
14987c478bd9Sstevel@tonic-gate
14997c478bd9Sstevel@tonic-gate } else if ((statep->state == IBCM_STATE_DREQ_RCVD) ||
15007c478bd9Sstevel@tonic-gate (statep->state == IBCM_STATE_DREQ_SENT) ||
15017c478bd9Sstevel@tonic-gate (statep->state == IBCM_STATE_DREP_RCVD) ||
15027c478bd9Sstevel@tonic-gate ((statep->state == IBCM_STATE_TIMED_OUT) &&
15037c478bd9Sstevel@tonic-gate (statep->timedout_state == IBCM_STATE_DREQ_SENT))) {
15047c478bd9Sstevel@tonic-gate
15057c478bd9Sstevel@tonic-gate /*
15067c478bd9Sstevel@tonic-gate * Either the remote or local client has already
15077c478bd9Sstevel@tonic-gate * initiated the teardown. IBCM_STATE_DREP_RCVD is
15087c478bd9Sstevel@tonic-gate * possible, if CM initiated teardown without client's
15097c478bd9Sstevel@tonic-gate * knowledge, for stale handling, etc.,
15107c478bd9Sstevel@tonic-gate */
15117c478bd9Sstevel@tonic-gate if (mode == IBT_NOCALLBACKS) {
15127c478bd9Sstevel@tonic-gate if (statep->close_nocb_state == IBCM_UNBLOCK) {
15137c478bd9Sstevel@tonic-gate statep->close_nocb_state = IBCM_FAIL;
15147c478bd9Sstevel@tonic-gate /* enable free qp after return */
15157c478bd9Sstevel@tonic-gate ibtl_cm_chan_is_closing(
15167c478bd9Sstevel@tonic-gate statep->channel);
15177c478bd9Sstevel@tonic-gate } else while (statep->close_nocb_state ==
15187c478bd9Sstevel@tonic-gate IBCM_BLOCK)
15197c478bd9Sstevel@tonic-gate cv_wait(&statep->block_client_cv,
15207c478bd9Sstevel@tonic-gate &statep->state_mutex);
15217c478bd9Sstevel@tonic-gate statep->cm_handler = NULL; /* sanity setting */
1522934f0bccShiremath if (statep->close_ret_status)
1523934f0bccShiremath *statep->close_ret_status =
1524934f0bccShiremath IBT_CM_CLOSED_ALREADY;
15257c478bd9Sstevel@tonic-gate } else if (mode == IBT_BLOCKING) {
15267c478bd9Sstevel@tonic-gate /* wait until state is moved to timewait */
15277c478bd9Sstevel@tonic-gate while (statep->close_done != B_TRUE)
15287c478bd9Sstevel@tonic-gate cv_wait(&statep->block_client_cv,
15297c478bd9Sstevel@tonic-gate &statep->state_mutex);
15307c478bd9Sstevel@tonic-gate }
15317c478bd9Sstevel@tonic-gate
15327c478bd9Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
15337c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
15347c478bd9Sstevel@tonic-gate
15357c478bd9Sstevel@tonic-gate /* ret_status is set in state machine code */
15367c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
15377c478bd9Sstevel@tonic-gate
15387c478bd9Sstevel@tonic-gate } else if (statep->state == IBCM_STATE_TIMED_OUT) {
15397c478bd9Sstevel@tonic-gate
15407c478bd9Sstevel@tonic-gate if ((mode == IBT_BLOCKING) ||
15417c478bd9Sstevel@tonic-gate (mode == IBT_NOCALLBACKS)) {
15427c478bd9Sstevel@tonic-gate
15437c478bd9Sstevel@tonic-gate /*
15447c478bd9Sstevel@tonic-gate * wait until cm handler invocation and
15457c478bd9Sstevel@tonic-gate * disassociation between statep and channel
15467c478bd9Sstevel@tonic-gate * is complete
15477c478bd9Sstevel@tonic-gate */
15487c478bd9Sstevel@tonic-gate while (statep->close_done != B_TRUE)
15497c478bd9Sstevel@tonic-gate cv_wait(&statep->block_client_cv,
15507c478bd9Sstevel@tonic-gate &statep->state_mutex);
15517c478bd9Sstevel@tonic-gate }
15527c478bd9Sstevel@tonic-gate
1553934f0bccShiremath if (statep->close_ret_status)
1554934f0bccShiremath *statep->close_ret_status = IBT_CM_CLOSED_ABORT;
15557c478bd9Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
15567c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
15577c478bd9Sstevel@tonic-gate
15587c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
15597c478bd9Sstevel@tonic-gate } else {
15607c478bd9Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
15617c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
15627c478bd9Sstevel@tonic-gate
15637c478bd9Sstevel@tonic-gate return (IBT_CM_FAILURE);
15647c478bd9Sstevel@tonic-gate }
15657c478bd9Sstevel@tonic-gate }
15667c478bd9Sstevel@tonic-gate
15677c478bd9Sstevel@tonic-gate ASSERT(statep->close_nocb_state != IBCM_BLOCK);
15687c478bd9Sstevel@tonic-gate
15697c478bd9Sstevel@tonic-gate if (mode == IBT_NOCALLBACKS) {
15707c478bd9Sstevel@tonic-gate statep->close_nocb_state = IBCM_FAIL;
15717c478bd9Sstevel@tonic-gate statep->cm_handler = NULL;
15727c478bd9Sstevel@tonic-gate ibtl_cm_chan_is_closing(statep->channel);
1573934f0bccShiremath IBTF_DPRINTF_L4(cmlog, "ibcm_close_rc_channel: "
15747c478bd9Sstevel@tonic-gate "NOCALLBACKS on in statep = %p", statep);
15757c478bd9Sstevel@tonic-gate }
15767c478bd9Sstevel@tonic-gate
15779d3d2ed0Shiremath if (statep->state != IBCM_STATE_ESTABLISHED) {
15789d3d2ed0Shiremath goto lost_race;
15799d3d2ed0Shiremath }
15807c478bd9Sstevel@tonic-gate
15817c478bd9Sstevel@tonic-gate /*
15827c478bd9Sstevel@tonic-gate * Cancel/wait for any pending ibt_set_alt_path, and
15837c478bd9Sstevel@tonic-gate * release state mutex
15847c478bd9Sstevel@tonic-gate */
15857c478bd9Sstevel@tonic-gate ibcm_sync_lapr_idle(statep);
15867c478bd9Sstevel@tonic-gate
15879d3d2ed0Shiremath ibcm_close_enter();
15889d3d2ed0Shiremath
15899d3d2ed0Shiremath mutex_enter(&statep->state_mutex);
15909d3d2ed0Shiremath if (statep->state != IBCM_STATE_ESTABLISHED) {
15919d3d2ed0Shiremath ibcm_close_exit();
15929d3d2ed0Shiremath goto lost_race;
15939d3d2ed0Shiremath }
15949d3d2ed0Shiremath
15959d3d2ed0Shiremath statep->state = IBCM_STATE_TRANSIENT_DREQ_SENT;
15969d3d2ed0Shiremath statep->timerid = 0;
15979d3d2ed0Shiremath statep->close_done = B_FALSE;
15989d3d2ed0Shiremath statep->close_flow = 1;
15999d3d2ed0Shiremath mutex_exit(&statep->state_mutex);
16009d3d2ed0Shiremath
16017c478bd9Sstevel@tonic-gate ibcm_post_dreq_mad(statep);
16027c478bd9Sstevel@tonic-gate
16037c478bd9Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
16047c478bd9Sstevel@tonic-gate
16059d3d2ed0Shiremath lost_race:
16067c478bd9Sstevel@tonic-gate if (mode == IBT_BLOCKING) {
16077c478bd9Sstevel@tonic-gate
16087c478bd9Sstevel@tonic-gate /* wait for DREP */
16097c478bd9Sstevel@tonic-gate while (statep->close_done != B_TRUE)
16107c478bd9Sstevel@tonic-gate cv_wait(&statep->block_client_cv,
16117c478bd9Sstevel@tonic-gate &statep->state_mutex);
16127c478bd9Sstevel@tonic-gate
1613934f0bccShiremath IBTF_DPRINTF_L4(cmlog, "ibcm_close_rc_channel: chan 0x%p "
16147c478bd9Sstevel@tonic-gate "done blocking", channel);
16157c478bd9Sstevel@tonic-gate }
16167c478bd9Sstevel@tonic-gate
16177c478bd9Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
16187c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
16197c478bd9Sstevel@tonic-gate
16207c478bd9Sstevel@tonic-gate /* If this message isn't seen then ibt_close_rc_channel failed */
1621934f0bccShiremath IBTF_DPRINTF_L5(cmlog, "ibcm_close_rc_channel: chan 0x%p done",
16227c478bd9Sstevel@tonic-gate channel);
16237c478bd9Sstevel@tonic-gate
16247c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
16257c478bd9Sstevel@tonic-gate }
16267c478bd9Sstevel@tonic-gate
16277c478bd9Sstevel@tonic-gate ibt_status_t
ibt_recycle_rc(ibt_channel_hdl_t rc_chan,ibt_cep_flags_t control,uint8_t hca_port_num,ibt_recycle_handler_t func,void * arg)16287c478bd9Sstevel@tonic-gate ibt_recycle_rc(ibt_channel_hdl_t rc_chan, ibt_cep_flags_t control,
16297c478bd9Sstevel@tonic-gate uint8_t hca_port_num, ibt_recycle_handler_t func, void *arg)
16307c478bd9Sstevel@tonic-gate {
16317c478bd9Sstevel@tonic-gate ibcm_state_data_t *statep;
16327c478bd9Sstevel@tonic-gate ibcm_taskq_recycle_arg_t *ibcm_tq_recycle_arg;
16337c478bd9Sstevel@tonic-gate ibt_qp_query_attr_t qp_attr;
16347c478bd9Sstevel@tonic-gate ibt_status_t retval;
16357c478bd9Sstevel@tonic-gate
16367c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_recycle_rc (%p, 0x%X, %d, %p, %p)", rc_chan,
16377c478bd9Sstevel@tonic-gate control, hca_port_num, func, arg);
16387c478bd9Sstevel@tonic-gate
16397c478bd9Sstevel@tonic-gate if (IBCM_INVALID_CHANNEL(rc_chan)) {
16407c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_recycle_rc: invalid channel");
16417c478bd9Sstevel@tonic-gate return (IBT_CHAN_HDL_INVALID);
16427c478bd9Sstevel@tonic-gate }
16437c478bd9Sstevel@tonic-gate
16447c478bd9Sstevel@tonic-gate /* check qp state */
16457c478bd9Sstevel@tonic-gate retval = ibt_query_qp(rc_chan, &qp_attr);
16467c478bd9Sstevel@tonic-gate
16477c478bd9Sstevel@tonic-gate if (retval != IBT_SUCCESS)
16487c478bd9Sstevel@tonic-gate return (retval);
16497c478bd9Sstevel@tonic-gate
16507c478bd9Sstevel@tonic-gate if (qp_attr.qp_info.qp_trans != IBT_RC_SRV)
16517c478bd9Sstevel@tonic-gate return (IBT_CHAN_SRV_TYPE_INVALID);
16527c478bd9Sstevel@tonic-gate
16537c478bd9Sstevel@tonic-gate if (qp_attr.qp_info.qp_state != IBT_STATE_ERROR)
16547c478bd9Sstevel@tonic-gate return (IBT_CHAN_STATE_INVALID);
16557c478bd9Sstevel@tonic-gate
16567c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ibcm_tq_recycle_arg))
16577c478bd9Sstevel@tonic-gate
16587c478bd9Sstevel@tonic-gate ibcm_tq_recycle_arg = kmem_alloc(sizeof (ibcm_taskq_recycle_arg_t),
16597c478bd9Sstevel@tonic-gate KM_SLEEP);
16607c478bd9Sstevel@tonic-gate
16617c478bd9Sstevel@tonic-gate ibcm_tq_recycle_arg->rc_chan = rc_chan;
16627c478bd9Sstevel@tonic-gate ibcm_tq_recycle_arg->control = control;
16637c478bd9Sstevel@tonic-gate ibcm_tq_recycle_arg->hca_port_num = hca_port_num;
16647c478bd9Sstevel@tonic-gate ibcm_tq_recycle_arg->func = func;
16657c478bd9Sstevel@tonic-gate ibcm_tq_recycle_arg->arg = arg;
16667c478bd9Sstevel@tonic-gate
16677c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ibcm_tq_recycle_arg))
16687c478bd9Sstevel@tonic-gate
16697c478bd9Sstevel@tonic-gate IBCM_GET_CHAN_PRIVATE(rc_chan, statep);
16707c478bd9Sstevel@tonic-gate
16717c478bd9Sstevel@tonic-gate /*
16727c478bd9Sstevel@tonic-gate * If non-blocking ie., func specified and channel has not yet completed
16737c478bd9Sstevel@tonic-gate * the timewait, then schedule the work for later
16747c478bd9Sstevel@tonic-gate */
16757c478bd9Sstevel@tonic-gate if ((func != NULL) && (statep != NULL)) {
16767c478bd9Sstevel@tonic-gate IBCM_RELEASE_CHAN_PRIVATE(rc_chan);
16777c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(statep->recycle_arg))
16787c478bd9Sstevel@tonic-gate statep->recycle_arg = ibcm_tq_recycle_arg;
16797c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(statep->recycle_arg))
16807c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
16817c478bd9Sstevel@tonic-gate }
16827c478bd9Sstevel@tonic-gate
16837c478bd9Sstevel@tonic-gate /*
16847c478bd9Sstevel@tonic-gate * if blocking ie., func specified, and channel has not yet completed
16857c478bd9Sstevel@tonic-gate * the timewait, then block until the channel completes the timewait
16867c478bd9Sstevel@tonic-gate */
16877c478bd9Sstevel@tonic-gate if (statep != NULL)
16887c478bd9Sstevel@tonic-gate IBCM_RELEASE_CHAN_PRIVATE(rc_chan);
16897c478bd9Sstevel@tonic-gate IBCM_WAIT_CHAN_PRIVATE(rc_chan);
16907c478bd9Sstevel@tonic-gate
16917c478bd9Sstevel@tonic-gate if (func) { /* NON BLOCKING case. Taskq for QP state change */
16927c478bd9Sstevel@tonic-gate (void) taskq_dispatch(ibcm_taskq, ibcm_process_rc_recycle,
16937c478bd9Sstevel@tonic-gate ibcm_tq_recycle_arg, TQ_SLEEP);
16947c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
16957c478bd9Sstevel@tonic-gate } else /* BLOCKING case */
16967c478bd9Sstevel@tonic-gate return (ibcm_process_rc_recycle_ret(ibcm_tq_recycle_arg));
16977c478bd9Sstevel@tonic-gate }
16987c478bd9Sstevel@tonic-gate
16997c478bd9Sstevel@tonic-gate void
ibcm_process_rc_recycle(void * recycle_arg)17007c478bd9Sstevel@tonic-gate ibcm_process_rc_recycle(void *recycle_arg)
17017c478bd9Sstevel@tonic-gate {
17027c478bd9Sstevel@tonic-gate (void) ibcm_process_rc_recycle_ret(recycle_arg);
17037c478bd9Sstevel@tonic-gate }
17047c478bd9Sstevel@tonic-gate
17057c478bd9Sstevel@tonic-gate static ibt_status_t
ibcm_process_rc_recycle_ret(void * recycle_arg)17067c478bd9Sstevel@tonic-gate ibcm_process_rc_recycle_ret(void *recycle_arg)
17077c478bd9Sstevel@tonic-gate {
17087c478bd9Sstevel@tonic-gate ibt_qp_info_t qp_info;
17097c478bd9Sstevel@tonic-gate ibt_status_t ibt_status = IBT_SUCCESS;
17107c478bd9Sstevel@tonic-gate ibt_cep_modify_flags_t cep_flags;
17117c478bd9Sstevel@tonic-gate ibt_qp_query_attr_t qp_attr;
17127c478bd9Sstevel@tonic-gate ibcm_taskq_recycle_arg_t *ibcm_tq_recycle_arg =
17137c478bd9Sstevel@tonic-gate (ibcm_taskq_recycle_arg_t *)recycle_arg;
17147c478bd9Sstevel@tonic-gate
17157c478bd9Sstevel@tonic-gate /* QP must have been in error state */
17167c478bd9Sstevel@tonic-gate ibt_status = ibt_query_qp(ibcm_tq_recycle_arg->rc_chan, &qp_attr);
17177c478bd9Sstevel@tonic-gate if (ibt_status != IBT_SUCCESS)
17187c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_rc_recycle_ret: "
17197c478bd9Sstevel@tonic-gate "chanp %p ibt_query_qp() = %d",
17207c478bd9Sstevel@tonic-gate ibcm_tq_recycle_arg->rc_chan, ibt_status);
17217c478bd9Sstevel@tonic-gate else {
17227c478bd9Sstevel@tonic-gate /* perform the QP state change from ERROR to RESET */
17237c478bd9Sstevel@tonic-gate bzero(&qp_info, sizeof (qp_info));
17247c478bd9Sstevel@tonic-gate
17257c478bd9Sstevel@tonic-gate qp_info.qp_trans = IBT_RC_SRV;
17267c478bd9Sstevel@tonic-gate qp_info.qp_state = IBT_STATE_RESET;
17277c478bd9Sstevel@tonic-gate
17287c478bd9Sstevel@tonic-gate /* Call modify_qp to move to RESET state */
17297c478bd9Sstevel@tonic-gate ibt_status = ibt_modify_qp(ibcm_tq_recycle_arg->rc_chan,
17307c478bd9Sstevel@tonic-gate IBT_CEP_SET_STATE, &qp_info, NULL);
17317c478bd9Sstevel@tonic-gate
17327c478bd9Sstevel@tonic-gate if (ibt_status != IBT_SUCCESS)
17337c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_rc_recycle_ret: "
17347c478bd9Sstevel@tonic-gate "chanp %p ibt_modify_qp() = %d for ERROR to RESET",
17357c478bd9Sstevel@tonic-gate ibcm_tq_recycle_arg->rc_chan, ibt_status);
17367c478bd9Sstevel@tonic-gate }
17377c478bd9Sstevel@tonic-gate
17387c478bd9Sstevel@tonic-gate if (ibt_status == IBT_SUCCESS) {
17397c478bd9Sstevel@tonic-gate
17407c478bd9Sstevel@tonic-gate qp_info.qp_state = IBT_STATE_INIT;
17417c478bd9Sstevel@tonic-gate
17427c478bd9Sstevel@tonic-gate /* set flags for all mandatory args from RESET to INIT */
17437c478bd9Sstevel@tonic-gate cep_flags = IBT_CEP_SET_STATE | IBT_CEP_SET_PORT;
17447c478bd9Sstevel@tonic-gate cep_flags |= IBT_CEP_SET_RDMA_R | IBT_CEP_SET_RDMA_W;
17457c478bd9Sstevel@tonic-gate cep_flags |= IBT_CEP_SET_ATOMIC;
17467c478bd9Sstevel@tonic-gate
17477c478bd9Sstevel@tonic-gate qp_info.qp_transport.rc.rc_path.cep_hca_port_num =
17487c478bd9Sstevel@tonic-gate ibcm_tq_recycle_arg->hca_port_num;
17497c478bd9Sstevel@tonic-gate qp_info.qp_flags |=
17507c478bd9Sstevel@tonic-gate ibcm_tq_recycle_arg->control & IBT_CEP_RDMA_RD;
17517c478bd9Sstevel@tonic-gate qp_info.qp_flags |=
17527c478bd9Sstevel@tonic-gate ibcm_tq_recycle_arg->control & IBT_CEP_RDMA_WR;
17537c478bd9Sstevel@tonic-gate qp_info.qp_flags |=
17547c478bd9Sstevel@tonic-gate ibcm_tq_recycle_arg->control & IBT_CEP_ATOMIC;
17557c478bd9Sstevel@tonic-gate
17567c478bd9Sstevel@tonic-gate /* Always use the existing pkey */
17577c478bd9Sstevel@tonic-gate qp_info.qp_transport.rc.rc_path.cep_pkey_ix =
17587c478bd9Sstevel@tonic-gate qp_attr. qp_info.qp_transport.rc.rc_path.cep_pkey_ix;
17597c478bd9Sstevel@tonic-gate
17607c478bd9Sstevel@tonic-gate /* Call modify_qp to move to INIT state */
17617c478bd9Sstevel@tonic-gate ibt_status = ibt_modify_qp(ibcm_tq_recycle_arg->rc_chan,
17627c478bd9Sstevel@tonic-gate cep_flags, &qp_info, NULL);
17637c478bd9Sstevel@tonic-gate
17647c478bd9Sstevel@tonic-gate if (ibt_status != IBT_SUCCESS)
17657c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_rc_recycle_ret: "
17667c478bd9Sstevel@tonic-gate "chanp %p ibt_modify_qp() = %d for RESET to INIT",
17677c478bd9Sstevel@tonic-gate ibcm_tq_recycle_arg->rc_chan, ibt_status);
17687c478bd9Sstevel@tonic-gate }
17697c478bd9Sstevel@tonic-gate
17707c478bd9Sstevel@tonic-gate /* Change the QP CM state to indicate QP being re-used */
17717c478bd9Sstevel@tonic-gate if (ibt_status == IBT_SUCCESS)
17727c478bd9Sstevel@tonic-gate ibtl_cm_chan_is_reused(ibcm_tq_recycle_arg->rc_chan);
17737c478bd9Sstevel@tonic-gate
17747c478bd9Sstevel@tonic-gate /* Call func, if defined */
17757c478bd9Sstevel@tonic-gate if (ibcm_tq_recycle_arg->func)
17767c478bd9Sstevel@tonic-gate (*(ibcm_tq_recycle_arg->func))(ibt_status,
17777c478bd9Sstevel@tonic-gate ibcm_tq_recycle_arg->arg);
17787c478bd9Sstevel@tonic-gate
17797c478bd9Sstevel@tonic-gate kmem_free(ibcm_tq_recycle_arg, sizeof (ibcm_taskq_recycle_arg_t));
17807c478bd9Sstevel@tonic-gate
17817c478bd9Sstevel@tonic-gate return (ibt_status);
17827c478bd9Sstevel@tonic-gate }
17837c478bd9Sstevel@tonic-gate
17847c478bd9Sstevel@tonic-gate static void
ibcm_process_abort_via_taskq(void * args)17857c478bd9Sstevel@tonic-gate ibcm_process_abort_via_taskq(void *args)
17867c478bd9Sstevel@tonic-gate {
17877c478bd9Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
17887c478bd9Sstevel@tonic-gate
17897c478bd9Sstevel@tonic-gate ibcm_process_abort(statep);
17907c478bd9Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
17917c478bd9Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
17927c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
17937c478bd9Sstevel@tonic-gate }
17947c478bd9Sstevel@tonic-gate
17957c478bd9Sstevel@tonic-gate /*
17967c478bd9Sstevel@tonic-gate * Local UD CM Handler's private data, used during ibt_request_ud_dest() in
17977c478bd9Sstevel@tonic-gate * Non-Blocking mode operations.
17987c478bd9Sstevel@tonic-gate */
17997c478bd9Sstevel@tonic-gate typedef struct ibcm_local_handler_s {
18007c478bd9Sstevel@tonic-gate ibt_cm_ud_handler_t actual_cm_handler;
18017c478bd9Sstevel@tonic-gate void *actual_cm_private;
18027c478bd9Sstevel@tonic-gate ibt_ud_dest_t *dest_hdl;
18037c478bd9Sstevel@tonic-gate } ibcm_local_handler_t;
18047c478bd9Sstevel@tonic-gate
_NOTE(READ_ONLY_DATA (ibcm_local_handler_s))18057c478bd9Sstevel@tonic-gate _NOTE(READ_ONLY_DATA(ibcm_local_handler_s))
18067c478bd9Sstevel@tonic-gate
18077c478bd9Sstevel@tonic-gate /*
18087c478bd9Sstevel@tonic-gate * Local UD CM Handler, used when ibt_alloc_ud_dest() is issued in
18097c478bd9Sstevel@tonic-gate * NON-Blocking mode.
18107c478bd9Sstevel@tonic-gate *
18117c478bd9Sstevel@tonic-gate * Out here, we update the UD Destination handle with
18127c478bd9Sstevel@tonic-gate * the obtained DQPN and QKey (from SIDR REP) and invokes actual client
18137c478bd9Sstevel@tonic-gate * handler that was specified by the client.
18147c478bd9Sstevel@tonic-gate */
18157c478bd9Sstevel@tonic-gate static ibt_cm_status_t
18167c478bd9Sstevel@tonic-gate ibcm_local_cm_handler(void *priv, ibt_cm_ud_event_t *event,
18177c478bd9Sstevel@tonic-gate ibt_cm_ud_return_args_t *ret_args, void *priv_data, ibt_priv_data_len_t len)
18187c478bd9Sstevel@tonic-gate {
18197c478bd9Sstevel@tonic-gate ibcm_local_handler_t *handler_priv = (ibcm_local_handler_t *)priv;
18207c478bd9Sstevel@tonic-gate
18217c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_local_cm_handler: event %d",
18227c478bd9Sstevel@tonic-gate event->cm_type);
18237c478bd9Sstevel@tonic-gate
18247c478bd9Sstevel@tonic-gate ASSERT(handler_priv != NULL);
18257c478bd9Sstevel@tonic-gate
18267c478bd9Sstevel@tonic-gate switch (event->cm_type) {
18277c478bd9Sstevel@tonic-gate case IBT_CM_UD_EVENT_SIDR_REP:
18287c478bd9Sstevel@tonic-gate /* Update QPN & QKey from event into destination handle. */
18297c478bd9Sstevel@tonic-gate if (handler_priv->dest_hdl != NULL) {
18307c478bd9Sstevel@tonic-gate handler_priv->dest_hdl->ud_dst_qpn =
18317c478bd9Sstevel@tonic-gate event->cm_event.sidr_rep.srep_remote_qpn;
18327c478bd9Sstevel@tonic-gate handler_priv->dest_hdl->ud_qkey =
18337c478bd9Sstevel@tonic-gate event->cm_event.sidr_rep.srep_remote_qkey;
18347c478bd9Sstevel@tonic-gate }
18357c478bd9Sstevel@tonic-gate
18367c478bd9Sstevel@tonic-gate /* Invoke the client handler - inform only, so ignore retval */
18377c478bd9Sstevel@tonic-gate (void) handler_priv->actual_cm_handler(
18387c478bd9Sstevel@tonic-gate handler_priv->actual_cm_private, event, ret_args, priv_data,
18397c478bd9Sstevel@tonic-gate len);
18407c478bd9Sstevel@tonic-gate
18417c478bd9Sstevel@tonic-gate /* Free memory allocated for local handler's private data. */
18427c478bd9Sstevel@tonic-gate if (handler_priv != NULL)
18437c478bd9Sstevel@tonic-gate kmem_free(handler_priv, sizeof (*handler_priv));
18447c478bd9Sstevel@tonic-gate
18457c478bd9Sstevel@tonic-gate break;
18467c478bd9Sstevel@tonic-gate default:
18477c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_local_cm_handler: ERROR");
18487c478bd9Sstevel@tonic-gate break;
18497c478bd9Sstevel@tonic-gate }
18507c478bd9Sstevel@tonic-gate
18517c478bd9Sstevel@tonic-gate return (IBT_CM_ACCEPT);
18527c478bd9Sstevel@tonic-gate }
18537c478bd9Sstevel@tonic-gate
18547c478bd9Sstevel@tonic-gate
18557c478bd9Sstevel@tonic-gate /* Validate the input UD destination attributes. */
18567c478bd9Sstevel@tonic-gate static ibt_status_t
ibcm_validate_dqpn_data(ibt_ud_dest_attr_t * attr,ibt_execution_mode_t mode,ibt_ud_returns_t * ret_args)18577c478bd9Sstevel@tonic-gate ibcm_validate_dqpn_data(ibt_ud_dest_attr_t *attr, ibt_execution_mode_t mode,
18587c478bd9Sstevel@tonic-gate ibt_ud_returns_t *ret_args)
18597c478bd9Sstevel@tonic-gate {
18607c478bd9Sstevel@tonic-gate /* cm handler must always be specified */
18617c478bd9Sstevel@tonic-gate if (mode == IBT_NONBLOCKING && attr->ud_cm_handler == NULL) {
18627c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_validate_dqpn_data: "
18637c478bd9Sstevel@tonic-gate "CM handler is not specified ");
18647c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
18657c478bd9Sstevel@tonic-gate }
18667c478bd9Sstevel@tonic-gate
18677c478bd9Sstevel@tonic-gate if (mode == IBT_NONBLOCKING) {
18687c478bd9Sstevel@tonic-gate if (ret_args != NULL) {
18697c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_validate_dqpn_data: "
18707c478bd9Sstevel@tonic-gate "ret_args should be NULL when called in "
18717c478bd9Sstevel@tonic-gate "non-blocking mode");
18727c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
18737c478bd9Sstevel@tonic-gate }
18747c478bd9Sstevel@tonic-gate } else if (mode == IBT_BLOCKING) {
18757c478bd9Sstevel@tonic-gate if (ret_args == NULL) {
18767c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_validate_dqpn_data: "
18777c478bd9Sstevel@tonic-gate "ret_args should be Non-NULL when called in "
18787c478bd9Sstevel@tonic-gate "blocking mode");
18797c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
18807c478bd9Sstevel@tonic-gate }
18817c478bd9Sstevel@tonic-gate } else {
18827c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_validate_dqpn_data: "
18837c478bd9Sstevel@tonic-gate "invalid mode %x specified ", mode);
18847c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
18857c478bd9Sstevel@tonic-gate }
18867c478bd9Sstevel@tonic-gate
18877c478bd9Sstevel@tonic-gate if (attr->ud_sid == 0) {
18887c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_validate_dqpn_data: "
18897c478bd9Sstevel@tonic-gate "ServiceID must be specified. ");
18907c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
18917c478bd9Sstevel@tonic-gate }
18927c478bd9Sstevel@tonic-gate
18937c478bd9Sstevel@tonic-gate if (attr->ud_addr == NULL) {
18947c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_validate_dqpn_data: "
18957c478bd9Sstevel@tonic-gate "Address Info NULL");
18967c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
18977c478bd9Sstevel@tonic-gate }
18987c478bd9Sstevel@tonic-gate
18997c478bd9Sstevel@tonic-gate /* Validate SGID */
19007c478bd9Sstevel@tonic-gate if ((attr->ud_addr->av_sgid.gid_prefix == 0) ||
19017c478bd9Sstevel@tonic-gate (attr->ud_addr->av_sgid.gid_guid == 0)) {
19027c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_validate_dqpn_data: Invalid SGID");
19037c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
19047c478bd9Sstevel@tonic-gate }
19057c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_validate_dqpn_data: SGID<%llX:%llX>",
19067c478bd9Sstevel@tonic-gate attr->ud_addr->av_sgid.gid_prefix,
19077c478bd9Sstevel@tonic-gate attr->ud_addr->av_sgid.gid_guid);
19087c478bd9Sstevel@tonic-gate
19097c478bd9Sstevel@tonic-gate /* Validate DGID */
19107c478bd9Sstevel@tonic-gate if ((attr->ud_addr->av_dgid.gid_prefix == 0) ||
19117c478bd9Sstevel@tonic-gate (attr->ud_addr->av_dgid.gid_guid == 0)) {
19127c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_validate_dqpn_data: Invalid DGID");
19137c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
19147c478bd9Sstevel@tonic-gate }
19157c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_validate_dqpn_data: DGID<%llX:%llX>",
19167c478bd9Sstevel@tonic-gate attr->ud_addr->av_dgid.gid_prefix,
19177c478bd9Sstevel@tonic-gate attr->ud_addr->av_dgid.gid_guid);
19187c478bd9Sstevel@tonic-gate
19197c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
19207c478bd9Sstevel@tonic-gate }
19217c478bd9Sstevel@tonic-gate
19227c478bd9Sstevel@tonic-gate
19237c478bd9Sstevel@tonic-gate /* Perform SIDR to retrieve DQPN and QKey. */
19247c478bd9Sstevel@tonic-gate static ibt_status_t
ibcm_ud_get_dqpn(ibt_ud_dest_attr_t * attr,ibt_execution_mode_t mode,ibt_ud_returns_t * ret_args)19257c478bd9Sstevel@tonic-gate ibcm_ud_get_dqpn(ibt_ud_dest_attr_t *attr, ibt_execution_mode_t mode,
19267c478bd9Sstevel@tonic-gate ibt_ud_returns_t *ret_args)
19277c478bd9Sstevel@tonic-gate {
19287c478bd9Sstevel@tonic-gate ibt_status_t retval;
19297c478bd9Sstevel@tonic-gate ib_pkey_t ud_pkey;
19307c478bd9Sstevel@tonic-gate ibmf_handle_t ibmf_hdl;
19317c478bd9Sstevel@tonic-gate ibmf_msg_t *ibmf_msg;
19327c478bd9Sstevel@tonic-gate ibcm_hca_info_t *hcap;
19337c478bd9Sstevel@tonic-gate ibcm_sidr_req_msg_t *sidr_req_msgp;
19347c478bd9Sstevel@tonic-gate ibcm_ud_state_data_t *ud_statep;
19357c478bd9Sstevel@tonic-gate ibtl_cm_hca_port_t port;
19367c478bd9Sstevel@tonic-gate ibcm_sidr_srch_t sidr_entry;
19377c478bd9Sstevel@tonic-gate ibcm_qp_list_t *cm_qp_entry;
19387c478bd9Sstevel@tonic-gate
19397c478bd9Sstevel@tonic-gate /* Retrieve HCA GUID value from the available SGID info. */
19407c478bd9Sstevel@tonic-gate retval = ibtl_cm_get_hca_port(attr->ud_addr->av_sgid, 0, &port);
19417c478bd9Sstevel@tonic-gate if ((retval != IBT_SUCCESS) || (port.hp_port == 0)) {
19427c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: "
19437c478bd9Sstevel@tonic-gate "ibtl_cm_get_hca_port failed: %d", retval);
19447c478bd9Sstevel@tonic-gate return (retval);
19457c478bd9Sstevel@tonic-gate }
19467c478bd9Sstevel@tonic-gate
19477c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: "
19487c478bd9Sstevel@tonic-gate "HCA GUID:%llX, port_num:%d", port.hp_hca_guid, port.hp_port);
19497c478bd9Sstevel@tonic-gate
19507c478bd9Sstevel@tonic-gate /* Lookup the HCA info for this GUID */
19517c478bd9Sstevel@tonic-gate if ((hcap = ibcm_find_hca_entry(port.hp_hca_guid)) == NULL) {
19527c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: hcap is NULL");
19537c478bd9Sstevel@tonic-gate return (IBT_HCA_INVALID);
19547c478bd9Sstevel@tonic-gate }
19557c478bd9Sstevel@tonic-gate
19567c478bd9Sstevel@tonic-gate /* Return failure if the HCA device or Port is not operational */
19577c478bd9Sstevel@tonic-gate
19587c478bd9Sstevel@tonic-gate if ((retval = ibt_get_port_state_byguid(port.hp_hca_guid, port.hp_port,
19597c478bd9Sstevel@tonic-gate NULL, NULL)) != IBT_SUCCESS) {
19607c478bd9Sstevel@tonic-gate /* Device Port is not in good state, don't use it. */
19617c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: Invalid "
19627c478bd9Sstevel@tonic-gate "port specified or port not active");
19637c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
19647c478bd9Sstevel@tonic-gate return (retval);
19657c478bd9Sstevel@tonic-gate }
19667c478bd9Sstevel@tonic-gate
19677c478bd9Sstevel@tonic-gate retval = ibt_index2pkey_byguid(port.hp_hca_guid, port.hp_port,
19687c478bd9Sstevel@tonic-gate attr->ud_pkey_ix, &ud_pkey);
19697c478bd9Sstevel@tonic-gate if (retval != IBT_SUCCESS) {
19707c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: "
19717c478bd9Sstevel@tonic-gate "Failed to convert index2pkey: %d", retval);
19727c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
19737c478bd9Sstevel@tonic-gate return (retval);
19747c478bd9Sstevel@tonic-gate }
19757c478bd9Sstevel@tonic-gate
19767c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(sidr_entry))
19777c478bd9Sstevel@tonic-gate
19787c478bd9Sstevel@tonic-gate /* Allocate a new request id */
19797c478bd9Sstevel@tonic-gate if (ibcm_alloc_reqid(hcap, &sidr_entry.srch_req_id) == IBCM_FAILURE) {
19807c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: "
19817c478bd9Sstevel@tonic-gate "no req id available");
19827c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
19837c478bd9Sstevel@tonic-gate return (IBT_INSUFF_KERNEL_RESOURCE);
19847c478bd9Sstevel@tonic-gate }
19857c478bd9Sstevel@tonic-gate
19867c478bd9Sstevel@tonic-gate if ((hcap->hca_port_info[port.hp_port - 1].port_ibmf_hdl == NULL) &&
19877c478bd9Sstevel@tonic-gate ((retval = ibcm_hca_reinit_port(hcap, port.hp_port - 1))
19887c478bd9Sstevel@tonic-gate != IBT_SUCCESS)) {
19897c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: "
19907c478bd9Sstevel@tonic-gate "ibmf reg or callback setup failed during re-initialize");
19917c478bd9Sstevel@tonic-gate return (retval);
19927c478bd9Sstevel@tonic-gate }
19937c478bd9Sstevel@tonic-gate
19947c478bd9Sstevel@tonic-gate ibmf_hdl = hcap->hca_port_info[port.hp_port - 1].port_ibmf_hdl;
19957c478bd9Sstevel@tonic-gate
19967c478bd9Sstevel@tonic-gate /* find the ibmf QP to post the SIDR REQ */
19977c478bd9Sstevel@tonic-gate if ((cm_qp_entry = ibcm_find_qp(hcap, port.hp_port, ud_pkey)) ==
19987c478bd9Sstevel@tonic-gate NULL) {
19997c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: IBMF QP allocation"
20007c478bd9Sstevel@tonic-gate " failed");
20017c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
20027c478bd9Sstevel@tonic-gate return (IBT_INSUFF_RESOURCE);
20037c478bd9Sstevel@tonic-gate }
20047c478bd9Sstevel@tonic-gate
20057c478bd9Sstevel@tonic-gate if ((retval = ibcm_alloc_out_msg(ibmf_hdl, &ibmf_msg, MAD_METHOD_SEND))
20067c478bd9Sstevel@tonic-gate != IBT_SUCCESS) {
20077c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: IBMF MSG allocation"
20087c478bd9Sstevel@tonic-gate " failed");
20097c478bd9Sstevel@tonic-gate ibcm_release_qp(cm_qp_entry);
20107c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
20117c478bd9Sstevel@tonic-gate return (retval);
20127c478bd9Sstevel@tonic-gate }
20137c478bd9Sstevel@tonic-gate
20147c478bd9Sstevel@tonic-gate sidr_entry.srch_lid = port.hp_base_lid;
20157c478bd9Sstevel@tonic-gate sidr_entry.srch_gid = attr->ud_addr->av_sgid;
20167c478bd9Sstevel@tonic-gate sidr_entry.srch_grh_exists = attr->ud_addr->av_send_grh;
20177c478bd9Sstevel@tonic-gate sidr_entry.srch_mode = IBCM_ACTIVE_MODE;
20187c478bd9Sstevel@tonic-gate
20197c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(sidr_entry))
20207c478bd9Sstevel@tonic-gate
20217c478bd9Sstevel@tonic-gate /* do various allocations needed here */
20227c478bd9Sstevel@tonic-gate rw_enter(&hcap->hca_sidr_list_lock, RW_WRITER);
20237c478bd9Sstevel@tonic-gate
20247c478bd9Sstevel@tonic-gate (void) ibcm_find_sidr_entry(&sidr_entry, hcap, &ud_statep,
20257c478bd9Sstevel@tonic-gate IBCM_FLAG_ADD);
20267c478bd9Sstevel@tonic-gate rw_exit(&hcap->hca_sidr_list_lock);
20277c478bd9Sstevel@tonic-gate
20287c478bd9Sstevel@tonic-gate /* Increment hca's resource count */
20297c478bd9Sstevel@tonic-gate ibcm_inc_hca_res_cnt(hcap);
20307c478bd9Sstevel@tonic-gate
20317c478bd9Sstevel@tonic-gate /* After a resource created on hca, no need to hold the acc cnt */
20327c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
20337c478bd9Sstevel@tonic-gate
20347c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ud_statep))
20357c478bd9Sstevel@tonic-gate
20367c478bd9Sstevel@tonic-gate /* Initialize some ud_statep fields */
20377c478bd9Sstevel@tonic-gate ud_statep->ud_stored_msg = ibmf_msg;
20387c478bd9Sstevel@tonic-gate ud_statep->ud_svc_id = attr->ud_sid;
20397c478bd9Sstevel@tonic-gate ud_statep->ud_pkt_life_time =
20407c478bd9Sstevel@tonic-gate ibt_ib2usec(attr->ud_pkt_lt);
20417c478bd9Sstevel@tonic-gate ud_statep->ud_stored_reply_addr.cm_qp_entry = cm_qp_entry;
20427c478bd9Sstevel@tonic-gate
20437c478bd9Sstevel@tonic-gate /* set remaining retry cnt */
20447c478bd9Sstevel@tonic-gate ud_statep->ud_remaining_retry_cnt = ud_statep->ud_max_cm_retries;
20457c478bd9Sstevel@tonic-gate
20467c478bd9Sstevel@tonic-gate /*
20477c478bd9Sstevel@tonic-gate * Get UD handler and corresponding args which is pass it back
20487c478bd9Sstevel@tonic-gate * as first argument for the handler.
20497c478bd9Sstevel@tonic-gate */
20507c478bd9Sstevel@tonic-gate ud_statep->ud_state_cm_private = attr->ud_cm_private;
20517c478bd9Sstevel@tonic-gate
20527c478bd9Sstevel@tonic-gate if (mode == IBT_BLOCKING)
20537c478bd9Sstevel@tonic-gate ud_statep->ud_return_data = ret_args;
20547c478bd9Sstevel@tonic-gate else
20557c478bd9Sstevel@tonic-gate ud_statep->ud_cm_handler = attr->ud_cm_handler;
20567c478bd9Sstevel@tonic-gate
20577c478bd9Sstevel@tonic-gate /* Initialize the fields of ud_statep->ud_stored_reply_addr */
20587c478bd9Sstevel@tonic-gate ud_statep->ud_stored_reply_addr.grh_exists = attr->ud_addr->av_send_grh;
20597c478bd9Sstevel@tonic-gate ud_statep->ud_stored_reply_addr.ibmf_hdl = ibmf_hdl;
20607c478bd9Sstevel@tonic-gate ud_statep->ud_stored_reply_addr.grh_hdr.ig_hop_limit =
20617c478bd9Sstevel@tonic-gate attr->ud_addr->av_hop;
20627c478bd9Sstevel@tonic-gate ud_statep->ud_stored_reply_addr.grh_hdr.ig_sender_gid =
20637c478bd9Sstevel@tonic-gate attr->ud_addr->av_sgid;
20647c478bd9Sstevel@tonic-gate ud_statep->ud_stored_reply_addr.grh_hdr.ig_recver_gid =
20657c478bd9Sstevel@tonic-gate attr->ud_addr->av_dgid;
20667c478bd9Sstevel@tonic-gate ud_statep->ud_stored_reply_addr.grh_hdr.ig_tclass =
20677c478bd9Sstevel@tonic-gate attr->ud_addr->av_tclass;
20687c478bd9Sstevel@tonic-gate ud_statep->ud_stored_reply_addr.grh_hdr.ig_flow_label =
20697c478bd9Sstevel@tonic-gate attr->ud_addr->av_flow & IB_GRH_FLOW_LABEL_MASK;
20707c478bd9Sstevel@tonic-gate
20717c478bd9Sstevel@tonic-gate /* needs to be derived based on the base LID and path bits */
20727c478bd9Sstevel@tonic-gate ud_statep->ud_stored_reply_addr.rcvd_addr.ia_local_lid =
20737c478bd9Sstevel@tonic-gate port.hp_base_lid;
20747c478bd9Sstevel@tonic-gate ud_statep->ud_stored_reply_addr.rcvd_addr.ia_remote_lid =
20757c478bd9Sstevel@tonic-gate attr->ud_addr->av_dlid;
20767c478bd9Sstevel@tonic-gate ud_statep->ud_stored_reply_addr.rcvd_addr.ia_p_key = ud_pkey;
20777c478bd9Sstevel@tonic-gate ud_statep->ud_stored_reply_addr.rcvd_addr.ia_q_key = IB_GSI_QKEY;
20787c478bd9Sstevel@tonic-gate ud_statep->ud_stored_reply_addr.rcvd_addr.ia_service_level =
20797c478bd9Sstevel@tonic-gate attr->ud_addr->av_srvl;
20807c478bd9Sstevel@tonic-gate
20817c478bd9Sstevel@tonic-gate /*
20827c478bd9Sstevel@tonic-gate * This may be enchanced later, to use a remote qno based on past
20837c478bd9Sstevel@tonic-gate * redirect rej mad responses. This would be the place to specify
20847c478bd9Sstevel@tonic-gate * appropriate remote qno
20857c478bd9Sstevel@tonic-gate */
20867c478bd9Sstevel@tonic-gate ud_statep->ud_stored_reply_addr.rcvd_addr.ia_remote_qno = 1;
20877c478bd9Sstevel@tonic-gate
20887c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sidr_req_msgp))
20897c478bd9Sstevel@tonic-gate
20907c478bd9Sstevel@tonic-gate /* Initialize the SIDR REQ message fields */
20917c478bd9Sstevel@tonic-gate sidr_req_msgp =
20927c478bd9Sstevel@tonic-gate (ibcm_sidr_req_msg_t *)IBCM_OUT_MSGP(ud_statep->ud_stored_msg);
20937c478bd9Sstevel@tonic-gate
20947c478bd9Sstevel@tonic-gate sidr_req_msgp->sidr_req_request_id = h2b32(ud_statep->ud_req_id);
20957c478bd9Sstevel@tonic-gate sidr_req_msgp->sidr_req_service_id = h2b64(attr->ud_sid);
20967c478bd9Sstevel@tonic-gate sidr_req_msgp->sidr_req_pkey = h2b16(ud_pkey);
20977c478bd9Sstevel@tonic-gate IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->AttributeID =
20987c478bd9Sstevel@tonic-gate h2b16(IBCM_INCOMING_SIDR_REQ + IBCM_ATTR_BASE_ID);
20997c478bd9Sstevel@tonic-gate
21007c478bd9Sstevel@tonic-gate if ((attr->ud_priv_data != NULL) && (attr->ud_priv_data_len > 0)) {
21017c478bd9Sstevel@tonic-gate bcopy(attr->ud_priv_data, sidr_req_msgp->sidr_req_private_data,
21027c478bd9Sstevel@tonic-gate min(attr->ud_priv_data_len, IBT_SIDR_REQ_PRIV_DATA_SZ));
21037c478bd9Sstevel@tonic-gate }
21047c478bd9Sstevel@tonic-gate
21057c478bd9Sstevel@tonic-gate /* Send out the SIDR REQ message */
21067c478bd9Sstevel@tonic-gate ud_statep->ud_state = IBCM_STATE_SIDR_REQ_SENT;
21077c478bd9Sstevel@tonic-gate ud_statep->ud_timer_stored_state = IBCM_STATE_SIDR_REQ_SENT;
21087c478bd9Sstevel@tonic-gate IBCM_UD_REF_CNT_INCR(ud_statep); /* for non-blocking SIDR REQ post */
21097c478bd9Sstevel@tonic-gate ud_statep->ud_timer_value = ibt_ib2usec(ibcm_max_sidr_rep_proctime) +
21107c478bd9Sstevel@tonic-gate (ud_statep->ud_pkt_life_time * 2);
21117c478bd9Sstevel@tonic-gate
21127c478bd9Sstevel@tonic-gate IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->TransactionID =
21137c478bd9Sstevel@tonic-gate h2b64(ibcm_generate_tranid(IBCM_INCOMING_SIDR_REQ,
21147c478bd9Sstevel@tonic-gate ud_statep->ud_req_id, 0));
21157c478bd9Sstevel@tonic-gate
21167c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: timer_value in HZ = %x",
21177c478bd9Sstevel@tonic-gate ud_statep->ud_timer_value);
21187c478bd9Sstevel@tonic-gate
21197c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ud_statep))
21207c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*sidr_req_msgp))
21217c478bd9Sstevel@tonic-gate
21227c478bd9Sstevel@tonic-gate ibcm_post_ud_mad(ud_statep, ud_statep->ud_stored_msg,
21237c478bd9Sstevel@tonic-gate ibcm_post_sidr_req_complete, ud_statep);
21247c478bd9Sstevel@tonic-gate
21257c478bd9Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
21267c478bd9Sstevel@tonic-gate
21277c478bd9Sstevel@tonic-gate /* Wait for SIDR_REP */
21287c478bd9Sstevel@tonic-gate if (mode == IBT_BLOCKING) {
21297c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: blocking");
21307c478bd9Sstevel@tonic-gate
21317c478bd9Sstevel@tonic-gate while (ud_statep->ud_blocking_done != B_TRUE) {
21327c478bd9Sstevel@tonic-gate cv_wait(&ud_statep->ud_block_client_cv,
21337c478bd9Sstevel@tonic-gate &ud_statep->ud_state_mutex);
21347c478bd9Sstevel@tonic-gate }
21357c478bd9Sstevel@tonic-gate
21367c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: finished blocking");
21377c478bd9Sstevel@tonic-gate
21387c478bd9Sstevel@tonic-gate if (ret_args->ud_status == IBT_CM_SREP_QPN_VALID) {
21397c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: DQPN = %x, "
21407c478bd9Sstevel@tonic-gate "status = %x, QKey = %x", ret_args->ud_dqpn,
21417c478bd9Sstevel@tonic-gate ret_args->ud_status, ret_args->ud_qkey);
21427c478bd9Sstevel@tonic-gate
21437c478bd9Sstevel@tonic-gate } else {
21447c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: Status<%x>",
21457c478bd9Sstevel@tonic-gate ret_args->ud_status);
21467c478bd9Sstevel@tonic-gate retval = IBT_CM_FAILURE;
21477c478bd9Sstevel@tonic-gate }
21487c478bd9Sstevel@tonic-gate }
21497c478bd9Sstevel@tonic-gate
21507c478bd9Sstevel@tonic-gate IBCM_UD_REF_CNT_DECR(ud_statep);
21517c478bd9Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
21527c478bd9Sstevel@tonic-gate
21537c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: done");
21547c478bd9Sstevel@tonic-gate
21557c478bd9Sstevel@tonic-gate return (retval);
21567c478bd9Sstevel@tonic-gate }
21577c478bd9Sstevel@tonic-gate
21587c478bd9Sstevel@tonic-gate
21597c478bd9Sstevel@tonic-gate /*
21607c478bd9Sstevel@tonic-gate * Function:
21617c478bd9Sstevel@tonic-gate * ibt_request_ud_dest
21627c478bd9Sstevel@tonic-gate * Input:
21637c478bd9Sstevel@tonic-gate * ud_dest A previously allocated UD destination handle.
21647c478bd9Sstevel@tonic-gate * mode This function can execute in blocking or non blocking
21657c478bd9Sstevel@tonic-gate * modes.
21667c478bd9Sstevel@tonic-gate * attr UD destination attributes to be modified.
21677c478bd9Sstevel@tonic-gate * Output:
21687c478bd9Sstevel@tonic-gate * ud_ret_args If the function is called in blocking mode, ud_ret_args
21697c478bd9Sstevel@tonic-gate * should be a pointer to an ibt_ud_returns_t struct.
21707c478bd9Sstevel@tonic-gate * Returns:
21717c478bd9Sstevel@tonic-gate * IBT_SUCCESS
21727c478bd9Sstevel@tonic-gate * Description:
21737c478bd9Sstevel@tonic-gate * Modify a previously allocated UD destination handle based on the
21747c478bd9Sstevel@tonic-gate * results of doing the SIDR protocol.
21757c478bd9Sstevel@tonic-gate */
21767c478bd9Sstevel@tonic-gate ibt_status_t
ibt_request_ud_dest(ibt_ud_dest_hdl_t ud_dest,ibt_execution_mode_t mode,ibt_ud_dest_attr_t * attr,ibt_ud_returns_t * ud_ret_args)21777c478bd9Sstevel@tonic-gate ibt_request_ud_dest(ibt_ud_dest_hdl_t ud_dest, ibt_execution_mode_t mode,
21787c478bd9Sstevel@tonic-gate ibt_ud_dest_attr_t *attr, ibt_ud_returns_t *ud_ret_args)
21797c478bd9Sstevel@tonic-gate {
21807c478bd9Sstevel@tonic-gate ibt_status_t retval;
21817c478bd9Sstevel@tonic-gate ibt_ud_dest_t *ud_destp;
21827c478bd9Sstevel@tonic-gate ibcm_local_handler_t *local_handler_priv = NULL;
21837c478bd9Sstevel@tonic-gate
21847c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_request_ud_dest(%p, %x, %p, %p)",
21857c478bd9Sstevel@tonic-gate ud_dest, mode, attr, ud_ret_args);
21867c478bd9Sstevel@tonic-gate
21877c478bd9Sstevel@tonic-gate retval = ibcm_validate_dqpn_data(attr, mode, ud_ret_args);
21887c478bd9Sstevel@tonic-gate if (retval != IBT_SUCCESS) {
21897c478bd9Sstevel@tonic-gate return (retval);
21907c478bd9Sstevel@tonic-gate }
21917c478bd9Sstevel@tonic-gate
21927c478bd9Sstevel@tonic-gate ud_destp = ud_dest;
21937c478bd9Sstevel@tonic-gate
21947c478bd9Sstevel@tonic-gate /* Allocate an Address handle. */
21957c478bd9Sstevel@tonic-gate retval = ibt_modify_ah(ud_destp->ud_dest_hca, ud_destp->ud_ah,
21967c478bd9Sstevel@tonic-gate attr->ud_addr);
21977c478bd9Sstevel@tonic-gate if (retval != IBT_SUCCESS) {
21987c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_request_ud_dest: "
21997c478bd9Sstevel@tonic-gate "Address Handle Modification failed: %d", retval);
22007c478bd9Sstevel@tonic-gate return (retval);
22017c478bd9Sstevel@tonic-gate }
22027c478bd9Sstevel@tonic-gate
22037c478bd9Sstevel@tonic-gate if (mode == IBT_NONBLOCKING) {
22047c478bd9Sstevel@tonic-gate /*
22057c478bd9Sstevel@tonic-gate * In NON-BLOCKING mode, and we need to update the destination
22067c478bd9Sstevel@tonic-gate * handle with the DQPN and QKey that are obtained from
22077c478bd9Sstevel@tonic-gate * SIDR REP, hook-up our own handler, so that we can catch
22087c478bd9Sstevel@tonic-gate * the event, and we ourselves call the actual client's
22097c478bd9Sstevel@tonic-gate * ud_cm_handler, in our handler.
22107c478bd9Sstevel@tonic-gate */
22117c478bd9Sstevel@tonic-gate
22127c478bd9Sstevel@tonic-gate /* Allocate memory for local handler's private data. */
22137c478bd9Sstevel@tonic-gate local_handler_priv =
22147c478bd9Sstevel@tonic-gate kmem_alloc(sizeof (*local_handler_priv), KM_SLEEP);
22157c478bd9Sstevel@tonic-gate
22167c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*local_handler_priv))
22177c478bd9Sstevel@tonic-gate
22187c478bd9Sstevel@tonic-gate local_handler_priv->actual_cm_handler = attr->ud_cm_handler;
22197c478bd9Sstevel@tonic-gate local_handler_priv->actual_cm_private = attr->ud_cm_private;
22207c478bd9Sstevel@tonic-gate local_handler_priv->dest_hdl = ud_destp;
22217c478bd9Sstevel@tonic-gate
22227c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*local_handler_priv))
22237c478bd9Sstevel@tonic-gate
22247c478bd9Sstevel@tonic-gate attr->ud_cm_handler = ibcm_local_cm_handler;
22257c478bd9Sstevel@tonic-gate attr->ud_cm_private = local_handler_priv;
22267c478bd9Sstevel@tonic-gate }
22277c478bd9Sstevel@tonic-gate
22287c478bd9Sstevel@tonic-gate /* In order to get DQPN and Destination QKey, perform SIDR */
22297c478bd9Sstevel@tonic-gate retval = ibcm_ud_get_dqpn(attr, mode, ud_ret_args);
22307c478bd9Sstevel@tonic-gate if (retval != IBT_SUCCESS) {
22317c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_request_ud_dest: "
22327c478bd9Sstevel@tonic-gate "Failed to get DQPN: %d", retval);
22337c478bd9Sstevel@tonic-gate
22347c478bd9Sstevel@tonic-gate /* Free memory allocated for local handler's private data. */
22357c478bd9Sstevel@tonic-gate if (local_handler_priv != NULL)
22367c478bd9Sstevel@tonic-gate kmem_free(local_handler_priv,
22377c478bd9Sstevel@tonic-gate sizeof (*local_handler_priv));
22387c478bd9Sstevel@tonic-gate return (retval);
22397c478bd9Sstevel@tonic-gate }
22407c478bd9Sstevel@tonic-gate
22417c478bd9Sstevel@tonic-gate /*
22427c478bd9Sstevel@tonic-gate * Fill in the dqpn and dqkey as obtained from ud_ret_args,
22437c478bd9Sstevel@tonic-gate * values will be valid only on BLOCKING mode.
22447c478bd9Sstevel@tonic-gate */
22457c478bd9Sstevel@tonic-gate if (mode == IBT_BLOCKING) {
22467c478bd9Sstevel@tonic-gate ud_destp->ud_dst_qpn = ud_ret_args->ud_dqpn;
22477c478bd9Sstevel@tonic-gate ud_destp->ud_qkey = ud_ret_args->ud_qkey;
22487c478bd9Sstevel@tonic-gate }
22497c478bd9Sstevel@tonic-gate
22507c478bd9Sstevel@tonic-gate return (retval);
22517c478bd9Sstevel@tonic-gate }
22527c478bd9Sstevel@tonic-gate
22537c478bd9Sstevel@tonic-gate /*
22547c478bd9Sstevel@tonic-gate * Function:
22557c478bd9Sstevel@tonic-gate * ibt_ud_get_dqpn
22567c478bd9Sstevel@tonic-gate * Input:
22577c478bd9Sstevel@tonic-gate * attr A pointer to an ibt_ud_dest_attr_t struct that are
22587c478bd9Sstevel@tonic-gate * required for SIDR REQ message. Not specified attributes
22597c478bd9Sstevel@tonic-gate * should be set to "NULL" or "0".
22607c478bd9Sstevel@tonic-gate * ud_sid, ud_addr and ud_pkt_lt must be specified.
22617c478bd9Sstevel@tonic-gate * mode This function can execute in blocking or non blocking
22627c478bd9Sstevel@tonic-gate * modes.
22637c478bd9Sstevel@tonic-gate * Output:
22647c478bd9Sstevel@tonic-gate * returns If the function is called in blocking mode, returns
22657c478bd9Sstevel@tonic-gate * should be a pointer to an ibt_ud_returns_t struct.
22667c478bd9Sstevel@tonic-gate * Return:
22677c478bd9Sstevel@tonic-gate * IBT_SUCCESS on success or respective failure on error.
22687c478bd9Sstevel@tonic-gate * Description:
22697c478bd9Sstevel@tonic-gate * Finds the destination QPN at the specified destination that the
22707c478bd9Sstevel@tonic-gate * specified service can be reached on. The IBTF CM initiates the
22717c478bd9Sstevel@tonic-gate * service ID resolution protocol (SIDR) to determine a destination QPN.
22727c478bd9Sstevel@tonic-gate *
22737c478bd9Sstevel@tonic-gate * NOTE: SIDR_REQ is initiated from active side.
22747c478bd9Sstevel@tonic-gate */
22757c478bd9Sstevel@tonic-gate ibt_status_t
ibt_ud_get_dqpn(ibt_ud_dest_attr_t * attr,ibt_execution_mode_t mode,ibt_ud_returns_t * returns)22767c478bd9Sstevel@tonic-gate ibt_ud_get_dqpn(ibt_ud_dest_attr_t *attr, ibt_execution_mode_t mode,
22777c478bd9Sstevel@tonic-gate ibt_ud_returns_t *returns)
22787c478bd9Sstevel@tonic-gate {
22797c478bd9Sstevel@tonic-gate ibt_status_t retval;
22807c478bd9Sstevel@tonic-gate
22817c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_ud_get_dqpn(%p, %x, %p)",
22827c478bd9Sstevel@tonic-gate attr, mode, returns);
22837c478bd9Sstevel@tonic-gate
22847c478bd9Sstevel@tonic-gate retval = ibcm_validate_dqpn_data(attr, mode, returns);
22857c478bd9Sstevel@tonic-gate if (retval != IBT_SUCCESS) {
22867c478bd9Sstevel@tonic-gate return (retval);
22877c478bd9Sstevel@tonic-gate }
22887c478bd9Sstevel@tonic-gate
22897c478bd9Sstevel@tonic-gate return (ibcm_ud_get_dqpn(attr, mode, returns));
22907c478bd9Sstevel@tonic-gate }
22917c478bd9Sstevel@tonic-gate
22927c478bd9Sstevel@tonic-gate
22937c478bd9Sstevel@tonic-gate /*
22947c478bd9Sstevel@tonic-gate * ibt_cm_delay:
22957c478bd9Sstevel@tonic-gate * A client CM handler function can call this function
22967c478bd9Sstevel@tonic-gate * to extend its response time to a CM event.
22977c478bd9Sstevel@tonic-gate * INPUTS:
22987c478bd9Sstevel@tonic-gate * flags Indicates what CM message processing is being delayed
22997c478bd9Sstevel@tonic-gate * by the CM handler, valid values are:
23007c478bd9Sstevel@tonic-gate * IBT_CM_DELAY_REQ
23017c478bd9Sstevel@tonic-gate * IBT_CM_DELAY_REP
23027c478bd9Sstevel@tonic-gate * IBT_CM_DELAY_LAP
23037c478bd9Sstevel@tonic-gate * cm_session_id The session ID that was passed to client srv_handler
23047c478bd9Sstevel@tonic-gate * by the CM
23057c478bd9Sstevel@tonic-gate * service_time The extended service time
23067c478bd9Sstevel@tonic-gate * priv_data Vendor specific data to be sent in the CM generated
23077c478bd9Sstevel@tonic-gate * MRA message. Should be NULL if not specified.
23087c478bd9Sstevel@tonic-gate * len The number of bytes of data specified by priv_data.
23097c478bd9Sstevel@tonic-gate *
23107c478bd9Sstevel@tonic-gate * RETURN VALUES:
23117c478bd9Sstevel@tonic-gate * IBT_SUCCESS on success (or respective failure on error)
23127c478bd9Sstevel@tonic-gate */
23137c478bd9Sstevel@tonic-gate ibt_status_t
ibt_cm_delay(ibt_cmdelay_flags_t flags,void * cm_session_id,clock_t service_time,void * priv_data,ibt_priv_data_len_t len)23147c478bd9Sstevel@tonic-gate ibt_cm_delay(ibt_cmdelay_flags_t flags, void *cm_session_id,
23157c478bd9Sstevel@tonic-gate clock_t service_time, void *priv_data, ibt_priv_data_len_t len)
23167c478bd9Sstevel@tonic-gate {
23177c478bd9Sstevel@tonic-gate uint8_t msg_typ = 0;
23187c478bd9Sstevel@tonic-gate ibcm_mra_msg_t *mra_msgp;
23197c478bd9Sstevel@tonic-gate ibcm_state_data_t *statep;
23207c478bd9Sstevel@tonic-gate ibt_status_t status;
23217c478bd9Sstevel@tonic-gate
23229d3d2ed0Shiremath IBTF_DPRINTF_L3(cmlog, "ibt_cm_delay(0x%x, %p, 0x%x)",
23237c478bd9Sstevel@tonic-gate flags, cm_session_id, service_time);
23247c478bd9Sstevel@tonic-gate
23257c478bd9Sstevel@tonic-gate /*
23267c478bd9Sstevel@tonic-gate * Make sure channel is associated with a statep
23277c478bd9Sstevel@tonic-gate */
23287c478bd9Sstevel@tonic-gate statep = (ibcm_state_data_t *)cm_session_id;
23297c478bd9Sstevel@tonic-gate
23307c478bd9Sstevel@tonic-gate if (statep == NULL) {
23317c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_cm_delay: statep NULL");
23327c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
23337c478bd9Sstevel@tonic-gate }
23347c478bd9Sstevel@tonic-gate
23357c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_cm_delay: statep %p", statep);
23367c478bd9Sstevel@tonic-gate
23377c478bd9Sstevel@tonic-gate /* Allocate an ibmf msg for mra, if not allocated yet */
23387c478bd9Sstevel@tonic-gate if (statep->mra_msg == NULL) {
23397c478bd9Sstevel@tonic-gate if ((status = ibcm_alloc_out_msg(
23407c478bd9Sstevel@tonic-gate statep->stored_reply_addr.ibmf_hdl, &statep->mra_msg,
23417c478bd9Sstevel@tonic-gate MAD_METHOD_SEND)) != IBT_SUCCESS) {
23427c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_cm_delay: chan 0x%p"
23437c478bd9Sstevel@tonic-gate "IBMF MSG allocation failed", statep->channel);
23447c478bd9Sstevel@tonic-gate return (status);
23457c478bd9Sstevel@tonic-gate }
23467c478bd9Sstevel@tonic-gate }
23477c478bd9Sstevel@tonic-gate
23487c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*mra_msgp))
23497c478bd9Sstevel@tonic-gate
23507c478bd9Sstevel@tonic-gate mra_msgp = (ibcm_mra_msg_t *)IBCM_OUT_MSGP(statep->mra_msg);
23517c478bd9Sstevel@tonic-gate mra_msgp->mra_local_comm_id = h2b32(statep->local_comid);
23527c478bd9Sstevel@tonic-gate mra_msgp->mra_remote_comm_id = h2b32(statep->remote_comid);
23537c478bd9Sstevel@tonic-gate
23547c478bd9Sstevel@tonic-gate /* fill in rest of MRA's fields - Message MRAed and Service Timeout */
23557c478bd9Sstevel@tonic-gate if (flags == IBT_CM_DELAY_REQ) {
23567c478bd9Sstevel@tonic-gate msg_typ = IBT_CM_MRA_TYPE_REQ;
23577c478bd9Sstevel@tonic-gate } else if (flags == IBT_CM_DELAY_REP) {
23587c478bd9Sstevel@tonic-gate msg_typ = IBT_CM_MRA_TYPE_REP;
23597c478bd9Sstevel@tonic-gate } else if (flags == IBT_CM_DELAY_LAP) {
23607c478bd9Sstevel@tonic-gate msg_typ = IBT_CM_MRA_TYPE_LAP;
23617c478bd9Sstevel@tonic-gate }
23627c478bd9Sstevel@tonic-gate
23637c478bd9Sstevel@tonic-gate mra_msgp->mra_message_type_plus = msg_typ << 6;
23647c478bd9Sstevel@tonic-gate mra_msgp->mra_service_timeout_plus = ibt_usec2ib(service_time) << 3;
23657c478bd9Sstevel@tonic-gate
23667c478bd9Sstevel@tonic-gate len = min(len, IBT_MRA_PRIV_DATA_SZ);
23677c478bd9Sstevel@tonic-gate if (priv_data && (len > 0))
23687c478bd9Sstevel@tonic-gate bcopy(priv_data, mra_msgp->mra_private_data, len);
23697c478bd9Sstevel@tonic-gate
23707c478bd9Sstevel@tonic-gate IBCM_OUT_HDRP(statep->mra_msg)->AttributeID =
23717c478bd9Sstevel@tonic-gate h2b16(IBCM_INCOMING_MRA + IBCM_ATTR_BASE_ID);
23727c478bd9Sstevel@tonic-gate
23737c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*mra_msgp))
23747c478bd9Sstevel@tonic-gate
23757c478bd9Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
23767c478bd9Sstevel@tonic-gate
23777c478bd9Sstevel@tonic-gate if ((statep->mode == IBCM_ACTIVE_MODE) &&
23787c478bd9Sstevel@tonic-gate (statep->state == IBCM_STATE_REP_RCVD)) {
23797c478bd9Sstevel@tonic-gate statep->state = IBCM_STATE_MRA_REP_SENT;
23807c478bd9Sstevel@tonic-gate } else if (statep->mode == IBCM_PASSIVE_MODE) {
238124b28d04Shiremath if (statep->state == IBCM_STATE_REQ_RCVD) {
23827c478bd9Sstevel@tonic-gate statep->state = IBCM_STATE_MRA_SENT;
238324b28d04Shiremath } else if (statep->ap_state == IBCM_AP_STATE_LAP_RCVD) {
23847c478bd9Sstevel@tonic-gate statep->ap_state = IBCM_AP_STATE_MRA_LAP_RCVD;
238524b28d04Shiremath } else {
238624b28d04Shiremath IBTF_DPRINTF_L2(cmlog, "ibt_cm_delay: invalid state "
238724b28d04Shiremath "/ap_state/mode %x, %x, %x", statep->state,
238824b28d04Shiremath statep->ap_state, statep->mode);
238924b28d04Shiremath mutex_exit(&statep->state_mutex);
239024b28d04Shiremath return (IBT_CHAN_STATE_INVALID);
23917c478bd9Sstevel@tonic-gate }
23927c478bd9Sstevel@tonic-gate } else {
23937c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_cm_delay: invalid state "
23947c478bd9Sstevel@tonic-gate "/ap_state/mode %x, %x, %x", statep->state,
23957c478bd9Sstevel@tonic-gate statep->ap_state, statep->mode);
23967c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
23977c478bd9Sstevel@tonic-gate
23987c478bd9Sstevel@tonic-gate return (IBT_CHAN_STATE_INVALID);
23997c478bd9Sstevel@tonic-gate }
240024b28d04Shiremath /* service time is usecs, stale_clock is nsecs */
2401fde3102fShiremath statep->stale_clock = gethrtime() +
2402fde3102fShiremath (hrtime_t)ibt_ib2usec(ibt_usec2ib(service_time)) * (1000 *
240324b28d04Shiremath statep->max_cm_retries);
24047c478bd9Sstevel@tonic-gate
24057c478bd9Sstevel@tonic-gate statep->send_mad_flags |= IBCM_MRA_POST_BUSY;
24067c478bd9Sstevel@tonic-gate IBCM_REF_CNT_INCR(statep); /* for ibcm_post_mra_complete */
24077c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
24087c478bd9Sstevel@tonic-gate
24097c478bd9Sstevel@tonic-gate IBCM_OUT_HDRP(statep->mra_msg)->TransactionID =
24107c478bd9Sstevel@tonic-gate IBCM_OUT_HDRP(statep->stored_msg)->TransactionID;
24117c478bd9Sstevel@tonic-gate
24127c478bd9Sstevel@tonic-gate /* post the MRA mad in blocking mode, as no timers involved */
24137c478bd9Sstevel@tonic-gate ibcm_post_rc_mad(statep, statep->mra_msg, ibcm_post_mra_complete,
24147c478bd9Sstevel@tonic-gate statep);
24159d3d2ed0Shiremath ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_MRA);
24167c478bd9Sstevel@tonic-gate /* If this message isn't seen then ibt_cm_delay failed */
24179d3d2ed0Shiremath IBTF_DPRINTF_L3(cmlog, "ibt_cm_delay: done !!");
24187c478bd9Sstevel@tonic-gate
24197c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
24207c478bd9Sstevel@tonic-gate }
24217c478bd9Sstevel@tonic-gate
24227c478bd9Sstevel@tonic-gate
24237c478bd9Sstevel@tonic-gate /*
24247c478bd9Sstevel@tonic-gate * ibt_register_service()
24257c478bd9Sstevel@tonic-gate * Register a service with the IBCM
24267c478bd9Sstevel@tonic-gate *
24277c478bd9Sstevel@tonic-gate * INPUTS:
24287c478bd9Sstevel@tonic-gate * ibt_hdl The IBT client handle returned to the client
24297c478bd9Sstevel@tonic-gate * on an ibt_attach() call.
24307c478bd9Sstevel@tonic-gate *
24317c478bd9Sstevel@tonic-gate * srv The address of a ibt_srv_desc_t that describes
24327c478bd9Sstevel@tonic-gate * the service, containing the following:
24337c478bd9Sstevel@tonic-gate *
24347c478bd9Sstevel@tonic-gate * sd_ud_handler The Service CM UD event Handler.
24357c478bd9Sstevel@tonic-gate * sd_handler The Service CM RC/UC/RD event Handler.
24367c478bd9Sstevel@tonic-gate * sd_flags Service flags (peer-to-peer, or not).
24377c478bd9Sstevel@tonic-gate *
24387c478bd9Sstevel@tonic-gate * sid This tells CM if the service is local (sid is 0) or
24397c478bd9Sstevel@tonic-gate * wellknown (sid is the starting service id of the range).
24407c478bd9Sstevel@tonic-gate *
24417c478bd9Sstevel@tonic-gate * num_sids The number of contiguous service-ids to reserve.
24427c478bd9Sstevel@tonic-gate *
24437c478bd9Sstevel@tonic-gate * srv_hdl The address of a service identification handle, used
24447c478bd9Sstevel@tonic-gate * to deregister a service, and to bind GIDs to.
24457c478bd9Sstevel@tonic-gate *
24467c478bd9Sstevel@tonic-gate * ret_sid The address to store the Service ID return value.
24477c478bd9Sstevel@tonic-gate * If num_sids > 1, ret_sid is the first Service ID
24487c478bd9Sstevel@tonic-gate * in the range.
24497c478bd9Sstevel@tonic-gate *
24507c478bd9Sstevel@tonic-gate * ibt_register_service() returns:
24517c478bd9Sstevel@tonic-gate * IBT_SUCCESS - added a service successfully.
24527c478bd9Sstevel@tonic-gate * IBT_INVALID_PARAM - invalid input parameter.
24537c478bd9Sstevel@tonic-gate * IBT_CM_FAILURE - failed to add the service.
24547c478bd9Sstevel@tonic-gate * IBT_CM_SERVICE_EXISTS - service already exists.
24557c478bd9Sstevel@tonic-gate * IBT_INSUFF_KERNEL_RESOURCE - ran out of local service ids (should
24567c478bd9Sstevel@tonic-gate * never happen).
24577c478bd9Sstevel@tonic-gate */
24587c478bd9Sstevel@tonic-gate ibt_status_t
ibt_register_service(ibt_clnt_hdl_t ibt_hdl,ibt_srv_desc_t * srv,ib_svc_id_t sid,int num_sids,ibt_srv_hdl_t * srv_hdl,ib_svc_id_t * ret_sid)24597c478bd9Sstevel@tonic-gate ibt_register_service(ibt_clnt_hdl_t ibt_hdl, ibt_srv_desc_t *srv,
24607c478bd9Sstevel@tonic-gate ib_svc_id_t sid, int num_sids, ibt_srv_hdl_t *srv_hdl, ib_svc_id_t *ret_sid)
24617c478bd9Sstevel@tonic-gate {
24627c478bd9Sstevel@tonic-gate ibcm_svc_info_t *svcinfop;
24637c478bd9Sstevel@tonic-gate
2464d3a82192SShantkumar Hiremath IBTF_DPRINTF_L2(cmlog, "ibt_register_service(%p (%s), %p, 0x%llX, %d)",
2465d3a82192SShantkumar Hiremath ibt_hdl, ibtl_cm_get_clnt_name(ibt_hdl), srv, (longlong_t)sid,
2466d3a82192SShantkumar Hiremath num_sids);
24677c478bd9Sstevel@tonic-gate
24687c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*svcinfop))
24697c478bd9Sstevel@tonic-gate
24707c478bd9Sstevel@tonic-gate *srv_hdl = NULL;
24717c478bd9Sstevel@tonic-gate
24727c478bd9Sstevel@tonic-gate if (num_sids <= 0) {
24737c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_register_service: "
24747c478bd9Sstevel@tonic-gate "Invalid number of service-ids specified (%d)", num_sids);
24757c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
24767c478bd9Sstevel@tonic-gate }
24777c478bd9Sstevel@tonic-gate
24787c478bd9Sstevel@tonic-gate if (sid == 0) {
24797c478bd9Sstevel@tonic-gate if (ret_sid == NULL)
24807c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
24817c478bd9Sstevel@tonic-gate sid = ibcm_alloc_local_sids(num_sids);
24827c478bd9Sstevel@tonic-gate if (sid == 0)
24837c478bd9Sstevel@tonic-gate return (IBT_INSUFF_KERNEL_RESOURCE);
24847c478bd9Sstevel@tonic-gate
24857c478bd9Sstevel@tonic-gate /* Make sure that the ServiceId specified is not of LOCAL AGN type. */
24867c478bd9Sstevel@tonic-gate } else if ((sid & IB_SID_AGN_MASK) == IB_SID_AGN_LOCAL) {
24877c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_register_service: "
24887c478bd9Sstevel@tonic-gate "Invalid non-LOCAL SID specified: 0x%llX",
24897c478bd9Sstevel@tonic-gate (longlong_t)sid);
24907c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
24917c478bd9Sstevel@tonic-gate }
24927c478bd9Sstevel@tonic-gate
24937c478bd9Sstevel@tonic-gate svcinfop = ibcm_create_svc_entry(sid, num_sids);
24947c478bd9Sstevel@tonic-gate
24957c478bd9Sstevel@tonic-gate if (svcinfop == NULL) {
24967c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_register_service: "
24977c478bd9Sstevel@tonic-gate "Service-ID 0x%llx already registered", (longlong_t)sid);
24987c478bd9Sstevel@tonic-gate return (IBT_CM_SERVICE_EXISTS);
24997c478bd9Sstevel@tonic-gate }
25007c478bd9Sstevel@tonic-gate
25017c478bd9Sstevel@tonic-gate /*
25027c478bd9Sstevel@tonic-gate * 'sid' and 'num_sids' are filled in ibcm_create_svc_entry()
25037c478bd9Sstevel@tonic-gate */
25047c478bd9Sstevel@tonic-gate svcinfop->svc_flags = srv->sd_flags;
25057c478bd9Sstevel@tonic-gate svcinfop->svc_rc_handler = srv->sd_handler;
25067c478bd9Sstevel@tonic-gate svcinfop->svc_ud_handler = srv->sd_ud_handler;
25077c478bd9Sstevel@tonic-gate
25087c478bd9Sstevel@tonic-gate if (ret_sid != NULL)
25097c478bd9Sstevel@tonic-gate *ret_sid = sid;
25107c478bd9Sstevel@tonic-gate
25117c478bd9Sstevel@tonic-gate *srv_hdl = svcinfop;
25127c478bd9Sstevel@tonic-gate
25137c478bd9Sstevel@tonic-gate ibtl_cm_change_service_cnt(ibt_hdl, num_sids);
25147c478bd9Sstevel@tonic-gate
25157c478bd9Sstevel@tonic-gate /* If this message isn't seen, then ibt_register_service failed. */
25167c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_register_service: done (%p, %llX)",
25177c478bd9Sstevel@tonic-gate svcinfop, sid);
25187c478bd9Sstevel@tonic-gate
25197c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*svcinfop))
25207c478bd9Sstevel@tonic-gate
25217c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
25227c478bd9Sstevel@tonic-gate }
25237c478bd9Sstevel@tonic-gate
25247c478bd9Sstevel@tonic-gate
25257c478bd9Sstevel@tonic-gate static ibt_status_t
ibcm_write_service_record(ibmf_saa_handle_t saa_handle,sa_service_record_t * srv_recp,ibmf_saa_access_type_t saa_type)25267c478bd9Sstevel@tonic-gate ibcm_write_service_record(ibmf_saa_handle_t saa_handle,
25277c478bd9Sstevel@tonic-gate sa_service_record_t *srv_recp, ibmf_saa_access_type_t saa_type)
25287c478bd9Sstevel@tonic-gate {
25297c478bd9Sstevel@tonic-gate int rval;
25307c478bd9Sstevel@tonic-gate int retry;
25317c478bd9Sstevel@tonic-gate
25327c478bd9Sstevel@tonic-gate ibcm_sa_access_enter();
25337c478bd9Sstevel@tonic-gate for (retry = 0; retry < ibcm_max_sa_retries; retry++) {
25347c478bd9Sstevel@tonic-gate rval = ibmf_saa_update_service_record(
25357c478bd9Sstevel@tonic-gate saa_handle, srv_recp, saa_type, 0);
25367c478bd9Sstevel@tonic-gate if (rval != IBMF_TRANS_TIMEOUT) {
25377c478bd9Sstevel@tonic-gate break;
25387c478bd9Sstevel@tonic-gate }
25397c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_write_service_record: "
25407c478bd9Sstevel@tonic-gate "ibmf_saa_update_service_record timed out"
25417c478bd9Sstevel@tonic-gate " SID = %llX, rval = %d, saa_type = %d",
25427c478bd9Sstevel@tonic-gate (longlong_t)srv_recp->ServiceID, rval, saa_type);
25437c478bd9Sstevel@tonic-gate delay(ibcm_sa_timeout_delay);
25447c478bd9Sstevel@tonic-gate }
25457c478bd9Sstevel@tonic-gate ibcm_sa_access_exit();
25467c478bd9Sstevel@tonic-gate
25477c478bd9Sstevel@tonic-gate if (rval != IBMF_SUCCESS) {
25487c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_write_service_record: "
25497c478bd9Sstevel@tonic-gate "ibmf_saa_update_service_record() : Failed - %d", rval);
25507c478bd9Sstevel@tonic-gate return (ibcm_ibmf_analyze_error(rval));
25517c478bd9Sstevel@tonic-gate } else
25527c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
25537c478bd9Sstevel@tonic-gate }
25547c478bd9Sstevel@tonic-gate
25557c478bd9Sstevel@tonic-gate
25567c478bd9Sstevel@tonic-gate static void
ibcm_rem_stale_srec(ibmf_saa_handle_t saa_handle,sa_service_record_t * srec)25577c478bd9Sstevel@tonic-gate ibcm_rem_stale_srec(ibmf_saa_handle_t saa_handle, sa_service_record_t *srec)
25587c478bd9Sstevel@tonic-gate {
25597c478bd9Sstevel@tonic-gate ibt_status_t retval;
25607c478bd9Sstevel@tonic-gate uint_t num_found;
25617c478bd9Sstevel@tonic-gate size_t length;
25627c478bd9Sstevel@tonic-gate sa_service_record_t *srv_resp;
25637c478bd9Sstevel@tonic-gate void *results_p;
25647c478bd9Sstevel@tonic-gate uint_t i;
25657c478bd9Sstevel@tonic-gate uint64_t component_mask;
25667c478bd9Sstevel@tonic-gate ibmf_saa_access_args_t access_args;
25677c478bd9Sstevel@tonic-gate
25687c478bd9Sstevel@tonic-gate component_mask =
25697c478bd9Sstevel@tonic-gate SA_SR_COMPMASK_PKEY | SA_SR_COMPMASK_NAME | SA_SR_COMPMASK_GID;
25707c478bd9Sstevel@tonic-gate
25717c478bd9Sstevel@tonic-gate /* Call in SA Access retrieve routine to get Service Records. */
25727c478bd9Sstevel@tonic-gate access_args.sq_attr_id = SA_SERVICERECORD_ATTRID;
25737c478bd9Sstevel@tonic-gate access_args.sq_access_type = IBMF_SAA_RETRIEVE;
25747c478bd9Sstevel@tonic-gate access_args.sq_component_mask = component_mask;
25757c478bd9Sstevel@tonic-gate access_args.sq_template = srec;
25767c478bd9Sstevel@tonic-gate access_args.sq_template_length = sizeof (sa_service_record_t);
25777c478bd9Sstevel@tonic-gate access_args.sq_callback = NULL;
25787c478bd9Sstevel@tonic-gate access_args.sq_callback_arg = NULL;
25797c478bd9Sstevel@tonic-gate
25807c478bd9Sstevel@tonic-gate retval = ibcm_contact_sa_access(saa_handle, &access_args, &length,
25817c478bd9Sstevel@tonic-gate &results_p);
25827c478bd9Sstevel@tonic-gate if (retval != IBT_SUCCESS) {
25837c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_rem_stale_srec: "
25847c478bd9Sstevel@tonic-gate "SA Access Failure");
25857c478bd9Sstevel@tonic-gate return;
25867c478bd9Sstevel@tonic-gate }
25877c478bd9Sstevel@tonic-gate
25887c478bd9Sstevel@tonic-gate num_found = length / sizeof (sa_service_record_t);
25897c478bd9Sstevel@tonic-gate
25907c478bd9Sstevel@tonic-gate if (num_found)
25917c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_rem_stale_srec: "
25927c478bd9Sstevel@tonic-gate "Found %d matching Service Records.", num_found);
25937c478bd9Sstevel@tonic-gate
25947c478bd9Sstevel@tonic-gate /* Validate the returned number of records. */
25957c478bd9Sstevel@tonic-gate if ((results_p != NULL) && (num_found > 0)) {
25967c478bd9Sstevel@tonic-gate
25977c478bd9Sstevel@tonic-gate /* Remove all the records. */
25987c478bd9Sstevel@tonic-gate for (i = 0; i < num_found; i++) {
25997c478bd9Sstevel@tonic-gate
26007c478bd9Sstevel@tonic-gate srv_resp = (sa_service_record_t *)
26017c478bd9Sstevel@tonic-gate ((uchar_t *)results_p +
26027c478bd9Sstevel@tonic-gate i * sizeof (sa_service_record_t));
26037c478bd9Sstevel@tonic-gate
26047c478bd9Sstevel@tonic-gate /*
26057c478bd9Sstevel@tonic-gate * Found some matching records, but check out whether
26067c478bd9Sstevel@tonic-gate * this Record is really stale or just happens to match
26077c478bd9Sstevel@tonic-gate * the current session records. If yes, don't remove it.
26087c478bd9Sstevel@tonic-gate */
26097c478bd9Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
26107c478bd9Sstevel@tonic-gate if (ibcm_find_svc_entry(srv_resp->ServiceID) != NULL) {
26117c478bd9Sstevel@tonic-gate /* This record is NOT STALE. */
26127c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
26137c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_rem_stale_srec: "
26147c478bd9Sstevel@tonic-gate "This is not Stale, it's an active record");
26157c478bd9Sstevel@tonic-gate continue;
26167c478bd9Sstevel@tonic-gate }
26177c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
26187c478bd9Sstevel@tonic-gate
26197c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_rem_stale_srec: "
26207c478bd9Sstevel@tonic-gate "Removing Stale Rec: %s, %llX",
26217c478bd9Sstevel@tonic-gate srv_resp->ServiceName, srv_resp->ServiceID);
26227c478bd9Sstevel@tonic-gate
26237c478bd9Sstevel@tonic-gate IBCM_DUMP_SERVICE_REC(srv_resp);
26247c478bd9Sstevel@tonic-gate
26257c478bd9Sstevel@tonic-gate /*
26267c478bd9Sstevel@tonic-gate * Remove the Service Record Entry from SA.
26277c478bd9Sstevel@tonic-gate *
26287c478bd9Sstevel@tonic-gate * Get ServiceID info from Response Buf, other
26297c478bd9Sstevel@tonic-gate * attributes are already filled-in.
26307c478bd9Sstevel@tonic-gate */
26317c478bd9Sstevel@tonic-gate
26327c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(srec->ServiceID))
26337c478bd9Sstevel@tonic-gate
26347c478bd9Sstevel@tonic-gate srec->ServiceID = srv_resp->ServiceID;
26357c478bd9Sstevel@tonic-gate
26367c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(srec->ServiceID))
26377c478bd9Sstevel@tonic-gate
26387c478bd9Sstevel@tonic-gate (void) ibcm_write_service_record(saa_handle, srec,
26397c478bd9Sstevel@tonic-gate IBMF_SAA_DELETE);
26407c478bd9Sstevel@tonic-gate }
26417c478bd9Sstevel@tonic-gate
26427c478bd9Sstevel@tonic-gate /* Deallocate the memory for results_p. */
26437c478bd9Sstevel@tonic-gate kmem_free(results_p, length);
26447c478bd9Sstevel@tonic-gate }
26457c478bd9Sstevel@tonic-gate }
26467c478bd9Sstevel@tonic-gate
26477c478bd9Sstevel@tonic-gate
26487c478bd9Sstevel@tonic-gate
26497c478bd9Sstevel@tonic-gate /*
26507c478bd9Sstevel@tonic-gate * ibt_bind_service()
26517c478bd9Sstevel@tonic-gate * Register a service with the IBCM
26527c478bd9Sstevel@tonic-gate *
26537c478bd9Sstevel@tonic-gate * INPUTS:
26547c478bd9Sstevel@tonic-gate * srv_hdl The service id handle returned to the client
26557c478bd9Sstevel@tonic-gate * on an ibt_service_register() call.
26567c478bd9Sstevel@tonic-gate *
26577c478bd9Sstevel@tonic-gate * gid The GID to which to bind the service.
26587c478bd9Sstevel@tonic-gate *
26597c478bd9Sstevel@tonic-gate * srv_bind The address of a ibt_srv_bind_t that describes
26607c478bd9Sstevel@tonic-gate * the service record. This should be NULL if there
26617c478bd9Sstevel@tonic-gate * is to be no service record. This contains:
26627c478bd9Sstevel@tonic-gate *
26637c478bd9Sstevel@tonic-gate * sb_lease Lease period
26647c478bd9Sstevel@tonic-gate * sb_pkey Partition
26657c478bd9Sstevel@tonic-gate * sb_name pointer to ASCII string Service Name,
26667c478bd9Sstevel@tonic-gate * NULL terminated.
26677c478bd9Sstevel@tonic-gate * sb_key[] Key to secure the service record.
26687c478bd9Sstevel@tonic-gate * sb_data Service Data structure (64-byte)
26697c478bd9Sstevel@tonic-gate *
26707c478bd9Sstevel@tonic-gate * cm_private First argument of Service handler.
26717c478bd9Sstevel@tonic-gate *
26727c478bd9Sstevel@tonic-gate * sb_hdl_p The address of a service bind handle, used
26737c478bd9Sstevel@tonic-gate * to undo the service binding.
26747c478bd9Sstevel@tonic-gate *
26757c478bd9Sstevel@tonic-gate * ibt_bind_service() returns:
26767c478bd9Sstevel@tonic-gate * IBT_SUCCESS - added a service successfully.
26777c478bd9Sstevel@tonic-gate * IBT_INVALID_PARAM - invalid input parameter.
26787c478bd9Sstevel@tonic-gate * IBT_CM_FAILURE - failed to add the service.
26797c478bd9Sstevel@tonic-gate * IBT_CM_SERVICE_EXISTS - service already exists.
26807c478bd9Sstevel@tonic-gate */
26817c478bd9Sstevel@tonic-gate ibt_status_t
ibt_bind_service(ibt_srv_hdl_t srv_hdl,ib_gid_t gid,ibt_srv_bind_t * srv_bind,void * cm_private,ibt_sbind_hdl_t * sb_hdl_p)26827c478bd9Sstevel@tonic-gate ibt_bind_service(ibt_srv_hdl_t srv_hdl, ib_gid_t gid, ibt_srv_bind_t *srv_bind,
26837c478bd9Sstevel@tonic-gate void *cm_private, ibt_sbind_hdl_t *sb_hdl_p)
26847c478bd9Sstevel@tonic-gate {
26857c478bd9Sstevel@tonic-gate ibt_status_t status;
26867c478bd9Sstevel@tonic-gate ibtl_cm_hca_port_t port;
26877c478bd9Sstevel@tonic-gate ibcm_svc_bind_t *sbindp, *sbp;
26887c478bd9Sstevel@tonic-gate ibcm_hca_info_t *hcap;
26897c478bd9Sstevel@tonic-gate ib_svc_id_t sid, start_sid, end_sid;
26907c478bd9Sstevel@tonic-gate ibmf_saa_handle_t saa_handle;
26917c478bd9Sstevel@tonic-gate sa_service_record_t srv_rec;
26927c478bd9Sstevel@tonic-gate uint16_t pkey_ix;
26937c478bd9Sstevel@tonic-gate
26947c478bd9Sstevel@tonic-gate if (sb_hdl_p != NULL)
26957c478bd9Sstevel@tonic-gate *sb_hdl_p = NULL; /* return value for error cases */
26967c478bd9Sstevel@tonic-gate
26977c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: srv_hdl %p, gid (%llX:%llX)",
26987c478bd9Sstevel@tonic-gate srv_hdl, (longlong_t)gid.gid_prefix, (longlong_t)gid.gid_guid);
26997c478bd9Sstevel@tonic-gate
27007c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sbindp))
27017c478bd9Sstevel@tonic-gate
27027c478bd9Sstevel@tonic-gate /* Call ibtl_cm_get_hca_port to get the port number and the HCA GUID. */
27037c478bd9Sstevel@tonic-gate if ((status = ibtl_cm_get_hca_port(gid, 0, &port)) != IBT_SUCCESS) {
27047c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: "
27057c478bd9Sstevel@tonic-gate "ibtl_cm_get_hca_port failed: %d", status);
27067c478bd9Sstevel@tonic-gate return (status);
27077c478bd9Sstevel@tonic-gate }
27087c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_bind_service: Port:%d HCA GUID:%llX",
27097c478bd9Sstevel@tonic-gate port.hp_port, port.hp_hca_guid);
27107c478bd9Sstevel@tonic-gate
27117c478bd9Sstevel@tonic-gate hcap = ibcm_find_hca_entry(port.hp_hca_guid);
27127c478bd9Sstevel@tonic-gate if (hcap == NULL) {
27137c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: NO HCA found");
27147c478bd9Sstevel@tonic-gate return (IBT_HCA_BUSY_DETACHING);
27157c478bd9Sstevel@tonic-gate }
27167c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_bind_service: hcap = %p", hcap);
27177c478bd9Sstevel@tonic-gate
27187c478bd9Sstevel@tonic-gate if (srv_bind != NULL) {
27197c478bd9Sstevel@tonic-gate saa_handle = ibcm_get_saa_handle(hcap, port.hp_port);
27207c478bd9Sstevel@tonic-gate if (saa_handle == NULL) {
27217c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: "
27227c478bd9Sstevel@tonic-gate "saa_handle is NULL");
27237c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
27247c478bd9Sstevel@tonic-gate return (IBT_HCA_PORT_NOT_ACTIVE);
27257c478bd9Sstevel@tonic-gate }
27267c478bd9Sstevel@tonic-gate if (srv_bind->sb_pkey == 0) {
27277c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: "
27287c478bd9Sstevel@tonic-gate "P_Key must not be 0");
27297c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
27307c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
27317c478bd9Sstevel@tonic-gate }
27327c478bd9Sstevel@tonic-gate if (strlen(srv_bind->sb_name) >= IB_SVC_NAME_LEN) {
27337c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: "
27347c478bd9Sstevel@tonic-gate "Service Name is too long");
27357c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
27367c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
27377c478bd9Sstevel@tonic-gate } else
27387c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_bind_service: "
27397c478bd9Sstevel@tonic-gate "Service Name='%s'", srv_bind->sb_name);
27407c478bd9Sstevel@tonic-gate status = ibt_pkey2index_byguid(port.hp_hca_guid,
27417c478bd9Sstevel@tonic-gate port.hp_port, srv_bind->sb_pkey, &pkey_ix);
27427c478bd9Sstevel@tonic-gate if (status != IBT_SUCCESS) {
27437c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: "
27447c478bd9Sstevel@tonic-gate "P_Key 0x%x not found in P_Key_Table",
27457c478bd9Sstevel@tonic-gate srv_bind->sb_pkey);
27467c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
27477c478bd9Sstevel@tonic-gate return (status);
27487c478bd9Sstevel@tonic-gate }
27497c478bd9Sstevel@tonic-gate }
27507c478bd9Sstevel@tonic-gate
27517c478bd9Sstevel@tonic-gate /* assume success - allocate before locking */
27527c478bd9Sstevel@tonic-gate sbindp = kmem_zalloc(sizeof (*sbindp), KM_SLEEP);
27537c478bd9Sstevel@tonic-gate sbindp->sbind_cm_private = cm_private;
27547c478bd9Sstevel@tonic-gate sbindp->sbind_gid = gid;
27557c478bd9Sstevel@tonic-gate sbindp->sbind_hcaguid = port.hp_hca_guid;
27567c478bd9Sstevel@tonic-gate sbindp->sbind_port = port.hp_port;
27577c478bd9Sstevel@tonic-gate
27587c478bd9Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
27597c478bd9Sstevel@tonic-gate
27607c478bd9Sstevel@tonic-gate sbp = srv_hdl->svc_bind_list;
27617c478bd9Sstevel@tonic-gate while (sbp != NULL) {
27627c478bd9Sstevel@tonic-gate if (sbp->sbind_gid.gid_guid == gid.gid_guid &&
27637c478bd9Sstevel@tonic-gate sbp->sbind_gid.gid_prefix == gid.gid_prefix) {
27647c478bd9Sstevel@tonic-gate if (srv_bind == NULL ||
27657c478bd9Sstevel@tonic-gate srv_bind->sb_pkey == sbp->sbind_pkey) {
27667c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: "
2767448978d3Shiremath "failed: GID %llX:%llX and PKEY %x is "
27685c42ea03Shiremath "already bound", gid.gid_prefix,
27695c42ea03Shiremath gid.gid_guid, sbp->sbind_pkey);
27707c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
27717c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
27727c478bd9Sstevel@tonic-gate kmem_free(sbindp, sizeof (*sbindp));
27737c478bd9Sstevel@tonic-gate return (IBT_CM_SERVICE_EXISTS);
27747c478bd9Sstevel@tonic-gate }
27757c478bd9Sstevel@tonic-gate }
27767c478bd9Sstevel@tonic-gate sbp = sbp->sbind_link;
27777c478bd9Sstevel@tonic-gate }
27787c478bd9Sstevel@tonic-gate /* no entry found */
27797c478bd9Sstevel@tonic-gate
27807c478bd9Sstevel@tonic-gate sbindp->sbind_link = srv_hdl->svc_bind_list;
27817c478bd9Sstevel@tonic-gate srv_hdl->svc_bind_list = sbindp;
27827c478bd9Sstevel@tonic-gate
27837c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
27847c478bd9Sstevel@tonic-gate
27857c478bd9Sstevel@tonic-gate if (srv_bind != NULL) {
27867c478bd9Sstevel@tonic-gate bzero(&srv_rec, sizeof (srv_rec));
27877c478bd9Sstevel@tonic-gate
27887c478bd9Sstevel@tonic-gate srv_rec.ServiceLease =
27897c478bd9Sstevel@tonic-gate sbindp->sbind_lease = srv_bind->sb_lease;
27907c478bd9Sstevel@tonic-gate srv_rec.ServiceP_Key =
27917c478bd9Sstevel@tonic-gate sbindp->sbind_pkey = srv_bind->sb_pkey;
27927c478bd9Sstevel@tonic-gate srv_rec.ServiceKey_hi =
27937c478bd9Sstevel@tonic-gate sbindp->sbind_key[0] = srv_bind->sb_key[0];
27947c478bd9Sstevel@tonic-gate srv_rec.ServiceKey_lo =
27957c478bd9Sstevel@tonic-gate sbindp->sbind_key[1] = srv_bind->sb_key[1];
27967c478bd9Sstevel@tonic-gate (void) strcpy(sbindp->sbind_name, srv_bind->sb_name);
27977c478bd9Sstevel@tonic-gate (void) strcpy((char *)srv_rec.ServiceName, srv_bind->sb_name);
27987c478bd9Sstevel@tonic-gate srv_rec.ServiceGID = gid;
27997c478bd9Sstevel@tonic-gate
28007c478bd9Sstevel@tonic-gate /*
28017c478bd9Sstevel@tonic-gate * Find out whether we have any stale Local Service records
28027c478bd9Sstevel@tonic-gate * matching the current attributes. If yes, we shall try to
28037c478bd9Sstevel@tonic-gate * remove them from SA using the current request's ServiceKey.
28047c478bd9Sstevel@tonic-gate *
28057c478bd9Sstevel@tonic-gate * We will perform this operation only for Local Services, as
28067c478bd9Sstevel@tonic-gate * it is handled by SA automatically for WellKnown Services.
28077c478bd9Sstevel@tonic-gate *
28087c478bd9Sstevel@tonic-gate * Ofcourse, clients can specify NOT to do this clean-up by
28097c478bd9Sstevel@tonic-gate * setting IBT_SBIND_NO_CLEANUP flag (srv_bind->sb_flag).
28107c478bd9Sstevel@tonic-gate */
28117c478bd9Sstevel@tonic-gate if ((srv_hdl->svc_id & IB_SID_AGN_LOCAL) &&
28127c478bd9Sstevel@tonic-gate (!(srv_bind->sb_flag & IBT_SBIND_NO_CLEANUP))) {
28137c478bd9Sstevel@tonic-gate ibcm_rem_stale_srec(saa_handle, &srv_rec);
28147c478bd9Sstevel@tonic-gate }
28157c478bd9Sstevel@tonic-gate
28167c478bd9Sstevel@tonic-gate /* Handle endianess for service data. */
28177c478bd9Sstevel@tonic-gate ibcm_swizzle_from_srv(&srv_bind->sb_data, sbindp->sbind_data);
28187c478bd9Sstevel@tonic-gate
28197c478bd9Sstevel@tonic-gate bcopy(sbindp->sbind_data, srv_rec.ServiceData, IB_SVC_DATA_LEN);
28207c478bd9Sstevel@tonic-gate
28217c478bd9Sstevel@tonic-gate /* insert srv record into the SA */
28227c478bd9Sstevel@tonic-gate start_sid = srv_hdl->svc_id;
28237c478bd9Sstevel@tonic-gate end_sid = start_sid + srv_hdl->svc_num_sids - 1;
28247c478bd9Sstevel@tonic-gate for (sid = start_sid; sid <= end_sid; sid++) {
28257c478bd9Sstevel@tonic-gate
28267c478bd9Sstevel@tonic-gate srv_rec.ServiceID = sid;
28277c478bd9Sstevel@tonic-gate
28287c478bd9Sstevel@tonic-gate IBCM_DUMP_SERVICE_REC(&srv_rec);
28297c478bd9Sstevel@tonic-gate
28307c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_bind_service: "
28317c478bd9Sstevel@tonic-gate "ibmf_saa_write_service_record, SvcId = %llX",
28327c478bd9Sstevel@tonic-gate (longlong_t)sid);
28337c478bd9Sstevel@tonic-gate
28347c478bd9Sstevel@tonic-gate status = ibcm_write_service_record(saa_handle, &srv_rec,
28357c478bd9Sstevel@tonic-gate IBMF_SAA_UPDATE);
28367c478bd9Sstevel@tonic-gate if (status != IBT_SUCCESS) {
28377c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_bind_service:"
28387c478bd9Sstevel@tonic-gate " ibcm_write_service_record fails %d, "
28397c478bd9Sstevel@tonic-gate "sid %llX", status, (longlong_t)sid);
28407c478bd9Sstevel@tonic-gate
28417c478bd9Sstevel@tonic-gate if (sid != start_sid) {
28427c478bd9Sstevel@tonic-gate /*
28437c478bd9Sstevel@tonic-gate * Bind failed while bind SID other than
28447c478bd9Sstevel@tonic-gate * first in the sid_range. So we need
28457c478bd9Sstevel@tonic-gate * to unbind those, which are passed.
28467c478bd9Sstevel@tonic-gate *
28477c478bd9Sstevel@tonic-gate * Need to increment svc count to
28487c478bd9Sstevel@tonic-gate * compensate for ibt_unbind_service().
28497c478bd9Sstevel@tonic-gate */
28507c478bd9Sstevel@tonic-gate ibcm_inc_hca_svc_cnt(hcap);
28517c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
28527c478bd9Sstevel@tonic-gate
28537c478bd9Sstevel@tonic-gate (void) ibt_unbind_service(srv_hdl,
28547c478bd9Sstevel@tonic-gate sbindp);
28557c478bd9Sstevel@tonic-gate } else {
28567c478bd9Sstevel@tonic-gate ibcm_svc_bind_t **sbpp;
28577c478bd9Sstevel@tonic-gate
28587c478bd9Sstevel@tonic-gate /*
28597c478bd9Sstevel@tonic-gate * Bind failed for the first SID or the
28607c478bd9Sstevel@tonic-gate * only SID in question, then no need
28617c478bd9Sstevel@tonic-gate * to unbind, just free memory and
28627c478bd9Sstevel@tonic-gate * return error.
28637c478bd9Sstevel@tonic-gate */
28647c478bd9Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
28657c478bd9Sstevel@tonic-gate
28667c478bd9Sstevel@tonic-gate sbpp = &srv_hdl->svc_bind_list;
28677c478bd9Sstevel@tonic-gate sbp = *sbpp;
28687c478bd9Sstevel@tonic-gate while (sbp != NULL) {
28697c478bd9Sstevel@tonic-gate if (sbp == sbindp) {
28707c478bd9Sstevel@tonic-gate *sbpp = sbp->sbind_link;
28717c478bd9Sstevel@tonic-gate break;
28727c478bd9Sstevel@tonic-gate }
28737c478bd9Sstevel@tonic-gate sbpp = &sbp->sbind_link;
28747c478bd9Sstevel@tonic-gate sbp = *sbpp;
28757c478bd9Sstevel@tonic-gate }
28767c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
28777c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
28787c478bd9Sstevel@tonic-gate
28797c478bd9Sstevel@tonic-gate kmem_free(sbindp, sizeof (*sbindp));
28807c478bd9Sstevel@tonic-gate }
28817c478bd9Sstevel@tonic-gate return (status);
28827c478bd9Sstevel@tonic-gate }
28837c478bd9Sstevel@tonic-gate }
28847c478bd9Sstevel@tonic-gate }
28857c478bd9Sstevel@tonic-gate ibcm_inc_hca_svc_cnt(hcap);
28867c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
28877c478bd9Sstevel@tonic-gate
28887c478bd9Sstevel@tonic-gate /* If this message isn't seen then ibt_bind_service failed */
28899d3d2ed0Shiremath IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: DONE (%p, %llX:%llX)",
28907c478bd9Sstevel@tonic-gate srv_hdl, gid.gid_prefix, gid.gid_guid);
28917c478bd9Sstevel@tonic-gate
28927c478bd9Sstevel@tonic-gate if (sb_hdl_p != NULL)
28937c478bd9Sstevel@tonic-gate *sb_hdl_p = sbindp;
28947c478bd9Sstevel@tonic-gate
28957c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*sbindp))
28967c478bd9Sstevel@tonic-gate
28977c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
28987c478bd9Sstevel@tonic-gate }
28997c478bd9Sstevel@tonic-gate
29007c478bd9Sstevel@tonic-gate ibt_status_t
ibt_unbind_service(ibt_srv_hdl_t srv_hdl,ibt_sbind_hdl_t sbindp)29017c478bd9Sstevel@tonic-gate ibt_unbind_service(ibt_srv_hdl_t srv_hdl, ibt_sbind_hdl_t sbindp)
29027c478bd9Sstevel@tonic-gate {
29037c478bd9Sstevel@tonic-gate ib_svc_id_t sid, end_sid;
29047c478bd9Sstevel@tonic-gate ibt_status_t rval;
29057c478bd9Sstevel@tonic-gate ibcm_hca_info_t *hcap;
29067c478bd9Sstevel@tonic-gate ibcm_svc_bind_t *sbp, **sbpp;
29077c478bd9Sstevel@tonic-gate
29087c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_unbind_service(%p, %p)",
29097c478bd9Sstevel@tonic-gate srv_hdl, sbindp);
29107c478bd9Sstevel@tonic-gate
29117c478bd9Sstevel@tonic-gate hcap = ibcm_find_hca_entry(sbindp->sbind_hcaguid);
29127c478bd9Sstevel@tonic-gate
29137c478bd9Sstevel@tonic-gate /* If there is a service on hca, respective hcap cannot go away */
29147c478bd9Sstevel@tonic-gate ASSERT(hcap != NULL);
29157c478bd9Sstevel@tonic-gate
29167c478bd9Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
29177c478bd9Sstevel@tonic-gate
29187c478bd9Sstevel@tonic-gate sbpp = &srv_hdl->svc_bind_list;
29197c478bd9Sstevel@tonic-gate sbp = *sbpp;
29207c478bd9Sstevel@tonic-gate while (sbp != NULL) {
29217c478bd9Sstevel@tonic-gate if (sbp == sbindp) {
29227c478bd9Sstevel@tonic-gate *sbpp = sbp->sbind_link;
29237c478bd9Sstevel@tonic-gate break;
29247c478bd9Sstevel@tonic-gate }
29257c478bd9Sstevel@tonic-gate sbpp = &sbp->sbind_link;
29267c478bd9Sstevel@tonic-gate sbp = *sbpp;
29277c478bd9Sstevel@tonic-gate }
29287c478bd9Sstevel@tonic-gate sid = srv_hdl->svc_id;
29297c478bd9Sstevel@tonic-gate end_sid = srv_hdl->svc_id + srv_hdl->svc_num_sids - 1;
29307c478bd9Sstevel@tonic-gate if (sbp != NULL)
29317c478bd9Sstevel@tonic-gate while (sbp->sbind_rewrite_state == IBCM_REWRITE_BUSY)
29327c478bd9Sstevel@tonic-gate cv_wait(&ibcm_svc_info_cv, &ibcm_svc_info_lock);
29337c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
29347c478bd9Sstevel@tonic-gate
29357c478bd9Sstevel@tonic-gate if (sbp == NULL) {
29367c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_unbind_service: "
29377c478bd9Sstevel@tonic-gate "service binding not found: srv_hdl %p, srv_bind %p",
29387c478bd9Sstevel@tonic-gate srv_hdl, sbindp);
29397c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
29407c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
29417c478bd9Sstevel@tonic-gate }
29427c478bd9Sstevel@tonic-gate
29437c478bd9Sstevel@tonic-gate if (sbindp->sbind_pkey != 0) { /* Are there service records? */
29447c478bd9Sstevel@tonic-gate ibtl_cm_hca_port_t port;
29457c478bd9Sstevel@tonic-gate sa_service_record_t srv_rec;
29467c478bd9Sstevel@tonic-gate ibmf_saa_handle_t saa_handle;
29477c478bd9Sstevel@tonic-gate ibt_status_t status;
29487c478bd9Sstevel@tonic-gate
29497c478bd9Sstevel@tonic-gate /* get the default SGID of the port */
29507c478bd9Sstevel@tonic-gate if ((status = ibtl_cm_get_hca_port(sbindp->sbind_gid, 0, &port))
29517c478bd9Sstevel@tonic-gate != IBT_SUCCESS) {
29527c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_unbind_service: "
29537c478bd9Sstevel@tonic-gate "ibtl_cm_get_hca_port failed: %d", status);
29547c478bd9Sstevel@tonic-gate /* we're done, but there may be stale service records */
29557c478bd9Sstevel@tonic-gate goto done;
29567c478bd9Sstevel@tonic-gate }
29577c478bd9Sstevel@tonic-gate
29587c478bd9Sstevel@tonic-gate saa_handle = ibcm_get_saa_handle(hcap, port.hp_port);
29597c478bd9Sstevel@tonic-gate if (saa_handle == NULL) {
29607c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_unbind_service: "
29617c478bd9Sstevel@tonic-gate "saa_handle is NULL");
29627c478bd9Sstevel@tonic-gate /* we're done, but there may be stale service records */
29637c478bd9Sstevel@tonic-gate goto done;
29647c478bd9Sstevel@tonic-gate }
29657c478bd9Sstevel@tonic-gate
29667c478bd9Sstevel@tonic-gate /* Fill in fields of srv_rec */
29677c478bd9Sstevel@tonic-gate bzero(&srv_rec, sizeof (srv_rec));
29687c478bd9Sstevel@tonic-gate
29697c478bd9Sstevel@tonic-gate srv_rec.ServiceP_Key = sbindp->sbind_pkey;
29707c478bd9Sstevel@tonic-gate srv_rec.ServiceKey_hi = sbindp->sbind_key[0];
29717c478bd9Sstevel@tonic-gate srv_rec.ServiceKey_lo = sbindp->sbind_key[1];
29727c478bd9Sstevel@tonic-gate srv_rec.ServiceGID = sbindp->sbind_gid;
29737c478bd9Sstevel@tonic-gate (void) strcpy((char *)srv_rec.ServiceName, sbindp->sbind_name);
29747c478bd9Sstevel@tonic-gate
29757c478bd9Sstevel@tonic-gate while (sid <= end_sid) {
29767c478bd9Sstevel@tonic-gate
29777c478bd9Sstevel@tonic-gate srv_rec.ServiceID = sid;
29787c478bd9Sstevel@tonic-gate IBCM_DUMP_SERVICE_REC(&srv_rec);
29797c478bd9Sstevel@tonic-gate
29807c478bd9Sstevel@tonic-gate rval = ibcm_write_service_record(saa_handle, &srv_rec,
29817c478bd9Sstevel@tonic-gate IBMF_SAA_DELETE);
29827c478bd9Sstevel@tonic-gate
29837c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_unbind_service: "
29847c478bd9Sstevel@tonic-gate "ibcm_write_service_record rval = %d, SID %llx",
29857c478bd9Sstevel@tonic-gate rval, sid);
29867c478bd9Sstevel@tonic-gate if (rval != IBT_SUCCESS) {
29877c478bd9Sstevel@tonic-gate /* this is not considered a reason to fail */
29887c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_unbind_service: "
29897c478bd9Sstevel@tonic-gate "ibcm_write_service_record fails %d, "
29907c478bd9Sstevel@tonic-gate "sid %llx", rval, sid);
29917c478bd9Sstevel@tonic-gate }
29927c478bd9Sstevel@tonic-gate sid++;
29937c478bd9Sstevel@tonic-gate }
29947c478bd9Sstevel@tonic-gate }
29957c478bd9Sstevel@tonic-gate done:
29967c478bd9Sstevel@tonic-gate ibcm_dec_hca_svc_cnt(hcap);
29977c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
29987c478bd9Sstevel@tonic-gate kmem_free(sbindp, sizeof (*sbindp));
29997c478bd9Sstevel@tonic-gate
30007c478bd9Sstevel@tonic-gate /* If this message isn't seen then ibt_unbind_service failed */
30017c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_unbind_service: done !!");
30027c478bd9Sstevel@tonic-gate
30037c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
30047c478bd9Sstevel@tonic-gate }
30057c478bd9Sstevel@tonic-gate
30067c478bd9Sstevel@tonic-gate /*
30077c478bd9Sstevel@tonic-gate * Simply pull off each binding from the list and unbind it.
30087c478bd9Sstevel@tonic-gate * If any of the unbind calls fail, we fail.
30097c478bd9Sstevel@tonic-gate */
30107c478bd9Sstevel@tonic-gate ibt_status_t
ibt_unbind_all_services(ibt_srv_hdl_t srv_hdl)30117c478bd9Sstevel@tonic-gate ibt_unbind_all_services(ibt_srv_hdl_t srv_hdl)
30127c478bd9Sstevel@tonic-gate {
30137c478bd9Sstevel@tonic-gate ibt_status_t status;
30147c478bd9Sstevel@tonic-gate ibcm_svc_bind_t *sbp;
30157c478bd9Sstevel@tonic-gate
30167c478bd9Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
30177c478bd9Sstevel@tonic-gate sbp = NULL;
30187c478bd9Sstevel@tonic-gate
30197c478bd9Sstevel@tonic-gate /* this compare keeps the loop from being infinite */
30207c478bd9Sstevel@tonic-gate while (sbp != srv_hdl->svc_bind_list) {
30217c478bd9Sstevel@tonic-gate sbp = srv_hdl->svc_bind_list;
30227c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
30237c478bd9Sstevel@tonic-gate status = ibt_unbind_service(srv_hdl, sbp);
30247c478bd9Sstevel@tonic-gate if (status != IBT_SUCCESS)
30257c478bd9Sstevel@tonic-gate return (status);
30267c478bd9Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
30277c478bd9Sstevel@tonic-gate if (srv_hdl->svc_bind_list == NULL)
30287c478bd9Sstevel@tonic-gate break;
30297c478bd9Sstevel@tonic-gate }
30307c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
30317c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
30327c478bd9Sstevel@tonic-gate }
30337c478bd9Sstevel@tonic-gate
30347c478bd9Sstevel@tonic-gate /*
30357c478bd9Sstevel@tonic-gate * ibt_deregister_service()
30367c478bd9Sstevel@tonic-gate * Deregister a service with the IBCM
30377c478bd9Sstevel@tonic-gate *
30387c478bd9Sstevel@tonic-gate * INPUTS:
30397c478bd9Sstevel@tonic-gate * ibt_hdl The IBT client handle returned to the client
30407c478bd9Sstevel@tonic-gate * on an ibt_attach() call.
30417c478bd9Sstevel@tonic-gate *
30427c478bd9Sstevel@tonic-gate * srv_hdl The address of a service identification handle, used
30437c478bd9Sstevel@tonic-gate * to de-register a service.
30447c478bd9Sstevel@tonic-gate * RETURN VALUES:
30457c478bd9Sstevel@tonic-gate * IBT_SUCCESS on success (or respective failure on error)
30467c478bd9Sstevel@tonic-gate */
30477c478bd9Sstevel@tonic-gate ibt_status_t
ibt_deregister_service(ibt_clnt_hdl_t ibt_hdl,ibt_srv_hdl_t srv_hdl)30487c478bd9Sstevel@tonic-gate ibt_deregister_service(ibt_clnt_hdl_t ibt_hdl, ibt_srv_hdl_t srv_hdl)
30497c478bd9Sstevel@tonic-gate {
30507c478bd9Sstevel@tonic-gate ibcm_svc_info_t *svcp;
30517c478bd9Sstevel@tonic-gate ibcm_svc_lookup_t svc;
30527c478bd9Sstevel@tonic-gate
3053d3a82192SShantkumar Hiremath IBTF_DPRINTF_L2(cmlog, "ibt_deregister_service(%p (%s), %p)",
3054d3a82192SShantkumar Hiremath ibt_hdl, ibtl_cm_get_clnt_name(ibt_hdl), srv_hdl);
30557c478bd9Sstevel@tonic-gate
30567c478bd9Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
30577c478bd9Sstevel@tonic-gate
30587c478bd9Sstevel@tonic-gate if (srv_hdl->svc_bind_list != NULL) {
30597c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_deregister_service:"
30607c478bd9Sstevel@tonic-gate " srv_hdl %p still has bindings", srv_hdl);
30617c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
30627c478bd9Sstevel@tonic-gate return (IBT_CM_SERVICE_BUSY);
30637c478bd9Sstevel@tonic-gate }
30647c478bd9Sstevel@tonic-gate svc.sid = srv_hdl->svc_id;
30657c478bd9Sstevel@tonic-gate svc.num_sids = 1;
306624b28d04Shiremath IBTF_DPRINTF_L3(cmlog, "ibt_deregister_service: SID 0x%llX, numsids %d",
306724b28d04Shiremath srv_hdl->svc_id, srv_hdl->svc_num_sids);
306824b28d04Shiremath
30697c478bd9Sstevel@tonic-gate #ifdef __lock_lint
30707c478bd9Sstevel@tonic-gate ibcm_svc_compare(NULL, NULL);
30717c478bd9Sstevel@tonic-gate #endif
30727c478bd9Sstevel@tonic-gate svcp = avl_find(&ibcm_svc_avl_tree, &svc, NULL);
30737c478bd9Sstevel@tonic-gate if (svcp != srv_hdl) {
30747c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
30757c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_deregister_service(): "
30767c478bd9Sstevel@tonic-gate "srv_hdl %p not found", srv_hdl);
30777c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
30787c478bd9Sstevel@tonic-gate }
30797c478bd9Sstevel@tonic-gate avl_remove(&ibcm_svc_avl_tree, svcp);
30807c478bd9Sstevel@tonic-gate
30817c478bd9Sstevel@tonic-gate /* wait for active REQ/SREQ handling to be done */
30827c478bd9Sstevel@tonic-gate svcp->svc_to_delete = 1;
30837c478bd9Sstevel@tonic-gate while (svcp->svc_ref_cnt != 0)
30847c478bd9Sstevel@tonic-gate cv_wait(&ibcm_svc_info_cv, &ibcm_svc_info_lock);
30857c478bd9Sstevel@tonic-gate
30867c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
30877c478bd9Sstevel@tonic-gate
30887c478bd9Sstevel@tonic-gate if ((srv_hdl->svc_id & IB_SID_AGN_MASK) == IB_SID_AGN_LOCAL)
30897c478bd9Sstevel@tonic-gate ibcm_free_local_sids(srv_hdl->svc_id, srv_hdl->svc_num_sids);
30907c478bd9Sstevel@tonic-gate
30917c478bd9Sstevel@tonic-gate ibtl_cm_change_service_cnt(ibt_hdl, -srv_hdl->svc_num_sids);
30927c478bd9Sstevel@tonic-gate kmem_free(srv_hdl, sizeof (*srv_hdl));
30937c478bd9Sstevel@tonic-gate
30947c478bd9Sstevel@tonic-gate /* If this message isn't seen then ibt_deregister_service failed */
30957c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_deregister_service: done !!");
30967c478bd9Sstevel@tonic-gate
30977c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
30987c478bd9Sstevel@tonic-gate }
30997c478bd9Sstevel@tonic-gate
31007c478bd9Sstevel@tonic-gate ibcm_status_t
ibcm_ar_init(void)31017c478bd9Sstevel@tonic-gate ibcm_ar_init(void)
31027c478bd9Sstevel@tonic-gate {
31037c478bd9Sstevel@tonic-gate ib_svc_id_t sid = IBCM_DAPL_ATS_SID;
31047c478bd9Sstevel@tonic-gate ibcm_svc_info_t *tmp_svcp;
31057c478bd9Sstevel@tonic-gate
31067c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_ar_init()");
31077c478bd9Sstevel@tonic-gate
31087c478bd9Sstevel@tonic-gate /* remove this special SID from the pool of available SIDs */
31097c478bd9Sstevel@tonic-gate if ((tmp_svcp = ibcm_create_svc_entry(sid, 1)) == NULL) {
3110d3a82192SShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibcm_ar_init: "
31117c478bd9Sstevel@tonic-gate "DAPL ATS SID 0x%llx already registered", (longlong_t)sid);
31127c478bd9Sstevel@tonic-gate return (IBCM_FAILURE);
31137c478bd9Sstevel@tonic-gate }
31147c478bd9Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
31157c478bd9Sstevel@tonic-gate ibcm_ar_svcinfop = tmp_svcp;
31167c478bd9Sstevel@tonic-gate ibcm_ar_list = NULL; /* no address records registered yet */
31177c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
31187c478bd9Sstevel@tonic-gate return (IBCM_SUCCESS);
31197c478bd9Sstevel@tonic-gate }
31207c478bd9Sstevel@tonic-gate
31217c478bd9Sstevel@tonic-gate ibcm_status_t
ibcm_ar_fini(void)31227c478bd9Sstevel@tonic-gate ibcm_ar_fini(void)
31237c478bd9Sstevel@tonic-gate {
31247c478bd9Sstevel@tonic-gate ibcm_ar_t *ar_list;
31257c478bd9Sstevel@tonic-gate ibcm_svc_info_t *tmp_svcp;
31267c478bd9Sstevel@tonic-gate
31277c478bd9Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
31287c478bd9Sstevel@tonic-gate ar_list = ibcm_ar_list;
31297c478bd9Sstevel@tonic-gate
31307c478bd9Sstevel@tonic-gate if (ar_list == NULL &&
31317c478bd9Sstevel@tonic-gate avl_numnodes(&ibcm_svc_avl_tree) == 1 &&
31327c478bd9Sstevel@tonic-gate avl_first(&ibcm_svc_avl_tree) == ibcm_ar_svcinfop) {
31337c478bd9Sstevel@tonic-gate avl_remove(&ibcm_svc_avl_tree, ibcm_ar_svcinfop);
31347c478bd9Sstevel@tonic-gate tmp_svcp = ibcm_ar_svcinfop;
31357c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
31367c478bd9Sstevel@tonic-gate kmem_free(tmp_svcp, sizeof (*ibcm_ar_svcinfop));
31377c478bd9Sstevel@tonic-gate return (IBCM_SUCCESS);
31387c478bd9Sstevel@tonic-gate }
31397c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
31407c478bd9Sstevel@tonic-gate return (IBCM_FAILURE);
31417c478bd9Sstevel@tonic-gate }
31427c478bd9Sstevel@tonic-gate
31437c478bd9Sstevel@tonic-gate
31447c478bd9Sstevel@tonic-gate /*
31457c478bd9Sstevel@tonic-gate * Return to the caller:
31467c478bd9Sstevel@tonic-gate * IBT_SUCCESS Found a perfect match.
31477c478bd9Sstevel@tonic-gate * *arpp is set to the record.
31487c478bd9Sstevel@tonic-gate * IBT_INCONSISTENT_AR Found a record that's inconsistent.
31497c478bd9Sstevel@tonic-gate * IBT_AR_NOT_REGISTERED Found no record with same GID/pkey and
31507c478bd9Sstevel@tonic-gate * found no record with same data.
31517c478bd9Sstevel@tonic-gate */
31527c478bd9Sstevel@tonic-gate static ibt_status_t
ibcm_search_ar(ibt_ar_t * arp,ibcm_ar_t ** arpp)31537c478bd9Sstevel@tonic-gate ibcm_search_ar(ibt_ar_t *arp, ibcm_ar_t **arpp)
31547c478bd9Sstevel@tonic-gate {
31557c478bd9Sstevel@tonic-gate ibcm_ar_t *tmp;
31567c478bd9Sstevel@tonic-gate int i;
31577c478bd9Sstevel@tonic-gate
31587c478bd9Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ibcm_svc_info_lock));
31597c478bd9Sstevel@tonic-gate tmp = ibcm_ar_list;
31607c478bd9Sstevel@tonic-gate while (tmp != NULL) {
31617c478bd9Sstevel@tonic-gate if (tmp->ar.ar_gid.gid_prefix == arp->ar_gid.gid_prefix &&
31627c478bd9Sstevel@tonic-gate tmp->ar.ar_gid.gid_guid == arp->ar_gid.gid_guid &&
31637c478bd9Sstevel@tonic-gate tmp->ar.ar_pkey == arp->ar_pkey) {
31647c478bd9Sstevel@tonic-gate for (i = 0; i < IBCM_DAPL_ATS_NBYTES; i++)
31657c478bd9Sstevel@tonic-gate if (tmp->ar.ar_data[i] != arp->ar_data[i])
31667c478bd9Sstevel@tonic-gate return (IBT_INCONSISTENT_AR);
31677c478bd9Sstevel@tonic-gate *arpp = tmp;
31687c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
31697c478bd9Sstevel@tonic-gate } else {
31707c478bd9Sstevel@tonic-gate /* if all the data bytes match, we have inconsistency */
31717c478bd9Sstevel@tonic-gate for (i = 0; i < IBCM_DAPL_ATS_NBYTES; i++)
31727c478bd9Sstevel@tonic-gate if (tmp->ar.ar_data[i] != arp->ar_data[i])
31737c478bd9Sstevel@tonic-gate break;
31747c478bd9Sstevel@tonic-gate if (i == IBCM_DAPL_ATS_NBYTES)
31757c478bd9Sstevel@tonic-gate return (IBT_INCONSISTENT_AR);
31767c478bd9Sstevel@tonic-gate /* try next address record */
31777c478bd9Sstevel@tonic-gate }
31787c478bd9Sstevel@tonic-gate tmp = tmp->ar_link;
31797c478bd9Sstevel@tonic-gate }
31807c478bd9Sstevel@tonic-gate return (IBT_AR_NOT_REGISTERED);
31817c478bd9Sstevel@tonic-gate }
31827c478bd9Sstevel@tonic-gate
31837c478bd9Sstevel@tonic-gate ibt_status_t
ibt_register_ar(ibt_clnt_hdl_t ibt_hdl,ibt_ar_t * arp)31847c478bd9Sstevel@tonic-gate ibt_register_ar(ibt_clnt_hdl_t ibt_hdl, ibt_ar_t *arp)
31857c478bd9Sstevel@tonic-gate {
31867c478bd9Sstevel@tonic-gate ibcm_ar_t *found;
31877c478bd9Sstevel@tonic-gate ibcm_ar_t *tmp;
31887c478bd9Sstevel@tonic-gate ibt_status_t status;
31897c478bd9Sstevel@tonic-gate ibt_status_t s1, s2;
31907c478bd9Sstevel@tonic-gate char *s;
31917c478bd9Sstevel@tonic-gate ibcm_ar_ref_t *hdlp;
31927c478bd9Sstevel@tonic-gate ibcm_ar_t *new;
31937c478bd9Sstevel@tonic-gate ibcm_ar_t **linkp;
31947c478bd9Sstevel@tonic-gate ibtl_cm_hca_port_t cm_port;
31957c478bd9Sstevel@tonic-gate uint16_t pkey_ix;
31967c478bd9Sstevel@tonic-gate ibcm_hca_info_t *hcap;
31977c478bd9Sstevel@tonic-gate ibmf_saa_handle_t saa_handle;
31987c478bd9Sstevel@tonic-gate sa_service_record_t *srv_recp;
31997c478bd9Sstevel@tonic-gate uint64_t gid_ored;
32007c478bd9Sstevel@tonic-gate
3201d3a82192SShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibt_register_ar: PKey 0x%X GID %llX:%llX",
32027c478bd9Sstevel@tonic-gate arp->ar_pkey, (longlong_t)arp->ar_gid.gid_prefix,
32037c478bd9Sstevel@tonic-gate (longlong_t)arp->ar_gid.gid_guid);
32047c478bd9Sstevel@tonic-gate
32057c478bd9Sstevel@tonic-gate /*
32067c478bd9Sstevel@tonic-gate * If P_Key is 0, but GID is not, this query is invalid.
32077c478bd9Sstevel@tonic-gate * If GID is 0, but P_Key is not, this query is invalid.
32087c478bd9Sstevel@tonic-gate */
32097c478bd9Sstevel@tonic-gate gid_ored = arp->ar_gid.gid_guid | arp->ar_gid.gid_prefix;
32107c478bd9Sstevel@tonic-gate if ((arp->ar_pkey == 0 && gid_ored != 0ULL) ||
32117c478bd9Sstevel@tonic-gate (arp->ar_pkey != 0 && gid_ored == 0ULL)) {
32127c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_register_ar: "
32137c478bd9Sstevel@tonic-gate "GID/P_Key is not valid");
32147c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
32157c478bd9Sstevel@tonic-gate }
32167c478bd9Sstevel@tonic-gate
32177c478bd9Sstevel@tonic-gate /* assume success, so these might be needed */
32187c478bd9Sstevel@tonic-gate hdlp = kmem_alloc(sizeof (*hdlp), KM_SLEEP);
321910243922Srm78299 new = kmem_zalloc(sizeof (*new), KM_SLEEP);
32207c478bd9Sstevel@tonic-gate
32217c478bd9Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
32227c478bd9Sstevel@tonic-gate /* search for existing GID/pkey (there can be at most 1) */
32237c478bd9Sstevel@tonic-gate status = ibcm_search_ar(arp, &found);
32247c478bd9Sstevel@tonic-gate if (status == IBT_INCONSISTENT_AR) {
32257c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
32267c478bd9Sstevel@tonic-gate kmem_free(new, sizeof (*new));
32277c478bd9Sstevel@tonic-gate kmem_free(hdlp, sizeof (*hdlp));
32287c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_register_ar: "
32297c478bd9Sstevel@tonic-gate "address record is inconsistent with a known one");
32307c478bd9Sstevel@tonic-gate return (IBT_INCONSISTENT_AR);
32317c478bd9Sstevel@tonic-gate } else if (status == IBT_SUCCESS) {
32327c478bd9Sstevel@tonic-gate if (found->ar_flags == IBCM_AR_INITING) {
32337c478bd9Sstevel@tonic-gate found->ar_waiters++;
32347c478bd9Sstevel@tonic-gate cv_wait(&found->ar_cv, &ibcm_svc_info_lock);
32357c478bd9Sstevel@tonic-gate found->ar_waiters--;
32367c478bd9Sstevel@tonic-gate }
32377c478bd9Sstevel@tonic-gate if (found->ar_flags == IBCM_AR_FAILED) {
32387c478bd9Sstevel@tonic-gate if (found->ar_waiters == 0) {
32397c478bd9Sstevel@tonic-gate cv_destroy(&found->ar_cv);
32407c478bd9Sstevel@tonic-gate kmem_free(found, sizeof (*found));
32417c478bd9Sstevel@tonic-gate }
32427c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
32437c478bd9Sstevel@tonic-gate kmem_free(new, sizeof (*new));
32447c478bd9Sstevel@tonic-gate kmem_free(hdlp, sizeof (*hdlp));
32457c478bd9Sstevel@tonic-gate return (ibt_get_module_failure(IBT_FAILURE_IBCM, 0));
32467c478bd9Sstevel@tonic-gate }
32477c478bd9Sstevel@tonic-gate hdlp->ar_ibt_hdl = ibt_hdl;
32487c478bd9Sstevel@tonic-gate hdlp->ar_ref_link = found->ar_ibt_hdl_list;
32497c478bd9Sstevel@tonic-gate found->ar_ibt_hdl_list = hdlp;
32507c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
32517c478bd9Sstevel@tonic-gate kmem_free(new, sizeof (*new));
32527c478bd9Sstevel@tonic-gate ibtl_cm_change_service_cnt(ibt_hdl, 1);
32537c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
32547c478bd9Sstevel@tonic-gate } else {
32557c478bd9Sstevel@tonic-gate ASSERT(status == IBT_AR_NOT_REGISTERED);
32567c478bd9Sstevel@tonic-gate }
32577c478bd9Sstevel@tonic-gate hdlp->ar_ref_link = NULL;
32587c478bd9Sstevel@tonic-gate hdlp->ar_ibt_hdl = ibt_hdl;
32597c478bd9Sstevel@tonic-gate new->ar_ibt_hdl_list = hdlp;
32607c478bd9Sstevel@tonic-gate new->ar = *arp;
32617c478bd9Sstevel@tonic-gate new->ar_flags = IBCM_AR_INITING;
32627c478bd9Sstevel@tonic-gate new->ar_waiters = 0;
32637c478bd9Sstevel@tonic-gate cv_init(&new->ar_cv, NULL, CV_DEFAULT, NULL);
32647c478bd9Sstevel@tonic-gate new->ar_link = ibcm_ar_list;
32657c478bd9Sstevel@tonic-gate ibcm_ar_list = new;
32667c478bd9Sstevel@tonic-gate
32677c478bd9Sstevel@tonic-gate /* verify GID/pkey is valid for a local port, etc. */
32687c478bd9Sstevel@tonic-gate hcap = NULL;
32697c478bd9Sstevel@tonic-gate if ((s1 = ibtl_cm_get_hca_port(arp->ar_gid, 0, &cm_port))
32707c478bd9Sstevel@tonic-gate != IBT_SUCCESS ||
32717c478bd9Sstevel@tonic-gate (s2 = ibt_pkey2index_byguid(cm_port.hp_hca_guid, cm_port.hp_port,
32727c478bd9Sstevel@tonic-gate arp->ar_pkey, &pkey_ix)) != IBT_SUCCESS ||
32737c478bd9Sstevel@tonic-gate (hcap = ibcm_find_hca_entry(cm_port.hp_hca_guid)) == NULL) {
32747c478bd9Sstevel@tonic-gate cv_destroy(&new->ar_cv);
32757c478bd9Sstevel@tonic-gate ibcm_ar_list = new->ar_link;
32767c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
32777c478bd9Sstevel@tonic-gate kmem_free(new, sizeof (*new));
32787c478bd9Sstevel@tonic-gate kmem_free(hdlp, sizeof (*hdlp));
32797c478bd9Sstevel@tonic-gate status = IBT_INVALID_PARAM;
32807c478bd9Sstevel@tonic-gate if (s1 == IBT_HCA_PORT_NOT_ACTIVE) {
32817c478bd9Sstevel@tonic-gate s = "PORT DOWN";
32827c478bd9Sstevel@tonic-gate status = IBT_HCA_PORT_NOT_ACTIVE;
32837c478bd9Sstevel@tonic-gate } else if (s1 != IBT_SUCCESS)
32847c478bd9Sstevel@tonic-gate s = "GID not found";
32857c478bd9Sstevel@tonic-gate else if (s2 != IBT_SUCCESS)
32867c478bd9Sstevel@tonic-gate s = "PKEY not found";
32877c478bd9Sstevel@tonic-gate else
32887c478bd9Sstevel@tonic-gate s = "CM could not find its HCA entry";
32897c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_register_ar: %s, status = %d",
32907c478bd9Sstevel@tonic-gate s, status);
32917c478bd9Sstevel@tonic-gate return (status);
32927c478bd9Sstevel@tonic-gate }
32937c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
32947c478bd9Sstevel@tonic-gate saa_handle = ibcm_get_saa_handle(hcap, cm_port.hp_port);
32957c478bd9Sstevel@tonic-gate
32967c478bd9Sstevel@tonic-gate /* create service record */
32977c478bd9Sstevel@tonic-gate srv_recp = kmem_zalloc(sizeof (*srv_recp), KM_SLEEP);
32987c478bd9Sstevel@tonic-gate srv_recp->ServiceLease = 0xFFFFFFFF; /* infinite */
32997c478bd9Sstevel@tonic-gate srv_recp->ServiceP_Key = arp->ar_pkey;
33007c478bd9Sstevel@tonic-gate srv_recp->ServiceKey_hi = 0xDA410000ULL; /* DAPL */
33017c478bd9Sstevel@tonic-gate srv_recp->ServiceKey_lo = 0xA7500000ULL; /* ATS */
33027c478bd9Sstevel@tonic-gate (void) strcpy((char *)srv_recp->ServiceName, IBCM_DAPL_ATS_NAME);
33037c478bd9Sstevel@tonic-gate srv_recp->ServiceGID = arp->ar_gid;
33047c478bd9Sstevel@tonic-gate bcopy(arp->ar_data, srv_recp->ServiceData, IBCM_DAPL_ATS_NBYTES);
33057c478bd9Sstevel@tonic-gate srv_recp->ServiceID = IBCM_DAPL_ATS_SID;
33067c478bd9Sstevel@tonic-gate
33077c478bd9Sstevel@tonic-gate /* insert service record into the SA */
33087c478bd9Sstevel@tonic-gate
33097c478bd9Sstevel@tonic-gate IBCM_DUMP_SERVICE_REC(srv_recp);
33107c478bd9Sstevel@tonic-gate
33117c478bd9Sstevel@tonic-gate if (saa_handle != NULL)
33127c478bd9Sstevel@tonic-gate status = ibcm_write_service_record(saa_handle, srv_recp,
33137c478bd9Sstevel@tonic-gate IBMF_SAA_UPDATE);
33147c478bd9Sstevel@tonic-gate else
33157c478bd9Sstevel@tonic-gate status = IBT_HCA_PORT_NOT_ACTIVE;
33167c478bd9Sstevel@tonic-gate
33177c478bd9Sstevel@tonic-gate if (status != IBT_SUCCESS) {
33187c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_register_ar: sa access fails %d, "
33197c478bd9Sstevel@tonic-gate "sid %llX", status, (longlong_t)srv_recp->ServiceID);
33207c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_register_ar: FAILED for gid "
33217c478bd9Sstevel@tonic-gate "%llX:%llX pkey 0x%X", (longlong_t)arp->ar_gid.gid_prefix,
33227c478bd9Sstevel@tonic-gate (longlong_t)arp->ar_gid.gid_guid, arp->ar_pkey);
33237c478bd9Sstevel@tonic-gate
33247c478bd9Sstevel@tonic-gate kmem_free(srv_recp, sizeof (*srv_recp));
33257c478bd9Sstevel@tonic-gate kmem_free(hdlp, sizeof (*hdlp));
33267c478bd9Sstevel@tonic-gate
33277c478bd9Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
33287c478bd9Sstevel@tonic-gate linkp = &ibcm_ar_list;
33297c478bd9Sstevel@tonic-gate tmp = *linkp;
33307c478bd9Sstevel@tonic-gate while (tmp != NULL) {
33317c478bd9Sstevel@tonic-gate if (tmp == new) {
33327c478bd9Sstevel@tonic-gate *linkp = new->ar_link;
33337c478bd9Sstevel@tonic-gate break;
33347c478bd9Sstevel@tonic-gate }
33357c478bd9Sstevel@tonic-gate linkp = &tmp->ar_link;
33367c478bd9Sstevel@tonic-gate tmp = *linkp;
33377c478bd9Sstevel@tonic-gate }
33387c478bd9Sstevel@tonic-gate if (new->ar_waiters > 0) {
33397c478bd9Sstevel@tonic-gate new->ar_flags = IBCM_AR_FAILED;
33407c478bd9Sstevel@tonic-gate cv_broadcast(&new->ar_cv);
33417c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
33427c478bd9Sstevel@tonic-gate } else {
33437c478bd9Sstevel@tonic-gate cv_destroy(&new->ar_cv);
33447c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
33457c478bd9Sstevel@tonic-gate kmem_free(new, sizeof (*new));
33467c478bd9Sstevel@tonic-gate }
33477c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
33487c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_register_ar: "
33497c478bd9Sstevel@tonic-gate "IBMF_SAA failed to write address record");
33507c478bd9Sstevel@tonic-gate } else { /* SUCCESS */
33517c478bd9Sstevel@tonic-gate uint8_t *b;
33527c478bd9Sstevel@tonic-gate
3353d3a82192SShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibt_register_ar: SUCCESS for gid "
33547c478bd9Sstevel@tonic-gate "%llx:%llx pkey %x", (longlong_t)arp->ar_gid.gid_prefix,
33557c478bd9Sstevel@tonic-gate (longlong_t)arp->ar_gid.gid_guid, arp->ar_pkey);
33567c478bd9Sstevel@tonic-gate b = arp->ar_data;
33577c478bd9Sstevel@tonic-gate
3358d3a82192SShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibt_register_ar:"
33597c478bd9Sstevel@tonic-gate " data %d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
33607c478bd9Sstevel@tonic-gate b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9],
33617c478bd9Sstevel@tonic-gate b[10], b[11], b[12], b[13], b[14], b[15]);
33627c478bd9Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
33637c478bd9Sstevel@tonic-gate new->ar_srv_recp = srv_recp;
33647c478bd9Sstevel@tonic-gate new->ar_saa_handle = saa_handle;
33657c478bd9Sstevel@tonic-gate new->ar_port = cm_port.hp_port;
33667c478bd9Sstevel@tonic-gate new->ar_hcap = hcap;
33677c478bd9Sstevel@tonic-gate new->ar_flags = IBCM_AR_SUCCESS;
33687c478bd9Sstevel@tonic-gate if (new->ar_waiters > 0)
33697c478bd9Sstevel@tonic-gate cv_broadcast(&new->ar_cv);
33707c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
33717c478bd9Sstevel@tonic-gate ibtl_cm_change_service_cnt(ibt_hdl, 1);
33727c478bd9Sstevel@tonic-gate /* do not call ibcm_dec_hca_acc_cnt(hcap) until deregister */
33737c478bd9Sstevel@tonic-gate }
33747c478bd9Sstevel@tonic-gate return (status);
33757c478bd9Sstevel@tonic-gate }
33767c478bd9Sstevel@tonic-gate
33777c478bd9Sstevel@tonic-gate ibt_status_t
ibt_deregister_ar(ibt_clnt_hdl_t ibt_hdl,ibt_ar_t * arp)33787c478bd9Sstevel@tonic-gate ibt_deregister_ar(ibt_clnt_hdl_t ibt_hdl, ibt_ar_t *arp)
33797c478bd9Sstevel@tonic-gate {
33807c478bd9Sstevel@tonic-gate ibcm_ar_t *found;
33817c478bd9Sstevel@tonic-gate ibcm_ar_t *tmp;
33827c478bd9Sstevel@tonic-gate ibcm_ar_t **linkp;
33837c478bd9Sstevel@tonic-gate ibcm_ar_ref_t *hdlp;
33847c478bd9Sstevel@tonic-gate ibcm_ar_ref_t **hdlpp;
33857c478bd9Sstevel@tonic-gate ibt_status_t status;
33867c478bd9Sstevel@tonic-gate ibmf_saa_handle_t saa_handle;
33877c478bd9Sstevel@tonic-gate sa_service_record_t *srv_recp;
33887c478bd9Sstevel@tonic-gate uint64_t gid_ored;
33897c478bd9Sstevel@tonic-gate
3390d3a82192SShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibt_deregister_ar: pkey %x", arp->ar_pkey);
3391d3a82192SShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibt_deregister_ar: gid %llx:%llx",
33927c478bd9Sstevel@tonic-gate (longlong_t)arp->ar_gid.gid_prefix,
33937c478bd9Sstevel@tonic-gate (longlong_t)arp->ar_gid.gid_guid);
33947c478bd9Sstevel@tonic-gate
33957c478bd9Sstevel@tonic-gate /*
33967c478bd9Sstevel@tonic-gate * If P_Key is 0, but GID is not, this query is invalid.
33977c478bd9Sstevel@tonic-gate * If GID is 0, but P_Key is not, this query is invalid.
33987c478bd9Sstevel@tonic-gate */
33997c478bd9Sstevel@tonic-gate gid_ored = arp->ar_gid.gid_guid | arp->ar_gid.gid_prefix;
34007c478bd9Sstevel@tonic-gate if ((arp->ar_pkey == 0 && gid_ored != 0ULL) ||
34017c478bd9Sstevel@tonic-gate (arp->ar_pkey != 0 && gid_ored == 0ULL)) {
34027c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_deregister_ar: "
34037c478bd9Sstevel@tonic-gate "GID/P_Key is not valid");
34047c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
34057c478bd9Sstevel@tonic-gate }
34067c478bd9Sstevel@tonic-gate
34077c478bd9Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
34087c478bd9Sstevel@tonic-gate /* search for existing GID/pkey (there can be at most 1) */
34097c478bd9Sstevel@tonic-gate status = ibcm_search_ar(arp, &found);
34107c478bd9Sstevel@tonic-gate if (status == IBT_INCONSISTENT_AR || status == IBT_AR_NOT_REGISTERED) {
34117c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
34127c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_deregister_ar: "
34137c478bd9Sstevel@tonic-gate "address record not found");
34147c478bd9Sstevel@tonic-gate return (IBT_AR_NOT_REGISTERED);
34157c478bd9Sstevel@tonic-gate }
34167c478bd9Sstevel@tonic-gate ASSERT(status == IBT_SUCCESS);
34177c478bd9Sstevel@tonic-gate
34187c478bd9Sstevel@tonic-gate hdlpp = &found->ar_ibt_hdl_list;
34197c478bd9Sstevel@tonic-gate hdlp = *hdlpp;
34207c478bd9Sstevel@tonic-gate while (hdlp != NULL) {
34217c478bd9Sstevel@tonic-gate if (hdlp->ar_ibt_hdl == ibt_hdl)
34227c478bd9Sstevel@tonic-gate break;
34237c478bd9Sstevel@tonic-gate hdlpp = &hdlp->ar_ref_link;
34247c478bd9Sstevel@tonic-gate hdlp = *hdlpp;
34257c478bd9Sstevel@tonic-gate }
34267c478bd9Sstevel@tonic-gate if (hdlp == NULL) { /* could not find ibt_hdl on list */
34277c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
34287c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_deregister_ar: "
34297c478bd9Sstevel@tonic-gate "address record found, but not for this client");
34307c478bd9Sstevel@tonic-gate return (IBT_AR_NOT_REGISTERED);
34317c478bd9Sstevel@tonic-gate }
34327c478bd9Sstevel@tonic-gate *hdlpp = hdlp->ar_ref_link; /* remove ref for this client */
34337c478bd9Sstevel@tonic-gate if (found->ar_ibt_hdl_list == NULL && found->ar_waiters == 0) {
34347c478bd9Sstevel@tonic-gate /* last entry was removed */
34357c478bd9Sstevel@tonic-gate found->ar_flags = IBCM_AR_INITING; /* hold off register_ar */
34367c478bd9Sstevel@tonic-gate saa_handle = found->ar_saa_handle;
34377c478bd9Sstevel@tonic-gate srv_recp = found->ar_srv_recp;
34387c478bd9Sstevel@tonic-gate
34397c478bd9Sstevel@tonic-gate /* wait if this service record is being rewritten */
34407c478bd9Sstevel@tonic-gate while (found->ar_rewrite_state == IBCM_REWRITE_BUSY)
34417c478bd9Sstevel@tonic-gate cv_wait(&ibcm_svc_info_cv, &ibcm_svc_info_lock);
34427c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
34437c478bd9Sstevel@tonic-gate
34447c478bd9Sstevel@tonic-gate /* remove service record */
34457c478bd9Sstevel@tonic-gate status = ibcm_write_service_record(saa_handle, srv_recp,
34467c478bd9Sstevel@tonic-gate IBMF_SAA_DELETE);
34477c478bd9Sstevel@tonic-gate if (status != IBT_SUCCESS)
34487c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_deregister_ar: "
34497c478bd9Sstevel@tonic-gate "IBMF_SAA failed to delete address record");
34507c478bd9Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
34517c478bd9Sstevel@tonic-gate if (found->ar_waiters == 0) { /* still no waiters */
34527c478bd9Sstevel@tonic-gate linkp = &ibcm_ar_list;
34537c478bd9Sstevel@tonic-gate tmp = *linkp;
34547c478bd9Sstevel@tonic-gate while (tmp != found) {
34557c478bd9Sstevel@tonic-gate linkp = &tmp->ar_link;
34567c478bd9Sstevel@tonic-gate tmp = *linkp;
34577c478bd9Sstevel@tonic-gate }
34587c478bd9Sstevel@tonic-gate *linkp = tmp->ar_link;
34597c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(found->ar_hcap);
34607c478bd9Sstevel@tonic-gate kmem_free(srv_recp, sizeof (*srv_recp));
34617c478bd9Sstevel@tonic-gate cv_destroy(&found->ar_cv);
34627c478bd9Sstevel@tonic-gate kmem_free(found, sizeof (*found));
34637c478bd9Sstevel@tonic-gate } else {
34647c478bd9Sstevel@tonic-gate /* add service record back in for the waiters */
34657c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
34667c478bd9Sstevel@tonic-gate status = ibcm_write_service_record(saa_handle, srv_recp,
34677c478bd9Sstevel@tonic-gate IBMF_SAA_UPDATE);
34687c478bd9Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
34697c478bd9Sstevel@tonic-gate if (status == IBT_SUCCESS)
34707c478bd9Sstevel@tonic-gate found->ar_flags = IBCM_AR_SUCCESS;
34717c478bd9Sstevel@tonic-gate else {
34727c478bd9Sstevel@tonic-gate found->ar_flags = IBCM_AR_FAILED;
34737c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_deregister_ar: "
34747c478bd9Sstevel@tonic-gate "IBMF_SAA failed to write address record");
34757c478bd9Sstevel@tonic-gate }
34767c478bd9Sstevel@tonic-gate cv_broadcast(&found->ar_cv);
34777c478bd9Sstevel@tonic-gate }
34787c478bd9Sstevel@tonic-gate }
34797c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
34807c478bd9Sstevel@tonic-gate kmem_free(hdlp, sizeof (*hdlp));
34817c478bd9Sstevel@tonic-gate ibtl_cm_change_service_cnt(ibt_hdl, -1);
34827c478bd9Sstevel@tonic-gate return (status);
34837c478bd9Sstevel@tonic-gate }
34847c478bd9Sstevel@tonic-gate
34857c478bd9Sstevel@tonic-gate ibt_status_t
ibt_query_ar(ib_gid_t * sgid,ibt_ar_t * queryp,ibt_ar_t * resultp)34867c478bd9Sstevel@tonic-gate ibt_query_ar(ib_gid_t *sgid, ibt_ar_t *queryp, ibt_ar_t *resultp)
34877c478bd9Sstevel@tonic-gate {
34887c478bd9Sstevel@tonic-gate sa_service_record_t svcrec_req;
34897c478bd9Sstevel@tonic-gate sa_service_record_t *svcrec_resp;
34907c478bd9Sstevel@tonic-gate void *results_p;
34917c478bd9Sstevel@tonic-gate uint64_t component_mask = 0;
34927c478bd9Sstevel@tonic-gate uint64_t gid_ored;
34937c478bd9Sstevel@tonic-gate size_t length;
34947c478bd9Sstevel@tonic-gate int num_rec;
34957c478bd9Sstevel@tonic-gate int i;
34967c478bd9Sstevel@tonic-gate ibmf_saa_access_args_t access_args;
34977c478bd9Sstevel@tonic-gate ibt_status_t retval;
34987c478bd9Sstevel@tonic-gate ibtl_cm_hca_port_t cm_port;
34997c478bd9Sstevel@tonic-gate ibcm_hca_info_t *hcap;
35007c478bd9Sstevel@tonic-gate ibmf_saa_handle_t saa_handle;
35017c478bd9Sstevel@tonic-gate
35027c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_query_ar(%p, %p)", queryp, resultp);
35037c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_query_ar: sgid %llx:%llx",
35047c478bd9Sstevel@tonic-gate (longlong_t)sgid->gid_prefix, (longlong_t)sgid->gid_guid);
35057c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_query_ar: query_pkey %x", queryp->ar_pkey);
35067c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_query_ar: query_gid %llx:%llx",
35077c478bd9Sstevel@tonic-gate (longlong_t)queryp->ar_gid.gid_prefix,
35087c478bd9Sstevel@tonic-gate (longlong_t)queryp->ar_gid.gid_guid);
35097c478bd9Sstevel@tonic-gate
35107c478bd9Sstevel@tonic-gate /*
35117c478bd9Sstevel@tonic-gate * If P_Key is 0, but GID is not, this query is invalid.
35127c478bd9Sstevel@tonic-gate * If GID is 0, but P_Key is not, this query is invalid.
35137c478bd9Sstevel@tonic-gate */
35147c478bd9Sstevel@tonic-gate gid_ored = queryp->ar_gid.gid_guid | queryp->ar_gid.gid_prefix;
35157c478bd9Sstevel@tonic-gate if ((queryp->ar_pkey == 0 && gid_ored != 0ULL) ||
35167c478bd9Sstevel@tonic-gate (queryp->ar_pkey != 0 && gid_ored == 0ULL)) {
35177c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_query_ar: GID/P_Key is not valid");
35187c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
35197c478bd9Sstevel@tonic-gate }
35207c478bd9Sstevel@tonic-gate
35217c478bd9Sstevel@tonic-gate hcap = NULL;
35227c478bd9Sstevel@tonic-gate if (ibtl_cm_get_hca_port(*sgid, 0, &cm_port) != IBT_SUCCESS ||
35237c478bd9Sstevel@tonic-gate (hcap = ibcm_find_hca_entry(cm_port.hp_hca_guid)) == NULL ||
35247c478bd9Sstevel@tonic-gate (saa_handle = ibcm_get_saa_handle(hcap, cm_port.hp_port)) == NULL) {
35257c478bd9Sstevel@tonic-gate if (hcap != NULL)
35267c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
35277c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_query_ar: sgid is not valid");
35287c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
35297c478bd9Sstevel@tonic-gate }
35307c478bd9Sstevel@tonic-gate
35317c478bd9Sstevel@tonic-gate bzero(&svcrec_req, sizeof (svcrec_req));
35327c478bd9Sstevel@tonic-gate
35337c478bd9Sstevel@tonic-gate /* Is GID/P_Key Specified. */
35347c478bd9Sstevel@tonic-gate if (queryp->ar_pkey != 0) { /* GID is non-zero from check above */
35357c478bd9Sstevel@tonic-gate svcrec_req.ServiceP_Key = queryp->ar_pkey;
35367c478bd9Sstevel@tonic-gate component_mask |= SA_SR_COMPMASK_PKEY;
35377c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_query_ar: P_Key %X",
35387c478bd9Sstevel@tonic-gate queryp->ar_pkey);
35397c478bd9Sstevel@tonic-gate svcrec_req.ServiceGID = queryp->ar_gid;
35407c478bd9Sstevel@tonic-gate component_mask |= SA_SR_COMPMASK_GID;
35417c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_query_ar: GID %llX:%llX",
35427c478bd9Sstevel@tonic-gate (longlong_t)queryp->ar_gid.gid_prefix,
35437c478bd9Sstevel@tonic-gate (longlong_t)queryp->ar_gid.gid_guid);
35447c478bd9Sstevel@tonic-gate }
35457c478bd9Sstevel@tonic-gate
35467c478bd9Sstevel@tonic-gate /* Is ServiceData Specified. */
35477c478bd9Sstevel@tonic-gate for (i = 0; i < IBCM_DAPL_ATS_NBYTES; i++) {
35487c478bd9Sstevel@tonic-gate if (queryp->ar_data[i] != 0) {
35497c478bd9Sstevel@tonic-gate bcopy(queryp->ar_data, svcrec_req.ServiceData,
35507c478bd9Sstevel@tonic-gate IBCM_DAPL_ATS_NBYTES);
35517c478bd9Sstevel@tonic-gate component_mask |= 0xFFFF << 7; /* all 16 Data8 */
35527c478bd9Sstevel@tonic-gate /* components */
35537c478bd9Sstevel@tonic-gate break;
35547c478bd9Sstevel@tonic-gate }
35557c478bd9Sstevel@tonic-gate }
35567c478bd9Sstevel@tonic-gate
35577c478bd9Sstevel@tonic-gate /* Service Name */
35587c478bd9Sstevel@tonic-gate (void) strcpy((char *)svcrec_req.ServiceName, IBCM_DAPL_ATS_NAME);
35597c478bd9Sstevel@tonic-gate component_mask |= SA_SR_COMPMASK_NAME;
35607c478bd9Sstevel@tonic-gate
35617c478bd9Sstevel@tonic-gate svcrec_req.ServiceID = IBCM_DAPL_ATS_SID;
35627c478bd9Sstevel@tonic-gate component_mask |= SA_SR_COMPMASK_ID;
35637c478bd9Sstevel@tonic-gate
35647c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_query_ar: "
35657c478bd9Sstevel@tonic-gate "Perform SA Access: Mask: 0x%X", component_mask);
35667c478bd9Sstevel@tonic-gate
35677c478bd9Sstevel@tonic-gate /*
35687c478bd9Sstevel@tonic-gate * Call in SA Access retrieve routine to get Service Records.
35697c478bd9Sstevel@tonic-gate *
35707c478bd9Sstevel@tonic-gate * SA Access framework allocated memory for the "results_p".
35717c478bd9Sstevel@tonic-gate * Make sure to deallocate once we are done with the results_p.
35727c478bd9Sstevel@tonic-gate * The size of the buffer allocated will be as returned in
35737c478bd9Sstevel@tonic-gate * "length" field.
35747c478bd9Sstevel@tonic-gate */
35757c478bd9Sstevel@tonic-gate access_args.sq_attr_id = SA_SERVICERECORD_ATTRID;
35767c478bd9Sstevel@tonic-gate access_args.sq_access_type = IBMF_SAA_RETRIEVE;
35777c478bd9Sstevel@tonic-gate access_args.sq_component_mask = component_mask;
35787c478bd9Sstevel@tonic-gate access_args.sq_template = &svcrec_req;
35797c478bd9Sstevel@tonic-gate access_args.sq_template_length = sizeof (sa_service_record_t);
35807c478bd9Sstevel@tonic-gate access_args.sq_callback = NULL;
35817c478bd9Sstevel@tonic-gate access_args.sq_callback_arg = NULL;
35827c478bd9Sstevel@tonic-gate
35837c478bd9Sstevel@tonic-gate retval = ibcm_contact_sa_access(saa_handle, &access_args, &length,
35847c478bd9Sstevel@tonic-gate &results_p);
35857c478bd9Sstevel@tonic-gate
35867c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
35877c478bd9Sstevel@tonic-gate if (retval != IBT_SUCCESS) {
35887c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_query_ar: SA Access Failed");
35897c478bd9Sstevel@tonic-gate return (retval);
35907c478bd9Sstevel@tonic-gate }
35917c478bd9Sstevel@tonic-gate
35927c478bd9Sstevel@tonic-gate num_rec = length / sizeof (sa_service_record_t);
35937c478bd9Sstevel@tonic-gate
35947c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_query_ar: "
35957c478bd9Sstevel@tonic-gate "Found %d Service Records.", num_rec);
35967c478bd9Sstevel@tonic-gate
35977c478bd9Sstevel@tonic-gate /* Validate the returned number of records. */
35987c478bd9Sstevel@tonic-gate if ((results_p != NULL) && (num_rec > 0)) {
35997c478bd9Sstevel@tonic-gate uint8_t *b;
36007c478bd9Sstevel@tonic-gate
36017c478bd9Sstevel@tonic-gate /* Just return info from the first service record. */
36027c478bd9Sstevel@tonic-gate svcrec_resp = (sa_service_record_t *)results_p;
36037c478bd9Sstevel@tonic-gate
36047c478bd9Sstevel@tonic-gate /* The Service GID and Service ID */
36057c478bd9Sstevel@tonic-gate resultp->ar_gid = svcrec_resp->ServiceGID;
36067c478bd9Sstevel@tonic-gate resultp->ar_pkey = svcrec_resp->ServiceP_Key;
36077c478bd9Sstevel@tonic-gate bcopy(svcrec_resp->ServiceData,
36087c478bd9Sstevel@tonic-gate resultp->ar_data, IBCM_DAPL_ATS_NBYTES);
36097c478bd9Sstevel@tonic-gate
3610d3a82192SShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibt_query_ar: "
36117c478bd9Sstevel@tonic-gate "Found: pkey %x dgid %llX:%llX", resultp->ar_pkey,
36127c478bd9Sstevel@tonic-gate (longlong_t)resultp->ar_gid.gid_prefix,
36137c478bd9Sstevel@tonic-gate (longlong_t)resultp->ar_gid.gid_guid);
36147c478bd9Sstevel@tonic-gate b = resultp->ar_data;
3615d3a82192SShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibt_query_ar:"
36167c478bd9Sstevel@tonic-gate " data %d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
36177c478bd9Sstevel@tonic-gate b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9],
36187c478bd9Sstevel@tonic-gate b[10], b[11], b[12], b[13], b[14], b[15]);
36197c478bd9Sstevel@tonic-gate
36207c478bd9Sstevel@tonic-gate /* Deallocate the memory for results_p. */
36217c478bd9Sstevel@tonic-gate kmem_free(results_p, length);
36227c478bd9Sstevel@tonic-gate if (num_rec > 1)
36237c478bd9Sstevel@tonic-gate retval = IBT_MULTIPLE_AR;
36247c478bd9Sstevel@tonic-gate else
36257c478bd9Sstevel@tonic-gate retval = IBT_SUCCESS;
36267c478bd9Sstevel@tonic-gate } else {
36277c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_query_ar: "
36287c478bd9Sstevel@tonic-gate "ibmf_sa_access found 0 matching records");
36297c478bd9Sstevel@tonic-gate retval = IBT_AR_NOT_REGISTERED;
36307c478bd9Sstevel@tonic-gate }
36317c478bd9Sstevel@tonic-gate return (retval);
36327c478bd9Sstevel@tonic-gate }
36337c478bd9Sstevel@tonic-gate
36347c478bd9Sstevel@tonic-gate /* mark all ATS service records associated with the port */
36357c478bd9Sstevel@tonic-gate static void
ibcm_mark_ar(ib_guid_t hca_guid,uint8_t port)36367c478bd9Sstevel@tonic-gate ibcm_mark_ar(ib_guid_t hca_guid, uint8_t port)
36377c478bd9Sstevel@tonic-gate {
36387c478bd9Sstevel@tonic-gate ibcm_ar_t *tmp;
36397c478bd9Sstevel@tonic-gate
36407c478bd9Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ibcm_svc_info_lock));
36417c478bd9Sstevel@tonic-gate for (tmp = ibcm_ar_list; tmp != NULL; tmp = tmp->ar_link) {
3642cd03c4aeSagiri if (tmp->ar_hcap == NULL)
3643cd03c4aeSagiri continue;
36447c478bd9Sstevel@tonic-gate if (tmp->ar_hcap->hca_guid == hca_guid &&
36457c478bd9Sstevel@tonic-gate tmp->ar_port == port) {
36467c478bd9Sstevel@tonic-gate /* even if it's busy, we mark it for rewrite */
36477c478bd9Sstevel@tonic-gate tmp->ar_rewrite_state = IBCM_REWRITE_NEEDED;
36487c478bd9Sstevel@tonic-gate }
36497c478bd9Sstevel@tonic-gate }
36507c478bd9Sstevel@tonic-gate }
36517c478bd9Sstevel@tonic-gate
36527c478bd9Sstevel@tonic-gate /* rewrite all ATS service records */
36537c478bd9Sstevel@tonic-gate static int
ibcm_rewrite_ar(void)36547c478bd9Sstevel@tonic-gate ibcm_rewrite_ar(void)
36557c478bd9Sstevel@tonic-gate {
36567c478bd9Sstevel@tonic-gate ibcm_ar_t *tmp;
36577c478bd9Sstevel@tonic-gate ibmf_saa_handle_t saa_handle;
36587c478bd9Sstevel@tonic-gate sa_service_record_t *srv_recp;
36597c478bd9Sstevel@tonic-gate ibt_status_t rval;
36607c478bd9Sstevel@tonic-gate int did_something = 0;
36617c478bd9Sstevel@tonic-gate
36627c478bd9Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ibcm_svc_info_lock));
36637c478bd9Sstevel@tonic-gate check_for_work:
36647c478bd9Sstevel@tonic-gate for (tmp = ibcm_ar_list; tmp != NULL; tmp = tmp->ar_link) {
36657c478bd9Sstevel@tonic-gate if (tmp->ar_rewrite_state == IBCM_REWRITE_NEEDED) {
36667c478bd9Sstevel@tonic-gate tmp->ar_rewrite_state = IBCM_REWRITE_BUSY;
36677c478bd9Sstevel@tonic-gate saa_handle = tmp->ar_saa_handle;
36687c478bd9Sstevel@tonic-gate srv_recp = tmp->ar_srv_recp;
36697c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
36707c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_rewrite_ar: "
36717c478bd9Sstevel@tonic-gate "rewriting ar @ %p", tmp);
36727c478bd9Sstevel@tonic-gate did_something = 1;
36737c478bd9Sstevel@tonic-gate rval = ibcm_write_service_record(saa_handle, srv_recp,
36747c478bd9Sstevel@tonic-gate IBMF_SAA_UPDATE);
36757c478bd9Sstevel@tonic-gate if (rval != IBT_SUCCESS)
36767c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_rewrite_ar: "
36777c478bd9Sstevel@tonic-gate "ibcm_write_service_record failed: "
36787c478bd9Sstevel@tonic-gate "status = %d", rval);
36797c478bd9Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
36807c478bd9Sstevel@tonic-gate /* if it got marked again, then we want to rewrite */
36817c478bd9Sstevel@tonic-gate if (tmp->ar_rewrite_state == IBCM_REWRITE_BUSY)
36827c478bd9Sstevel@tonic-gate tmp->ar_rewrite_state = IBCM_REWRITE_IDLE;
36837c478bd9Sstevel@tonic-gate /* in case there was a waiter... */
36847c478bd9Sstevel@tonic-gate cv_broadcast(&ibcm_svc_info_cv);
36857c478bd9Sstevel@tonic-gate goto check_for_work;
36867c478bd9Sstevel@tonic-gate }
36877c478bd9Sstevel@tonic-gate }
36887c478bd9Sstevel@tonic-gate return (did_something);
36897c478bd9Sstevel@tonic-gate }
36907c478bd9Sstevel@tonic-gate
36917c478bd9Sstevel@tonic-gate static void
ibcm_rewrite_svc_record(ibcm_svc_info_t * srv_hdl,ibcm_svc_bind_t * sbindp)36927c478bd9Sstevel@tonic-gate ibcm_rewrite_svc_record(ibcm_svc_info_t *srv_hdl, ibcm_svc_bind_t *sbindp)
36937c478bd9Sstevel@tonic-gate {
36947c478bd9Sstevel@tonic-gate ibcm_hca_info_t *hcap;
36957c478bd9Sstevel@tonic-gate ib_svc_id_t sid, start_sid, end_sid;
36967c478bd9Sstevel@tonic-gate ibmf_saa_handle_t saa_handle;
36977c478bd9Sstevel@tonic-gate sa_service_record_t srv_rec;
36987c478bd9Sstevel@tonic-gate ibt_status_t rval;
36997c478bd9Sstevel@tonic-gate
37007c478bd9Sstevel@tonic-gate hcap = ibcm_find_hca_entry(sbindp->sbind_hcaguid);
37017c478bd9Sstevel@tonic-gate if (hcap == NULL) {
37027c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_rewrite_svc_record: "
37037c478bd9Sstevel@tonic-gate "NO HCA found for HCA GUID %llX", sbindp->sbind_hcaguid);
37047c478bd9Sstevel@tonic-gate return;
37057c478bd9Sstevel@tonic-gate }
37067c478bd9Sstevel@tonic-gate
37077c478bd9Sstevel@tonic-gate saa_handle = ibcm_get_saa_handle(hcap, sbindp->sbind_port);
37087c478bd9Sstevel@tonic-gate if (saa_handle == NULL) {
37097c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_rewrite_svc_record: "
37107c478bd9Sstevel@tonic-gate "saa_handle is NULL");
37117c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
37127c478bd9Sstevel@tonic-gate return;
37137c478bd9Sstevel@tonic-gate }
37147c478bd9Sstevel@tonic-gate
37157c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_rewrite_svc_record: "
37167c478bd9Sstevel@tonic-gate "rewriting svc '%s', port_guid = %llX", sbindp->sbind_name,
37177c478bd9Sstevel@tonic-gate sbindp->sbind_gid.gid_guid);
37187c478bd9Sstevel@tonic-gate
37197c478bd9Sstevel@tonic-gate bzero(&srv_rec, sizeof (srv_rec));
37207c478bd9Sstevel@tonic-gate
37217c478bd9Sstevel@tonic-gate srv_rec.ServiceLease = sbindp->sbind_lease;
37227c478bd9Sstevel@tonic-gate srv_rec.ServiceP_Key = sbindp->sbind_pkey;
37237c478bd9Sstevel@tonic-gate srv_rec.ServiceKey_hi = sbindp->sbind_key[0];
37247c478bd9Sstevel@tonic-gate srv_rec.ServiceKey_lo = sbindp->sbind_key[1];
37257c478bd9Sstevel@tonic-gate (void) strcpy((char *)srv_rec.ServiceName, sbindp->sbind_name);
37267c478bd9Sstevel@tonic-gate srv_rec.ServiceGID = sbindp->sbind_gid;
37277c478bd9Sstevel@tonic-gate
37287c478bd9Sstevel@tonic-gate bcopy(sbindp->sbind_data, srv_rec.ServiceData, IB_SVC_DATA_LEN);
37297c478bd9Sstevel@tonic-gate
37307c478bd9Sstevel@tonic-gate /* insert srv record into the SA */
37317c478bd9Sstevel@tonic-gate start_sid = srv_hdl->svc_id;
37327c478bd9Sstevel@tonic-gate end_sid = start_sid + srv_hdl->svc_num_sids - 1;
37337c478bd9Sstevel@tonic-gate for (sid = start_sid; sid <= end_sid; sid++) {
37347c478bd9Sstevel@tonic-gate srv_rec.ServiceID = sid;
37357c478bd9Sstevel@tonic-gate
37367c478bd9Sstevel@tonic-gate rval = ibcm_write_service_record(saa_handle, &srv_rec,
37377c478bd9Sstevel@tonic-gate IBMF_SAA_UPDATE);
37387c478bd9Sstevel@tonic-gate
37397c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_rewrite_svc_record: "
37407c478bd9Sstevel@tonic-gate "ibcm_write_service_record, SvcId = %llX, "
37417c478bd9Sstevel@tonic-gate "rval = %d", (longlong_t)sid, rval);
37427c478bd9Sstevel@tonic-gate if (rval != IBT_SUCCESS) {
37437c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_rewrite_svc_record:"
37447c478bd9Sstevel@tonic-gate " ibcm_write_service_record fails %d sid %llX",
37457c478bd9Sstevel@tonic-gate rval, (longlong_t)sid);
37467c478bd9Sstevel@tonic-gate }
37477c478bd9Sstevel@tonic-gate }
37487c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
37497c478bd9Sstevel@tonic-gate }
37507c478bd9Sstevel@tonic-gate
37517c478bd9Sstevel@tonic-gate /*
37527c478bd9Sstevel@tonic-gate * Task to mark all service records as needing to be rewritten to the SM/SA.
37537c478bd9Sstevel@tonic-gate * This task does not return until all of them have been rewritten.
37547c478bd9Sstevel@tonic-gate */
37557c478bd9Sstevel@tonic-gate void
ibcm_service_record_rewrite_task(void * arg)37567c478bd9Sstevel@tonic-gate ibcm_service_record_rewrite_task(void *arg)
37577c478bd9Sstevel@tonic-gate {
37587c478bd9Sstevel@tonic-gate ibcm_port_up_t *pup = (ibcm_port_up_t *)arg;
37597c478bd9Sstevel@tonic-gate ib_guid_t hca_guid = pup->pup_hca_guid;
37607c478bd9Sstevel@tonic-gate uint8_t port = pup->pup_port;
37617c478bd9Sstevel@tonic-gate ibcm_svc_info_t *svcp;
37627c478bd9Sstevel@tonic-gate ibcm_svc_bind_t *sbp;
37637c478bd9Sstevel@tonic-gate avl_tree_t *avl_tree = &ibcm_svc_avl_tree;
37647c478bd9Sstevel@tonic-gate static int task_is_running = 0;
37657c478bd9Sstevel@tonic-gate
3766d3a82192SShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibcm_service_record_rewrite_task STARTED "
37677c478bd9Sstevel@tonic-gate "for hca_guid %llX, port %d", hca_guid, port);
37687c478bd9Sstevel@tonic-gate
37697c478bd9Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
37707c478bd9Sstevel@tonic-gate ibcm_mark_ar(hca_guid, port);
37717c478bd9Sstevel@tonic-gate for (svcp = avl_first(avl_tree); svcp != NULL;
37727c478bd9Sstevel@tonic-gate svcp = avl_walk(avl_tree, svcp, AVL_AFTER)) {
37737c478bd9Sstevel@tonic-gate sbp = svcp->svc_bind_list;
37747c478bd9Sstevel@tonic-gate while (sbp != NULL) {
37757c478bd9Sstevel@tonic-gate if (sbp->sbind_pkey != 0 &&
37767c478bd9Sstevel@tonic-gate sbp->sbind_port == port &&
37777c478bd9Sstevel@tonic-gate sbp->sbind_hcaguid == hca_guid) {
37787c478bd9Sstevel@tonic-gate /* even if it's busy, we mark it for rewrite */
37797c478bd9Sstevel@tonic-gate sbp->sbind_rewrite_state = IBCM_REWRITE_NEEDED;
37807c478bd9Sstevel@tonic-gate }
37817c478bd9Sstevel@tonic-gate sbp = sbp->sbind_link;
37827c478bd9Sstevel@tonic-gate }
37837c478bd9Sstevel@tonic-gate }
37847c478bd9Sstevel@tonic-gate if (task_is_running) {
37857c478bd9Sstevel@tonic-gate /* let the other task thread finish the work */
37867c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
37877c478bd9Sstevel@tonic-gate return;
37887c478bd9Sstevel@tonic-gate }
37897c478bd9Sstevel@tonic-gate task_is_running = 1;
37907c478bd9Sstevel@tonic-gate
37917c478bd9Sstevel@tonic-gate (void) ibcm_rewrite_ar();
37927c478bd9Sstevel@tonic-gate
37937c478bd9Sstevel@tonic-gate check_for_work:
37947c478bd9Sstevel@tonic-gate for (svcp = avl_first(avl_tree); svcp != NULL;
37957c478bd9Sstevel@tonic-gate svcp = avl_walk(avl_tree, svcp, AVL_AFTER)) {
37967c478bd9Sstevel@tonic-gate sbp = svcp->svc_bind_list;
37977c478bd9Sstevel@tonic-gate while (sbp != NULL) {
37987c478bd9Sstevel@tonic-gate if (sbp->sbind_rewrite_state == IBCM_REWRITE_NEEDED) {
37997c478bd9Sstevel@tonic-gate sbp->sbind_rewrite_state = IBCM_REWRITE_BUSY;
38007c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
38017c478bd9Sstevel@tonic-gate ibcm_rewrite_svc_record(svcp, sbp);
38027c478bd9Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
38037c478bd9Sstevel@tonic-gate /* if it got marked again, we want to rewrite */
38047c478bd9Sstevel@tonic-gate if (sbp->sbind_rewrite_state ==
38057c478bd9Sstevel@tonic-gate IBCM_REWRITE_BUSY)
38067c478bd9Sstevel@tonic-gate sbp->sbind_rewrite_state =
38077c478bd9Sstevel@tonic-gate IBCM_REWRITE_IDLE;
38087c478bd9Sstevel@tonic-gate /* in case there was a waiter... */
38097c478bd9Sstevel@tonic-gate cv_broadcast(&ibcm_svc_info_cv);
38107c478bd9Sstevel@tonic-gate goto check_for_work;
38117c478bd9Sstevel@tonic-gate }
38127c478bd9Sstevel@tonic-gate sbp = sbp->sbind_link;
38137c478bd9Sstevel@tonic-gate }
38147c478bd9Sstevel@tonic-gate }
38157c478bd9Sstevel@tonic-gate /*
38167c478bd9Sstevel@tonic-gate * If there were no service records to write, and we failed to
38177c478bd9Sstevel@tonic-gate * have to rewrite any more ATS service records, then we're done.
38187c478bd9Sstevel@tonic-gate */
38197c478bd9Sstevel@tonic-gate if (ibcm_rewrite_ar() != 0)
38207c478bd9Sstevel@tonic-gate goto check_for_work;
38217c478bd9Sstevel@tonic-gate task_is_running = 0;
38227c478bd9Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
38237c478bd9Sstevel@tonic-gate
3824d3a82192SShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibcm_service_record_rewrite_task DONE");
38257c478bd9Sstevel@tonic-gate kmem_free(pup, sizeof (ibcm_port_up_t));
38267c478bd9Sstevel@tonic-gate }
38277c478bd9Sstevel@tonic-gate
3828f07a6d2aSShantkumar Hiremath ibt_status_t
ibt_ofuvcm_get_req_data(void * session_id,ibt_ofuvcm_req_data_t * req_data)3829f07a6d2aSShantkumar Hiremath ibt_ofuvcm_get_req_data(void *session_id, ibt_ofuvcm_req_data_t *req_data)
3830f07a6d2aSShantkumar Hiremath {
3831f07a6d2aSShantkumar Hiremath ibcm_state_data_t *statep = (ibcm_state_data_t *)session_id;
3832f07a6d2aSShantkumar Hiremath ibcm_req_msg_t *req_msgp;
3833f07a6d2aSShantkumar Hiremath
3834f07a6d2aSShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibt_get_ofuvcm_req_data: session_id %p",
3835f07a6d2aSShantkumar Hiremath session_id);
3836f07a6d2aSShantkumar Hiremath mutex_enter(&statep->state_mutex);
3837f07a6d2aSShantkumar Hiremath if ((statep->state != IBCM_STATE_REQ_RCVD) &&
3838f07a6d2aSShantkumar Hiremath (statep->state != IBCM_STATE_MRA_SENT)) {
3839f07a6d2aSShantkumar Hiremath IBTF_DPRINTF_L2(cmlog, "ibt_get_ofuvcm_req_data: Invalid "
3840f07a6d2aSShantkumar Hiremath "State %x", statep->state);
3841f07a6d2aSShantkumar Hiremath mutex_exit(&statep->state_mutex);
3842f07a6d2aSShantkumar Hiremath return (IBT_CHAN_STATE_INVALID);
3843f07a6d2aSShantkumar Hiremath }
3844f07a6d2aSShantkumar Hiremath if (statep->mode == IBCM_ACTIVE_MODE) {
3845f07a6d2aSShantkumar Hiremath IBTF_DPRINTF_L2(cmlog, "ibt_get_ofuvcm_req_data: Active mode "
3846f07a6d2aSShantkumar Hiremath "not supported");
3847f07a6d2aSShantkumar Hiremath mutex_exit(&statep->state_mutex);
3848f07a6d2aSShantkumar Hiremath return (IBT_INVALID_PARAM);
3849f07a6d2aSShantkumar Hiremath }
3850f07a6d2aSShantkumar Hiremath ASSERT(statep->req_msgp);
3851f07a6d2aSShantkumar Hiremath
3852f07a6d2aSShantkumar Hiremath /*
3853f07a6d2aSShantkumar Hiremath * Fill in the additional req message values reqired for
3854f07a6d2aSShantkumar Hiremath * RTR transition.
3855f07a6d2aSShantkumar Hiremath * Should the PSN be same as the active side??
3856f07a6d2aSShantkumar Hiremath */
3857f07a6d2aSShantkumar Hiremath req_msgp = (ibcm_req_msg_t *)statep->req_msgp;
3858f07a6d2aSShantkumar Hiremath req_data->req_rnr_nak_time = ibcm_default_rnr_nak_time;
3859f07a6d2aSShantkumar Hiremath req_data->req_path_mtu = req_msgp->req_mtu_plus >> 4;
3860f07a6d2aSShantkumar Hiremath req_data->req_rq_psn = b2h32(req_msgp->req_starting_psn_plus) >> 8;
3861f07a6d2aSShantkumar Hiremath mutex_exit(&statep->state_mutex);
3862f07a6d2aSShantkumar Hiremath return (IBT_SUCCESS);
3863f07a6d2aSShantkumar Hiremath }
3864f07a6d2aSShantkumar Hiremath
3865f07a6d2aSShantkumar Hiremath ibt_status_t
ibt_ofuvcm_proceed(ibt_cm_event_type_t event,void * session_id,ibt_cm_status_t status,ibt_cm_proceed_reply_t * cm_event_data,void * priv_data,ibt_priv_data_len_t priv_data_len)3866f07a6d2aSShantkumar Hiremath ibt_ofuvcm_proceed(ibt_cm_event_type_t event, void *session_id,
3867f07a6d2aSShantkumar Hiremath ibt_cm_status_t status, ibt_cm_proceed_reply_t *cm_event_data,
3868f07a6d2aSShantkumar Hiremath void *priv_data, ibt_priv_data_len_t priv_data_len)
3869f07a6d2aSShantkumar Hiremath {
3870f07a6d2aSShantkumar Hiremath ibcm_state_data_t *statep = (ibcm_state_data_t *)session_id;
3871f07a6d2aSShantkumar Hiremath ibt_status_t ret;
3872f07a6d2aSShantkumar Hiremath
3873f07a6d2aSShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibt_ofuvcm_proceed chan 0x%p event %x "
3874f07a6d2aSShantkumar Hiremath "status %x session_id %p", statep->channel, event, status,
3875f07a6d2aSShantkumar Hiremath session_id);
3876f07a6d2aSShantkumar Hiremath
3877f07a6d2aSShantkumar Hiremath IBTF_DPRINTF_L5(cmlog, "ibt_ofuvcm_proceed chan 0x%p "
3878f07a6d2aSShantkumar Hiremath "cm_event_data %p, priv_data %p priv_data_len %x",
3879f07a6d2aSShantkumar Hiremath statep->channel, cm_event_data, priv_data, priv_data_len);
3880f07a6d2aSShantkumar Hiremath
3881f07a6d2aSShantkumar Hiremath /* validate session_id and status */
3882f07a6d2aSShantkumar Hiremath if ((statep == NULL) || (status == IBT_CM_DEFER)) {
3883f07a6d2aSShantkumar Hiremath IBTF_DPRINTF_L2(cmlog, "ibt_ofuvcm_proceed : Invalid Args");
3884f07a6d2aSShantkumar Hiremath return (IBT_INVALID_PARAM);
3885f07a6d2aSShantkumar Hiremath }
3886f07a6d2aSShantkumar Hiremath
3887f07a6d2aSShantkumar Hiremath if (event != IBT_CM_EVENT_REQ_RCV) {
3888f07a6d2aSShantkumar Hiremath IBTF_DPRINTF_L2(cmlog, "ibt_ofuvcm_proceed : only for REQ_RCV");
3889f07a6d2aSShantkumar Hiremath return (IBT_INVALID_PARAM);
3890f07a6d2aSShantkumar Hiremath }
3891f07a6d2aSShantkumar Hiremath mutex_enter(&statep->state_mutex);
38929c468ea9SPramod Gunjikar statep->is_this_ofuv_chan = B_TRUE;
3893f07a6d2aSShantkumar Hiremath mutex_exit(&statep->state_mutex);
3894f07a6d2aSShantkumar Hiremath
3895f07a6d2aSShantkumar Hiremath ret = ibt_cm_proceed(event, session_id, status, cm_event_data,
3896f07a6d2aSShantkumar Hiremath priv_data, priv_data_len);
3897f07a6d2aSShantkumar Hiremath return (ret);
3898f07a6d2aSShantkumar Hiremath }
38997c478bd9Sstevel@tonic-gate
39007c478bd9Sstevel@tonic-gate /*
39017c478bd9Sstevel@tonic-gate * Function:
39027c478bd9Sstevel@tonic-gate * ibt_cm_proceed
39037c478bd9Sstevel@tonic-gate *
39047c478bd9Sstevel@tonic-gate * Verifies the arguments and dispatches the cm state machine processing
39057c478bd9Sstevel@tonic-gate * via taskq
39067c478bd9Sstevel@tonic-gate */
39077c478bd9Sstevel@tonic-gate
39087c478bd9Sstevel@tonic-gate ibt_status_t
ibt_cm_proceed(ibt_cm_event_type_t event,void * session_id,ibt_cm_status_t status,ibt_cm_proceed_reply_t * cm_event_data,void * priv_data,ibt_priv_data_len_t priv_data_len)39097c478bd9Sstevel@tonic-gate ibt_cm_proceed(ibt_cm_event_type_t event, void *session_id,
39107c478bd9Sstevel@tonic-gate ibt_cm_status_t status, ibt_cm_proceed_reply_t *cm_event_data,
39117c478bd9Sstevel@tonic-gate void *priv_data, ibt_priv_data_len_t priv_data_len)
39127c478bd9Sstevel@tonic-gate {
39137c478bd9Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)session_id;
39147c478bd9Sstevel@tonic-gate ibcm_proceed_targs_t *proceed_targs;
39157c478bd9Sstevel@tonic-gate ibcm_proceed_error_t proceed_error;
39167c478bd9Sstevel@tonic-gate
39177c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_cm_proceed chan 0x%p event %x status %x "
39187c478bd9Sstevel@tonic-gate "session_id %p", statep->channel, event, status, session_id);
39197c478bd9Sstevel@tonic-gate
39207c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_cm_proceed chan 0x%p cm_event_data %p, "
39217c478bd9Sstevel@tonic-gate "priv_data %p priv_data_len %x", statep->channel, cm_event_data,
39227c478bd9Sstevel@tonic-gate priv_data, priv_data_len);
39237c478bd9Sstevel@tonic-gate
39247c478bd9Sstevel@tonic-gate /* validate session_id and status */
39257c478bd9Sstevel@tonic-gate if ((statep == NULL) || (status == IBT_CM_DEFER)) {
39267c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_cm_proceed : Invalid Args");
39277c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
39287c478bd9Sstevel@tonic-gate }
39297c478bd9Sstevel@tonic-gate
39307c478bd9Sstevel@tonic-gate /* If priv data len specified, then priv_data cannot be NULL */
39317c478bd9Sstevel@tonic-gate if ((priv_data_len > 0) && (priv_data == NULL))
39327c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
39337c478bd9Sstevel@tonic-gate
39347c478bd9Sstevel@tonic-gate proceed_error = IBCM_PROCEED_INVALID_NONE;
39357c478bd9Sstevel@tonic-gate
39367c478bd9Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
39377c478bd9Sstevel@tonic-gate if (event == IBT_CM_EVENT_REQ_RCV) {
39387c478bd9Sstevel@tonic-gate
39397c478bd9Sstevel@tonic-gate if ((statep->state != IBCM_STATE_REQ_RCVD) &&
39407c478bd9Sstevel@tonic-gate (statep->state != IBCM_STATE_MRA_SENT))
39417c478bd9Sstevel@tonic-gate proceed_error = IBCM_PROCEED_INVALID_EVENT_STATE;
39427c478bd9Sstevel@tonic-gate else if (priv_data_len > IBT_REP_PRIV_DATA_SZ)
39437c478bd9Sstevel@tonic-gate proceed_error = IBCM_PROCEED_INVALID_PRIV_SZ;
39447c478bd9Sstevel@tonic-gate
39457c478bd9Sstevel@tonic-gate } else if (event == IBT_CM_EVENT_REP_RCV) {
39467c478bd9Sstevel@tonic-gate if ((statep->state != IBCM_STATE_REP_RCVD) &&
39477c478bd9Sstevel@tonic-gate (statep->state != IBCM_STATE_MRA_REP_SENT))
39487c478bd9Sstevel@tonic-gate proceed_error = IBCM_PROCEED_INVALID_EVENT_STATE;
39497c478bd9Sstevel@tonic-gate else if (priv_data_len > IBT_RTU_PRIV_DATA_SZ)
39507c478bd9Sstevel@tonic-gate proceed_error = IBCM_PROCEED_INVALID_PRIV_SZ;
39517c478bd9Sstevel@tonic-gate } else if (event == IBT_CM_EVENT_LAP_RCV) {
39527c478bd9Sstevel@tonic-gate if ((statep->ap_state != IBCM_AP_STATE_LAP_RCVD) &&
39537c478bd9Sstevel@tonic-gate (statep->ap_state != IBCM_AP_STATE_MRA_LAP_SENT))
39547c478bd9Sstevel@tonic-gate proceed_error = IBCM_PROCEED_INVALID_EVENT_STATE;
39557c478bd9Sstevel@tonic-gate else if (priv_data_len > IBT_APR_PRIV_DATA_SZ)
39567c478bd9Sstevel@tonic-gate proceed_error = IBCM_PROCEED_INVALID_PRIV_SZ;
39577c478bd9Sstevel@tonic-gate } else if (event == IBT_CM_EVENT_CONN_CLOSED) {
39587c478bd9Sstevel@tonic-gate if (statep->state != IBCM_STATE_DREQ_RCVD)
39597c478bd9Sstevel@tonic-gate proceed_error = IBCM_PROCEED_INVALID_EVENT_STATE;
39607c478bd9Sstevel@tonic-gate else if (priv_data_len > IBT_DREP_PRIV_DATA_SZ)
39617c478bd9Sstevel@tonic-gate proceed_error = IBCM_PROCEED_INVALID_PRIV_SZ;
39627c478bd9Sstevel@tonic-gate } else {
39637c478bd9Sstevel@tonic-gate proceed_error = IBCM_PROCEED_INVALID_EVENT;
39647c478bd9Sstevel@tonic-gate }
39657c478bd9Sstevel@tonic-gate
39667c478bd9Sstevel@tonic-gate /* if there is an error, print an error message and return */
39677c478bd9Sstevel@tonic-gate if (proceed_error != IBCM_PROCEED_INVALID_NONE) {
39687c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
39697c478bd9Sstevel@tonic-gate if (proceed_error == IBCM_PROCEED_INVALID_EVENT_STATE) {
39707c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_cm_proceed : chan 0x%p"
39717c478bd9Sstevel@tonic-gate "Invalid Event/State combination specified",
39727c478bd9Sstevel@tonic-gate statep->channel);
39737c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
39747c478bd9Sstevel@tonic-gate } else if (proceed_error == IBCM_PROCEED_INVALID_PRIV_SZ) {
39757c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_cm_proceed : chan 0x%p"
39767c478bd9Sstevel@tonic-gate "Invalid Event/priv len combination specified",
39777c478bd9Sstevel@tonic-gate statep->channel);
39787c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
39797c478bd9Sstevel@tonic-gate } else if (proceed_error == IBCM_PROCEED_INVALID_EVENT) {
39807c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_cm_proceed : chan 0x%p"
39817c478bd9Sstevel@tonic-gate "Invalid Event specified", statep->channel);
39827c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
39837c478bd9Sstevel@tonic-gate } else {
39847c478bd9Sstevel@tonic-gate ASSERT(proceed_error == IBCM_PROCEED_INVALID_LAP);
39857c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_cm_proceed : chan 0x%p"
39867c478bd9Sstevel@tonic-gate "IBT_CM_EVENT_LAP_RCV not supported",
39877c478bd9Sstevel@tonic-gate statep->channel);
39887c478bd9Sstevel@tonic-gate /* UNTIL HCA DRIVER ENABLES AP SUPPORT, FAIL THE CALL */
39897c478bd9Sstevel@tonic-gate return (IBT_APM_NOT_SUPPORTED);
39907c478bd9Sstevel@tonic-gate }
39917c478bd9Sstevel@tonic-gate }
39927c478bd9Sstevel@tonic-gate
39937c478bd9Sstevel@tonic-gate
39947c478bd9Sstevel@tonic-gate /* wait until client's CM handler returns DEFER status back to CM */
39957c478bd9Sstevel@tonic-gate
39967c478bd9Sstevel@tonic-gate while (statep->clnt_proceed == IBCM_BLOCK) {
39977c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_cm_proceed : chan 0x%p blocked for "
39987c478bd9Sstevel@tonic-gate "return of client's cm handler", statep->channel);
39997c478bd9Sstevel@tonic-gate cv_wait(&statep->block_client_cv, &statep->state_mutex);
40007c478bd9Sstevel@tonic-gate }
40017c478bd9Sstevel@tonic-gate
40027c478bd9Sstevel@tonic-gate if (statep->clnt_proceed == IBCM_FAIL) {
40037c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
40047c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_cm_proceed : chan 0x%p Failed as "
40057c478bd9Sstevel@tonic-gate "client returned non-DEFER status from cm handler",
40067c478bd9Sstevel@tonic-gate statep->channel);
40077c478bd9Sstevel@tonic-gate return (IBT_CHAN_STATE_INVALID);
40087c478bd9Sstevel@tonic-gate }
40097c478bd9Sstevel@tonic-gate
40107c478bd9Sstevel@tonic-gate ASSERT(statep->clnt_proceed == IBCM_UNBLOCK);
40117c478bd9Sstevel@tonic-gate statep->clnt_proceed = IBCM_FAIL;
40127c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
40137c478bd9Sstevel@tonic-gate
40147c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*proceed_targs))
40157c478bd9Sstevel@tonic-gate
40167c478bd9Sstevel@tonic-gate /* the state machine processing is done in a separate thread */
40177c478bd9Sstevel@tonic-gate
40187c478bd9Sstevel@tonic-gate /* proceed_targs is freed in ibcm_proceed_via_taskq */
40197c478bd9Sstevel@tonic-gate proceed_targs = kmem_alloc(sizeof (ibcm_proceed_targs_t),
40207c478bd9Sstevel@tonic-gate KM_SLEEP);
40217c478bd9Sstevel@tonic-gate
40227c478bd9Sstevel@tonic-gate proceed_targs->event = event;
40237c478bd9Sstevel@tonic-gate proceed_targs->status = status;
40247c478bd9Sstevel@tonic-gate proceed_targs->priv_data_len = priv_data_len;
40257c478bd9Sstevel@tonic-gate
40267c478bd9Sstevel@tonic-gate bcopy(priv_data, proceed_targs->priv_data, priv_data_len);
40277c478bd9Sstevel@tonic-gate
40287c478bd9Sstevel@tonic-gate proceed_targs->tst.rc.statep = statep;
40297c478bd9Sstevel@tonic-gate bcopy(cm_event_data, &proceed_targs->tst.rc.rc_cm_event_data,
40307c478bd9Sstevel@tonic-gate sizeof (ibt_cm_proceed_reply_t));
40317c478bd9Sstevel@tonic-gate
40327c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*proceed_targs))
40337c478bd9Sstevel@tonic-gate
40347c478bd9Sstevel@tonic-gate (void) taskq_dispatch(ibcm_taskq, ibcm_proceed_via_taskq,
40357c478bd9Sstevel@tonic-gate proceed_targs, TQ_SLEEP);
40367c478bd9Sstevel@tonic-gate
40377c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
40387c478bd9Sstevel@tonic-gate }
40397c478bd9Sstevel@tonic-gate
40407c478bd9Sstevel@tonic-gate /*
40417c478bd9Sstevel@tonic-gate * Function:
40427c478bd9Sstevel@tonic-gate * ibcm_proceed_via_taskq
40437c478bd9Sstevel@tonic-gate *
40447c478bd9Sstevel@tonic-gate * Called from taskq, dispatched by ibt_cm_proceed
40457c478bd9Sstevel@tonic-gate * Completes the cm state processing for ibt_cm_proceed
40467c478bd9Sstevel@tonic-gate */
40477c478bd9Sstevel@tonic-gate void
ibcm_proceed_via_taskq(void * targs)40487c478bd9Sstevel@tonic-gate ibcm_proceed_via_taskq(void *targs)
40497c478bd9Sstevel@tonic-gate {
40507c478bd9Sstevel@tonic-gate ibcm_proceed_targs_t *proceed_targs = (ibcm_proceed_targs_t *)targs;
40517c478bd9Sstevel@tonic-gate ibcm_state_data_t *statep = proceed_targs->tst.rc.statep;
40527c478bd9Sstevel@tonic-gate ibt_cm_reason_t reject_reason;
40537c478bd9Sstevel@tonic-gate uint8_t arej_len;
40547c478bd9Sstevel@tonic-gate ibcm_status_t response;
40557c478bd9Sstevel@tonic-gate ibcm_clnt_reply_info_t clnt_info;
40567c478bd9Sstevel@tonic-gate
40577c478bd9Sstevel@tonic-gate clnt_info.reply_event = &proceed_targs->tst.rc.rc_cm_event_data;
40587c478bd9Sstevel@tonic-gate clnt_info.priv_data = proceed_targs->priv_data;
40597c478bd9Sstevel@tonic-gate clnt_info.priv_data_len = proceed_targs->priv_data_len;
40607c478bd9Sstevel@tonic-gate
40617c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_proceed_via_taskq chan 0x%p targs %x",
40627c478bd9Sstevel@tonic-gate statep->channel, targs);
40637c478bd9Sstevel@tonic-gate
40647c478bd9Sstevel@tonic-gate if (proceed_targs->event == IBT_CM_EVENT_REQ_RCV) {
40657c478bd9Sstevel@tonic-gate response =
40667c478bd9Sstevel@tonic-gate ibcm_process_cep_req_cm_hdlr(statep, proceed_targs->status,
40677c478bd9Sstevel@tonic-gate &clnt_info, &reject_reason, &arej_len,
40687c478bd9Sstevel@tonic-gate (ibcm_req_msg_t *)statep->defer_cm_msg);
40697c478bd9Sstevel@tonic-gate
40707c478bd9Sstevel@tonic-gate ibcm_handle_cep_req_response(statep, response, reject_reason,
40717c478bd9Sstevel@tonic-gate arej_len);
40727c478bd9Sstevel@tonic-gate
40737c478bd9Sstevel@tonic-gate } else if (proceed_targs->event == IBT_CM_EVENT_REP_RCV) {
40747c478bd9Sstevel@tonic-gate response =
40757c478bd9Sstevel@tonic-gate ibcm_process_cep_rep_cm_hdlr(statep, proceed_targs->status,
40767c478bd9Sstevel@tonic-gate &clnt_info, &reject_reason, &arej_len,
40777c478bd9Sstevel@tonic-gate (ibcm_rep_msg_t *)statep->defer_cm_msg);
40787c478bd9Sstevel@tonic-gate
40797c478bd9Sstevel@tonic-gate ibcm_handle_cep_rep_response(statep, response, reject_reason,
40807c478bd9Sstevel@tonic-gate arej_len, (ibcm_rep_msg_t *)statep->defer_cm_msg);
40817c478bd9Sstevel@tonic-gate
40827c478bd9Sstevel@tonic-gate } else if (proceed_targs->event == IBT_CM_EVENT_LAP_RCV) {
40837c478bd9Sstevel@tonic-gate ibcm_process_cep_lap_cm_hdlr(statep, proceed_targs->status,
40847c478bd9Sstevel@tonic-gate &clnt_info, (ibcm_lap_msg_t *)statep->defer_cm_msg,
40857c478bd9Sstevel@tonic-gate (ibcm_apr_msg_t *)IBCM_OUT_MSGP(statep->lapr_msg));
40867c478bd9Sstevel@tonic-gate
40877c478bd9Sstevel@tonic-gate ibcm_post_apr_mad(statep);
40887c478bd9Sstevel@tonic-gate
40897c478bd9Sstevel@tonic-gate } else {
40907c478bd9Sstevel@tonic-gate ASSERT(proceed_targs->event == IBT_CM_EVENT_CONN_CLOSED);
40917c478bd9Sstevel@tonic-gate ibcm_handle_cep_dreq_response(statep, proceed_targs->priv_data,
40927c478bd9Sstevel@tonic-gate proceed_targs->priv_data_len);
40937c478bd9Sstevel@tonic-gate }
40947c478bd9Sstevel@tonic-gate
40957c478bd9Sstevel@tonic-gate kmem_free(targs, sizeof (ibcm_proceed_targs_t));
40967c478bd9Sstevel@tonic-gate }
40977c478bd9Sstevel@tonic-gate
40987c478bd9Sstevel@tonic-gate /*
40997c478bd9Sstevel@tonic-gate * Function:
41007c478bd9Sstevel@tonic-gate * ibt_cm_ud_proceed
41017c478bd9Sstevel@tonic-gate *
41027c478bd9Sstevel@tonic-gate * Verifies the arguments and dispatches the cm state machine processing
41037c478bd9Sstevel@tonic-gate * via taskq
41047c478bd9Sstevel@tonic-gate */
41057c478bd9Sstevel@tonic-gate ibt_status_t
ibt_cm_ud_proceed(void * session_id,ibt_channel_hdl_t ud_channel,ibt_cm_status_t status,ibt_redirect_info_t * redirect_infop,void * priv_data,ibt_priv_data_len_t priv_data_len)41067c478bd9Sstevel@tonic-gate ibt_cm_ud_proceed(void *session_id, ibt_channel_hdl_t ud_channel,
41077c478bd9Sstevel@tonic-gate ibt_cm_status_t status, ibt_redirect_info_t *redirect_infop,
41087c478bd9Sstevel@tonic-gate void *priv_data, ibt_priv_data_len_t priv_data_len)
41097c478bd9Sstevel@tonic-gate {
41107c478bd9Sstevel@tonic-gate ibcm_ud_state_data_t *ud_statep = (ibcm_ud_state_data_t *)session_id;
41117c478bd9Sstevel@tonic-gate ibcm_proceed_targs_t *proceed_targs;
41127c478bd9Sstevel@tonic-gate ibt_qp_query_attr_t qp_attr;
41137c478bd9Sstevel@tonic-gate ibt_status_t retval;
41147c478bd9Sstevel@tonic-gate
41157c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_cm_ud_proceed session_id %p "
41167c478bd9Sstevel@tonic-gate "ud_channel %p ", session_id, ud_channel);
41177c478bd9Sstevel@tonic-gate
41187c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_cm_ud_proceed status %x priv_data %p "
41197c478bd9Sstevel@tonic-gate "priv_data_len %x", status, priv_data, priv_data_len);
41207c478bd9Sstevel@tonic-gate
41217c478bd9Sstevel@tonic-gate /* validate session_id and status */
41227c478bd9Sstevel@tonic-gate if ((ud_statep == NULL) || (status == IBT_CM_DEFER)) {
41237c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_cm_ud_proceed : Invalid Args");
41247c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
41257c478bd9Sstevel@tonic-gate }
41267c478bd9Sstevel@tonic-gate
41277c478bd9Sstevel@tonic-gate /* If priv data len specified, then priv_data cannot be NULL */
41287c478bd9Sstevel@tonic-gate if ((priv_data_len > 0) && (priv_data == NULL))
41297c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
41307c478bd9Sstevel@tonic-gate
41317c478bd9Sstevel@tonic-gate if (priv_data_len > IBT_SIDR_REP_PRIV_DATA_SZ)
41327c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
41337c478bd9Sstevel@tonic-gate
41347c478bd9Sstevel@tonic-gate /* retrieve qpn and qkey from ud channel */
41357c478bd9Sstevel@tonic-gate
41367c478bd9Sstevel@tonic-gate /* validate event and statep's state */
41377c478bd9Sstevel@tonic-gate
41387c478bd9Sstevel@tonic-gate if (status == IBT_CM_ACCEPT) {
41397c478bd9Sstevel@tonic-gate retval = ibt_query_qp(ud_channel, &qp_attr);
41407c478bd9Sstevel@tonic-gate if ((retval != IBT_SUCCESS) ||
41417c478bd9Sstevel@tonic-gate (qp_attr.qp_info.qp_trans != IBT_UD_SRV)) {
41427c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_cm_ud_proceed: "
41437c478bd9Sstevel@tonic-gate "Failed to retrieve QPN from the channel: %d",
41447c478bd9Sstevel@tonic-gate retval);
41457c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
41467c478bd9Sstevel@tonic-gate }
41477c478bd9Sstevel@tonic-gate }
41487c478bd9Sstevel@tonic-gate
41497c478bd9Sstevel@tonic-gate
41507c478bd9Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
41517c478bd9Sstevel@tonic-gate
41527c478bd9Sstevel@tonic-gate if (ud_statep->ud_state != IBCM_STATE_SIDR_REQ_RCVD) {
41537c478bd9Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
41547c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_cm_ud_proceed : Invalid State "
41557c478bd9Sstevel@tonic-gate "specified");
41567c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
41577c478bd9Sstevel@tonic-gate }
41587c478bd9Sstevel@tonic-gate
41597c478bd9Sstevel@tonic-gate /* wait until client's CM handler returns DEFER status back to CM */
41607c478bd9Sstevel@tonic-gate
41617c478bd9Sstevel@tonic-gate while (ud_statep->ud_clnt_proceed == IBCM_BLOCK) {
41627c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_cm_ud_proceed : Blocked for return"
41637c478bd9Sstevel@tonic-gate " of client's ud cm handler");
41647c478bd9Sstevel@tonic-gate cv_wait(&ud_statep->ud_block_client_cv,
41657c478bd9Sstevel@tonic-gate &ud_statep->ud_state_mutex);
41667c478bd9Sstevel@tonic-gate }
41677c478bd9Sstevel@tonic-gate
41687c478bd9Sstevel@tonic-gate if (ud_statep->ud_clnt_proceed == IBCM_FAIL) {
41697c478bd9Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
41707c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_cm_ud_proceed : Failed as client "
41717c478bd9Sstevel@tonic-gate "returned non-DEFER status from cm handler");
41727c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
41737c478bd9Sstevel@tonic-gate }
41747c478bd9Sstevel@tonic-gate
41757c478bd9Sstevel@tonic-gate ASSERT(ud_statep->ud_clnt_proceed == IBCM_UNBLOCK);
41767c478bd9Sstevel@tonic-gate ud_statep->ud_clnt_proceed = IBCM_FAIL;
41777c478bd9Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
41787c478bd9Sstevel@tonic-gate
41797c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*proceed_targs))
41807c478bd9Sstevel@tonic-gate
41817c478bd9Sstevel@tonic-gate /* the state machine processing is done in a separate thread */
41827c478bd9Sstevel@tonic-gate
41837c478bd9Sstevel@tonic-gate /* proceed_targs is freed in ibcm_proceed_via_taskq */
4184934f0bccShiremath proceed_targs = kmem_zalloc(sizeof (ibcm_proceed_targs_t),
41857c478bd9Sstevel@tonic-gate KM_SLEEP);
41867c478bd9Sstevel@tonic-gate
41877c478bd9Sstevel@tonic-gate proceed_targs->status = status;
41887c478bd9Sstevel@tonic-gate proceed_targs->priv_data_len = priv_data_len;
41897c478bd9Sstevel@tonic-gate
41907c478bd9Sstevel@tonic-gate bcopy(priv_data, proceed_targs->priv_data, priv_data_len);
41917c478bd9Sstevel@tonic-gate
41927c478bd9Sstevel@tonic-gate if (status == IBT_CM_ACCEPT) {
41937c478bd9Sstevel@tonic-gate proceed_targs->tst.ud.ud_qkey =
41947c478bd9Sstevel@tonic-gate qp_attr.qp_info.qp_transport.ud.ud_qkey;
41957c478bd9Sstevel@tonic-gate proceed_targs->tst.ud.ud_qpn = qp_attr.qp_qpn;
41967c478bd9Sstevel@tonic-gate }
41977c478bd9Sstevel@tonic-gate
41987c478bd9Sstevel@tonic-gate proceed_targs->tst.ud.ud_statep = ud_statep;
41997c478bd9Sstevel@tonic-gate
42007c478bd9Sstevel@tonic-gate /* copy redirect info based on status */
42017c478bd9Sstevel@tonic-gate if (status == IBT_CM_REDIRECT)
42027c478bd9Sstevel@tonic-gate bcopy(redirect_infop, &proceed_targs->tst.ud.ud_redirect_info,
42037c478bd9Sstevel@tonic-gate sizeof (ibt_redirect_info_t));
42047c478bd9Sstevel@tonic-gate
42057c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*proceed_targs))
42067c478bd9Sstevel@tonic-gate
42077c478bd9Sstevel@tonic-gate (void) taskq_dispatch(ibcm_taskq, ibcm_ud_proceed_via_taskq,
42087c478bd9Sstevel@tonic-gate proceed_targs, TQ_SLEEP);
42097c478bd9Sstevel@tonic-gate
42107c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
42117c478bd9Sstevel@tonic-gate }
42127c478bd9Sstevel@tonic-gate
42137c478bd9Sstevel@tonic-gate /*
42147c478bd9Sstevel@tonic-gate * Function:
42157c478bd9Sstevel@tonic-gate * ibcm_ud_proceed_via_taskq
42167c478bd9Sstevel@tonic-gate *
42177c478bd9Sstevel@tonic-gate * Called from taskq, dispatched by ibt_cm_ud_proceed
42187c478bd9Sstevel@tonic-gate * Completes the cm state processing for ibt_cm_ud_proceed
42197c478bd9Sstevel@tonic-gate */
42207c478bd9Sstevel@tonic-gate void
ibcm_ud_proceed_via_taskq(void * targs)42217c478bd9Sstevel@tonic-gate ibcm_ud_proceed_via_taskq(void *targs)
42227c478bd9Sstevel@tonic-gate {
42237c478bd9Sstevel@tonic-gate ibcm_proceed_targs_t *proceed_targs = (ibcm_proceed_targs_t *)targs;
42247c478bd9Sstevel@tonic-gate ibcm_ud_state_data_t *ud_statep = proceed_targs->tst.ud.ud_statep;
42257c478bd9Sstevel@tonic-gate ibcm_ud_clnt_reply_info_t ud_clnt_info;
42267c478bd9Sstevel@tonic-gate ibt_sidr_status_t sidr_status;
42277c478bd9Sstevel@tonic-gate
42287c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_ud_proceed_via_taskq(%p)", targs);
42297c478bd9Sstevel@tonic-gate
42307c478bd9Sstevel@tonic-gate ud_clnt_info.ud_qpn = proceed_targs->tst.ud.ud_qpn;
42317c478bd9Sstevel@tonic-gate ud_clnt_info.ud_qkey = proceed_targs->tst.ud.ud_qkey;
42327c478bd9Sstevel@tonic-gate ud_clnt_info.priv_data = proceed_targs->priv_data;
42337c478bd9Sstevel@tonic-gate ud_clnt_info.priv_data_len = proceed_targs->priv_data_len;
42347c478bd9Sstevel@tonic-gate ud_clnt_info.redirect_infop = &proceed_targs->tst.ud.ud_redirect_info;
42357c478bd9Sstevel@tonic-gate
42367c478bd9Sstevel@tonic-gate /* validate event and statep's state */
42377c478bd9Sstevel@tonic-gate ibcm_process_sidr_req_cm_hdlr(ud_statep, proceed_targs->status,
42387c478bd9Sstevel@tonic-gate &ud_clnt_info, &sidr_status,
42397c478bd9Sstevel@tonic-gate (ibcm_sidr_rep_msg_t *)IBCM_OUT_MSGP(ud_statep->ud_stored_msg));
42407c478bd9Sstevel@tonic-gate
42417c478bd9Sstevel@tonic-gate ibcm_post_sidr_rep_mad(ud_statep, sidr_status);
42427c478bd9Sstevel@tonic-gate
42437c478bd9Sstevel@tonic-gate /* decr the statep ref cnt incremented in ibcm_process_sidr_req_msg */
42447c478bd9Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
42457c478bd9Sstevel@tonic-gate IBCM_UD_REF_CNT_DECR(ud_statep);
42467c478bd9Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
42477c478bd9Sstevel@tonic-gate
42487c478bd9Sstevel@tonic-gate kmem_free(targs, sizeof (ibcm_proceed_targs_t));
42497c478bd9Sstevel@tonic-gate }
42507c478bd9Sstevel@tonic-gate
42517c478bd9Sstevel@tonic-gate /*
42527c478bd9Sstevel@tonic-gate * Function:
42537c478bd9Sstevel@tonic-gate * ibt_set_alt_path
42547c478bd9Sstevel@tonic-gate * Input:
42557c478bd9Sstevel@tonic-gate * channel Channel handle returned from ibt_alloc_rc_channel(9F).
42567c478bd9Sstevel@tonic-gate *
42577c478bd9Sstevel@tonic-gate * mode Execute in blocking or non blocking mode.
42587c478bd9Sstevel@tonic-gate *
42597c478bd9Sstevel@tonic-gate * alt_path A pointer to an ibt_alt_path_info_t as returned from an
42607c478bd9Sstevel@tonic-gate * ibt_get_alt_path(9F) call that specifies the new
42617c478bd9Sstevel@tonic-gate * alternate path.
42627c478bd9Sstevel@tonic-gate *
42637c478bd9Sstevel@tonic-gate * priv_data A pointer to a buffer specified by caller for the
42647c478bd9Sstevel@tonic-gate * private data in the outgoing CM Load Alternate Path
42657c478bd9Sstevel@tonic-gate * (LAP) message sent to the remote host. This can be NULL
42667c478bd9Sstevel@tonic-gate * if no private data is available to communicate to the
42677c478bd9Sstevel@tonic-gate * remote node.
42687c478bd9Sstevel@tonic-gate *
42697c478bd9Sstevel@tonic-gate * priv_data_len Length of valid data in priv_data, this should be less
42707c478bd9Sstevel@tonic-gate * than or equal to IBT_LAP_PRIV_DATA_SZ.
42717c478bd9Sstevel@tonic-gate *
42727c478bd9Sstevel@tonic-gate * Output:
42737c478bd9Sstevel@tonic-gate * ret_args If called in blocking mode, points to a return argument
42747c478bd9Sstevel@tonic-gate * structure of type ibt_ap_returns_t.
42757c478bd9Sstevel@tonic-gate *
42767c478bd9Sstevel@tonic-gate * Returns:
42777c478bd9Sstevel@tonic-gate * IBT_SUCCESS on Success else appropriate error.
42787c478bd9Sstevel@tonic-gate * Description:
42797c478bd9Sstevel@tonic-gate * Load the specified alternate path. Causes the CM to send an LAP message
42807c478bd9Sstevel@tonic-gate * to the remote node.
42817c478bd9Sstevel@tonic-gate * Can only be called on a previously opened RC channel.
42827c478bd9Sstevel@tonic-gate */
42837c478bd9Sstevel@tonic-gate ibt_status_t
ibt_set_alt_path(ibt_channel_hdl_t channel,ibt_execution_mode_t mode,ibt_alt_path_info_t * alt_path,void * priv_data,ibt_priv_data_len_t priv_data_len,ibt_ap_returns_t * ret_args)42847c478bd9Sstevel@tonic-gate ibt_set_alt_path(ibt_channel_hdl_t channel, ibt_execution_mode_t mode,
42857c478bd9Sstevel@tonic-gate ibt_alt_path_info_t *alt_path, void *priv_data,
42867c478bd9Sstevel@tonic-gate ibt_priv_data_len_t priv_data_len, ibt_ap_returns_t *ret_args)
42877c478bd9Sstevel@tonic-gate {
42887c478bd9Sstevel@tonic-gate ibmf_handle_t ibmf_hdl;
42897c478bd9Sstevel@tonic-gate ibt_status_t status = IBT_SUCCESS;
42907c478bd9Sstevel@tonic-gate ibcm_lap_msg_t *lap_msgp;
42917c478bd9Sstevel@tonic-gate ibcm_hca_info_t *hcap;
42927c478bd9Sstevel@tonic-gate ibcm_state_data_t *statep;
42937c478bd9Sstevel@tonic-gate uint8_t port_no;
42947c478bd9Sstevel@tonic-gate ib_lid_t alternate_slid;
42957c478bd9Sstevel@tonic-gate ibt_priv_data_len_t len;
42967c478bd9Sstevel@tonic-gate ib_lid_t base_lid;
42977c478bd9Sstevel@tonic-gate boolean_t alt_grh;
42987c478bd9Sstevel@tonic-gate
42997c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_set_alt_path(%p, %x, %p, %p, %x, %p)",
43007c478bd9Sstevel@tonic-gate channel, mode, alt_path, priv_data, priv_data_len, ret_args);
43017c478bd9Sstevel@tonic-gate
43027c478bd9Sstevel@tonic-gate /* validate channel */
43037c478bd9Sstevel@tonic-gate if (IBCM_INVALID_CHANNEL(channel)) {
43047c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: invalid channel");
43057c478bd9Sstevel@tonic-gate return (IBT_CHAN_HDL_INVALID);
43067c478bd9Sstevel@tonic-gate }
43077c478bd9Sstevel@tonic-gate
43087c478bd9Sstevel@tonic-gate if (ibtl_cm_get_chan_type(channel) != IBT_RC_SRV) {
43097c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: "
43107c478bd9Sstevel@tonic-gate "Invalid Channel type: Applicable only to RC Channel");
43117c478bd9Sstevel@tonic-gate return (IBT_CHAN_SRV_TYPE_INVALID);
43127c478bd9Sstevel@tonic-gate }
43137c478bd9Sstevel@tonic-gate
43147c478bd9Sstevel@tonic-gate if (mode == IBT_NONBLOCKING) {
43157c478bd9Sstevel@tonic-gate if (ret_args != NULL) {
43167c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: "
43177c478bd9Sstevel@tonic-gate "ret_args should be NULL when called in "
43187c478bd9Sstevel@tonic-gate "non-blocking mode");
43197c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
43207c478bd9Sstevel@tonic-gate }
43217c478bd9Sstevel@tonic-gate } else if (mode == IBT_BLOCKING) {
43227c478bd9Sstevel@tonic-gate if (ret_args == NULL) {
43237c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: "
43247c478bd9Sstevel@tonic-gate "ret_args should be Non-NULL when called in "
43257c478bd9Sstevel@tonic-gate "blocking mode");
43267c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
43277c478bd9Sstevel@tonic-gate }
43287c478bd9Sstevel@tonic-gate if (ret_args->ap_priv_data_len > IBT_APR_PRIV_DATA_SZ) {
43297c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: "
43307c478bd9Sstevel@tonic-gate "expected private data length is too large");
43317c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
43327c478bd9Sstevel@tonic-gate }
43337c478bd9Sstevel@tonic-gate if ((ret_args->ap_priv_data_len > 0) &&
43347c478bd9Sstevel@tonic-gate (ret_args->ap_priv_data == NULL)) {
43357c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: "
43367c478bd9Sstevel@tonic-gate "apr_priv_data_len > 0, but apr_priv_data NULL");
43377c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
43387c478bd9Sstevel@tonic-gate }
43397c478bd9Sstevel@tonic-gate } else { /* any other mode is not valid for ibt_set_alt_path */
43407c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: "
43417c478bd9Sstevel@tonic-gate "invalid mode %x specified", mode);
43427c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
43437c478bd9Sstevel@tonic-gate }
43447c478bd9Sstevel@tonic-gate
43457c478bd9Sstevel@tonic-gate if ((port_no = alt_path->ap_alt_cep_path.cep_hca_port_num) == 0)
43467c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
43477c478bd9Sstevel@tonic-gate
43487c478bd9Sstevel@tonic-gate /* get the statep */
43497c478bd9Sstevel@tonic-gate IBCM_GET_CHAN_PRIVATE(channel, statep);
43507c478bd9Sstevel@tonic-gate if (statep == NULL) {
43517c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: statep NULL");
43527c478bd9Sstevel@tonic-gate return (IBT_CM_FAILURE);
43537c478bd9Sstevel@tonic-gate }
43547c478bd9Sstevel@tonic-gate
43557c478bd9Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
43567c478bd9Sstevel@tonic-gate IBCM_RELEASE_CHAN_PRIVATE(channel);
43577c478bd9Sstevel@tonic-gate IBCM_REF_CNT_INCR(statep);
43587c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
43597c478bd9Sstevel@tonic-gate
43607c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_set_alt_path: statep %p", statep);
43617c478bd9Sstevel@tonic-gate
43627c478bd9Sstevel@tonic-gate hcap = statep->hcap;
43637c478bd9Sstevel@tonic-gate
43647c478bd9Sstevel@tonic-gate /* HCA must have been in active state. If not, it's a client bug */
43657c478bd9Sstevel@tonic-gate if (!IBCM_ACCESS_HCA_OK(hcap))
43667c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: hca in error state");
43677c478bd9Sstevel@tonic-gate
43687c478bd9Sstevel@tonic-gate ASSERT(statep->cm_handler != NULL);
43697c478bd9Sstevel@tonic-gate
43707c478bd9Sstevel@tonic-gate /* Check Alternate port */
43717c478bd9Sstevel@tonic-gate status = ibt_get_port_state_byguid(hcap->hca_guid, port_no, NULL,
43727c478bd9Sstevel@tonic-gate &base_lid);
43737c478bd9Sstevel@tonic-gate if (status != IBT_SUCCESS) {
43747c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: "
43757c478bd9Sstevel@tonic-gate "ibt_get_port_state_byguid status %d ", status);
43767c478bd9Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
43777c478bd9Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
43787c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
43797c478bd9Sstevel@tonic-gate return (status);
43807c478bd9Sstevel@tonic-gate }
43817c478bd9Sstevel@tonic-gate
43827c478bd9Sstevel@tonic-gate if ((hcap->hca_port_info[port_no - 1].port_ibmf_hdl == NULL) &&
43837c478bd9Sstevel@tonic-gate ((status = ibcm_hca_reinit_port(hcap, port_no - 1))
43847c478bd9Sstevel@tonic-gate != IBT_SUCCESS)) {
43857c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: "
43867c478bd9Sstevel@tonic-gate "ibmf reg or callback setup failed during re-initialize");
43877c478bd9Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
43887c478bd9Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
43897c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
43907c478bd9Sstevel@tonic-gate return (status);
43917c478bd9Sstevel@tonic-gate }
43927c478bd9Sstevel@tonic-gate
43937c478bd9Sstevel@tonic-gate ibmf_hdl = statep->stored_reply_addr.ibmf_hdl;
43947c478bd9Sstevel@tonic-gate
43957c478bd9Sstevel@tonic-gate alternate_slid = base_lid +
43967c478bd9Sstevel@tonic-gate alt_path->ap_alt_cep_path.cep_adds_vect.av_src_path;
43977c478bd9Sstevel@tonic-gate
43987c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_set_alt_path: alternate SLID = %x",
43997c478bd9Sstevel@tonic-gate h2b16(alternate_slid));
44007c478bd9Sstevel@tonic-gate
44019d3d2ed0Shiremath ibcm_lapr_enter(); /* limit how many run simultaneously */
44027c478bd9Sstevel@tonic-gate
44037c478bd9Sstevel@tonic-gate /* Allocate MAD for LAP */
44047c478bd9Sstevel@tonic-gate if (statep->lapr_msg == NULL)
44057c478bd9Sstevel@tonic-gate if ((status = ibcm_alloc_out_msg(ibmf_hdl, &statep->lapr_msg,
44067c478bd9Sstevel@tonic-gate MAD_METHOD_SEND)) != IBT_SUCCESS) {
44079d3d2ed0Shiremath ibcm_lapr_exit();
44087c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_set_alt_path: "
44097c478bd9Sstevel@tonic-gate "chan 0x%p ibcm_alloc_out_msg failed", channel);
44107c478bd9Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
44117c478bd9Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
44127c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
44137c478bd9Sstevel@tonic-gate return (status);
44147c478bd9Sstevel@tonic-gate }
44157c478bd9Sstevel@tonic-gate
44167c478bd9Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
44177c478bd9Sstevel@tonic-gate
44187c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_set_alt_path: connection state is"
44197c478bd9Sstevel@tonic-gate " %x", statep->state);
44207c478bd9Sstevel@tonic-gate
44217c478bd9Sstevel@tonic-gate /* Check state */
44227c478bd9Sstevel@tonic-gate if ((statep->state != IBCM_STATE_ESTABLISHED) ||
44237c478bd9Sstevel@tonic-gate (statep->ap_state != IBCM_AP_STATE_IDLE)) {
44247c478bd9Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
44257c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
44267c478bd9Sstevel@tonic-gate (void) ibcm_free_out_msg(ibmf_hdl, &statep->lapr_msg);
44279d3d2ed0Shiremath ibcm_lapr_exit();
44287c478bd9Sstevel@tonic-gate return (IBT_CHAN_STATE_INVALID);
44297c478bd9Sstevel@tonic-gate } else {
44307c478bd9Sstevel@tonic-gate /* Set to LAP Sent state */
44317c478bd9Sstevel@tonic-gate statep->ap_state = IBCM_AP_STATE_LAP_SENT;
44327c478bd9Sstevel@tonic-gate statep->ap_done = B_FALSE;
44337c478bd9Sstevel@tonic-gate statep->remaining_retry_cnt = statep->max_cm_retries;
44347c478bd9Sstevel@tonic-gate statep->timer_stored_state = statep->state;
44357c478bd9Sstevel@tonic-gate statep->timer_stored_ap_state = statep->ap_state;
44367c478bd9Sstevel@tonic-gate IBCM_REF_CNT_INCR(statep); /* for ibcm_post_lap_complete */
44377c478bd9Sstevel@tonic-gate }
44387c478bd9Sstevel@tonic-gate
44397c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
44407c478bd9Sstevel@tonic-gate
44417c478bd9Sstevel@tonic-gate /* No more failure returns below */
44427c478bd9Sstevel@tonic-gate
44437c478bd9Sstevel@tonic-gate /* Allocate MAD for LAP */
44447c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibt_set_alt_path:"
44457c478bd9Sstevel@tonic-gate " statep's mad addr = 0x%p", IBCM_OUT_HDRP(statep->lapr_msg));
44467c478bd9Sstevel@tonic-gate
44477c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lap_msgp))
44487c478bd9Sstevel@tonic-gate
44497c478bd9Sstevel@tonic-gate lap_msgp = (ibcm_lap_msg_t *)IBCM_OUT_MSGP(statep->lapr_msg);
44507c478bd9Sstevel@tonic-gate
44517c478bd9Sstevel@tonic-gate lap_msgp->lap_alt_l_port_lid = h2b16(alternate_slid);
44527c478bd9Sstevel@tonic-gate lap_msgp->lap_alt_r_port_lid =
44537c478bd9Sstevel@tonic-gate h2b16(alt_path->ap_alt_cep_path.cep_adds_vect.av_dlid);
44547c478bd9Sstevel@tonic-gate
44557c478bd9Sstevel@tonic-gate /* Fill in remote port gid */
44567c478bd9Sstevel@tonic-gate lap_msgp->lap_alt_r_port_gid.gid_prefix =
44577c478bd9Sstevel@tonic-gate h2b64(alt_path->ap_alt_cep_path.cep_adds_vect.av_dgid.gid_prefix);
44587c478bd9Sstevel@tonic-gate lap_msgp->lap_alt_r_port_gid.gid_guid =
44597c478bd9Sstevel@tonic-gate h2b64(alt_path->ap_alt_cep_path.cep_adds_vect.av_dgid.gid_guid);
44607c478bd9Sstevel@tonic-gate
44617c478bd9Sstevel@tonic-gate /* Fill in local port gid */
44627c478bd9Sstevel@tonic-gate lap_msgp->lap_alt_l_port_gid.gid_prefix =
44637c478bd9Sstevel@tonic-gate h2b64(alt_path->ap_alt_cep_path.cep_adds_vect.av_sgid.gid_prefix);
44647c478bd9Sstevel@tonic-gate lap_msgp->lap_alt_l_port_gid.gid_guid =
44657c478bd9Sstevel@tonic-gate h2b64(alt_path->ap_alt_cep_path.cep_adds_vect.av_sgid.gid_guid);
44667c478bd9Sstevel@tonic-gate
44677c478bd9Sstevel@tonic-gate alt_grh = alt_path->ap_alt_cep_path.cep_adds_vect.av_send_grh;
44687c478bd9Sstevel@tonic-gate
44697c478bd9Sstevel@tonic-gate /* alternate_flow_label, and alternate srate, alternate traffic class */
44707c478bd9Sstevel@tonic-gate lap_msgp->lap_alt_srate_plus =
44717c478bd9Sstevel@tonic-gate alt_path->ap_alt_cep_path.cep_adds_vect.av_srate & 0x3f;
44727c478bd9Sstevel@tonic-gate lap_msgp->lap_alt_flow_label_plus = h2b32(((alt_grh == B_TRUE) ?
44737c478bd9Sstevel@tonic-gate (alt_path->ap_alt_cep_path.cep_adds_vect.av_flow << 12) : 0) |
44747c478bd9Sstevel@tonic-gate alt_path->ap_alt_cep_path.cep_adds_vect.av_tclass);
44757c478bd9Sstevel@tonic-gate
44767c478bd9Sstevel@tonic-gate /* Alternate hop limit, service level */
44777c478bd9Sstevel@tonic-gate lap_msgp->lap_alt_hop_limit = (alt_grh == B_TRUE) ?
44786db9c6ddShiremath alt_path->ap_alt_cep_path.cep_adds_vect.av_hop : 1;
44797c478bd9Sstevel@tonic-gate lap_msgp->lap_alt_sl_plus =
44807c478bd9Sstevel@tonic-gate alt_path->ap_alt_cep_path.cep_adds_vect.av_srvl << 4 |
44817c478bd9Sstevel@tonic-gate ((alt_grh == B_FALSE) ? 0x8 : 0);
44827c478bd9Sstevel@tonic-gate
44837c478bd9Sstevel@tonic-gate lap_msgp->lap_alt_local_acktime_plus = ibt_usec2ib(
44847c478bd9Sstevel@tonic-gate (2 * statep->rc_alt_pkt_lt) +
44857c478bd9Sstevel@tonic-gate ibt_ib2usec(hcap->hca_ack_delay)) << 3;
44867c478bd9Sstevel@tonic-gate
44877c478bd9Sstevel@tonic-gate lap_msgp->lap_local_comm_id = h2b32(statep->local_comid);
44887c478bd9Sstevel@tonic-gate lap_msgp->lap_remote_comm_id = h2b32(statep->remote_comid);
44897c478bd9Sstevel@tonic-gate
44907c478bd9Sstevel@tonic-gate lap_msgp->lap_remote_qpn_eecn_plus =
44917c478bd9Sstevel@tonic-gate h2b32((statep->remote_qpn << 8) |
44927c478bd9Sstevel@tonic-gate ibt_usec2ib(ibcm_remote_response_time) << 3);
44937c478bd9Sstevel@tonic-gate
44947c478bd9Sstevel@tonic-gate len = min(priv_data_len, IBT_LAP_PRIV_DATA_SZ);
44957c478bd9Sstevel@tonic-gate if ((len > 0) && priv_data) {
44967c478bd9Sstevel@tonic-gate bcopy(priv_data, lap_msgp->lap_private_data, len);
44977c478bd9Sstevel@tonic-gate }
44987c478bd9Sstevel@tonic-gate
44997c478bd9Sstevel@tonic-gate /* only rc_alt_pkt_lt and ap_return_data fields are initialized */
45007c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
45017c478bd9Sstevel@tonic-gate
45027c478bd9Sstevel@tonic-gate statep->rc_alt_pkt_lt = ibt_ib2usec(alt_path->ap_alt_pkt_lt);
45037c478bd9Sstevel@tonic-gate
45047c478bd9Sstevel@tonic-gate /* return_data is filled up in the state machine code */
45057c478bd9Sstevel@tonic-gate statep->ap_return_data = ret_args;
45067c478bd9Sstevel@tonic-gate
45077c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*statep))
45087c478bd9Sstevel@tonic-gate
45097c478bd9Sstevel@tonic-gate IBCM_OUT_HDRP(statep->lapr_msg)->AttributeID =
45107c478bd9Sstevel@tonic-gate h2b16(IBCM_INCOMING_LAP + IBCM_ATTR_BASE_ID);
45117c478bd9Sstevel@tonic-gate
45127c478bd9Sstevel@tonic-gate IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID =
45137c478bd9Sstevel@tonic-gate h2b64(ibcm_generate_tranid(IBCM_INCOMING_LAP, statep->local_comid,
45147c478bd9Sstevel@tonic-gate 0));
45157c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_set_alt_path: statep %p, tid %llx",
45167c478bd9Sstevel@tonic-gate statep, IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID);
45177c478bd9Sstevel@tonic-gate
45187c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*lap_msgp))
45197c478bd9Sstevel@tonic-gate
45207c478bd9Sstevel@tonic-gate /* Send LAP */
45217c478bd9Sstevel@tonic-gate ibcm_post_rc_mad(statep, statep->lapr_msg, ibcm_post_lap_complete,
45227c478bd9Sstevel@tonic-gate statep);
45237c478bd9Sstevel@tonic-gate
45247c478bd9Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
45257c478bd9Sstevel@tonic-gate
45267c478bd9Sstevel@tonic-gate if (mode == IBT_BLOCKING) {
45277c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_set_alt_path: blocking");
45287c478bd9Sstevel@tonic-gate
45297c478bd9Sstevel@tonic-gate /* wait for APR */
45307c478bd9Sstevel@tonic-gate while (statep->ap_done != B_TRUE) {
45317c478bd9Sstevel@tonic-gate cv_wait(&statep->block_client_cv,
45327c478bd9Sstevel@tonic-gate &statep->state_mutex);
45337c478bd9Sstevel@tonic-gate }
45347c478bd9Sstevel@tonic-gate
45357c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_set_alt_path: done blocking");
45367c478bd9Sstevel@tonic-gate
45377c478bd9Sstevel@tonic-gate /*
45387c478bd9Sstevel@tonic-gate * In the case that ibt_set_alt_path fails,
45397c478bd9Sstevel@tonic-gate * change retval to IBT_CM_FAILURE
45407c478bd9Sstevel@tonic-gate */
45417c478bd9Sstevel@tonic-gate if (statep->ap_return_data->ap_status != IBT_CM_AP_LOADED)
45427c478bd9Sstevel@tonic-gate status = IBT_CM_FAILURE;
45437c478bd9Sstevel@tonic-gate
45447c478bd9Sstevel@tonic-gate }
45457c478bd9Sstevel@tonic-gate
45467c478bd9Sstevel@tonic-gate /* decrement the ref-count before leaving here */
45477c478bd9Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
45487c478bd9Sstevel@tonic-gate
45497c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
45507c478bd9Sstevel@tonic-gate
45519d3d2ed0Shiremath ibcm_lapr_exit();
45529d3d2ed0Shiremath
45537c478bd9Sstevel@tonic-gate /* If this message isn't seen then ibt_set_alt_path failed */
45547c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_set_alt_path: done");
45557c478bd9Sstevel@tonic-gate
45567c478bd9Sstevel@tonic-gate return (status);
45577c478bd9Sstevel@tonic-gate }
45587c478bd9Sstevel@tonic-gate
45597c478bd9Sstevel@tonic-gate
45607c478bd9Sstevel@tonic-gate #ifdef DEBUG
45617c478bd9Sstevel@tonic-gate
45627c478bd9Sstevel@tonic-gate /*
45637c478bd9Sstevel@tonic-gate * ibcm_query_classport_info:
45647c478bd9Sstevel@tonic-gate * Query classportinfo
45657c478bd9Sstevel@tonic-gate *
45667c478bd9Sstevel@tonic-gate * INPUTS:
45677c478bd9Sstevel@tonic-gate * channel - Channel that is associated with a statep
45687c478bd9Sstevel@tonic-gate *
45697c478bd9Sstevel@tonic-gate * RETURN VALUE: NONE
45707c478bd9Sstevel@tonic-gate * This function is currently used to generate a valid get method classport
45717c478bd9Sstevel@tonic-gate * info, and test CM functionality. There is no ibtl client interface to
45727c478bd9Sstevel@tonic-gate * generate a classportinfo. It is possible that CM may use classportinfo
45737c478bd9Sstevel@tonic-gate * from other nodes in the future, and most of the code below could be re-used.
45747c478bd9Sstevel@tonic-gate */
45757c478bd9Sstevel@tonic-gate void
ibcm_query_classport_info(ibt_channel_hdl_t channel)45767c478bd9Sstevel@tonic-gate ibcm_query_classport_info(ibt_channel_hdl_t channel)
45777c478bd9Sstevel@tonic-gate {
45787c478bd9Sstevel@tonic-gate ibcm_state_data_t *statep;
45797c478bd9Sstevel@tonic-gate ibmf_msg_t *msgp;
45807c478bd9Sstevel@tonic-gate
4581d3a82192SShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibcm_query_classport_info(%p)", channel);
45827c478bd9Sstevel@tonic-gate
45837c478bd9Sstevel@tonic-gate /* validate channel, first */
45847c478bd9Sstevel@tonic-gate if (IBCM_INVALID_CHANNEL(channel)) {
45857c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_query_classport_info: "
45867c478bd9Sstevel@tonic-gate "invalid channel (%p)", channel);
45877c478bd9Sstevel@tonic-gate return;
45887c478bd9Sstevel@tonic-gate }
45897c478bd9Sstevel@tonic-gate
45907c478bd9Sstevel@tonic-gate /* get the statep */
45917c478bd9Sstevel@tonic-gate IBCM_GET_CHAN_PRIVATE(channel, statep);
45927c478bd9Sstevel@tonic-gate
45937c478bd9Sstevel@tonic-gate /*
45947c478bd9Sstevel@tonic-gate * This can happen, if the statep is already gone by a DREQ from
45957c478bd9Sstevel@tonic-gate * the remote side
45967c478bd9Sstevel@tonic-gate */
45977c478bd9Sstevel@tonic-gate if (statep == NULL) {
45987c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_query_classport_info: "
45997c478bd9Sstevel@tonic-gate "statep NULL");
46007c478bd9Sstevel@tonic-gate return;
46017c478bd9Sstevel@tonic-gate }
46027c478bd9Sstevel@tonic-gate
46037c478bd9Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
46047c478bd9Sstevel@tonic-gate IBCM_RELEASE_CHAN_PRIVATE(channel);
46057c478bd9Sstevel@tonic-gate IBCM_REF_CNT_INCR(statep);
46067c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
46077c478bd9Sstevel@tonic-gate
46087c478bd9Sstevel@tonic-gate /* Debug/test code, so don't care about return status */
46097c478bd9Sstevel@tonic-gate (void) ibcm_alloc_out_msg(statep->stored_reply_addr.ibmf_hdl, &msgp,
46107c478bd9Sstevel@tonic-gate MAD_METHOD_GET);
46117c478bd9Sstevel@tonic-gate
46127c478bd9Sstevel@tonic-gate IBCM_OUT_HDRP(msgp)->TransactionID = h2b64(ibcm_generate_tranid(
46137c478bd9Sstevel@tonic-gate MAD_ATTR_ID_CLASSPORTINFO, statep->local_comid, 0));
46147c478bd9Sstevel@tonic-gate IBCM_OUT_HDRP(msgp)->AttributeID = h2b16(MAD_ATTR_ID_CLASSPORTINFO);
46157c478bd9Sstevel@tonic-gate
46167c478bd9Sstevel@tonic-gate (void) ibcm_post_mad(msgp, &statep->stored_reply_addr, NULL, NULL);
46177c478bd9Sstevel@tonic-gate
4618d3a82192SShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibcm_query_classport_info(%p) "
46197c478bd9Sstevel@tonic-gate "Get method MAD posted ", channel);
46207c478bd9Sstevel@tonic-gate
46217c478bd9Sstevel@tonic-gate (void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl, &msgp);
46227c478bd9Sstevel@tonic-gate
46237c478bd9Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
46247c478bd9Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
46257c478bd9Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
46267c478bd9Sstevel@tonic-gate }
46277c478bd9Sstevel@tonic-gate
46287c478bd9Sstevel@tonic-gate static void
ibcm_print_reply_addr(ibt_channel_hdl_t channel,ibcm_mad_addr_t * cm_reply_addr)46297c478bd9Sstevel@tonic-gate ibcm_print_reply_addr(ibt_channel_hdl_t channel, ibcm_mad_addr_t *cm_reply_addr)
46307c478bd9Sstevel@tonic-gate {
46317c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_print_reply_addr: chan 0x%p, SLID %x, "
46327c478bd9Sstevel@tonic-gate "DLID %x", channel, cm_reply_addr->rcvd_addr.ia_local_lid,
46337c478bd9Sstevel@tonic-gate cm_reply_addr->rcvd_addr.ia_remote_lid);
46347c478bd9Sstevel@tonic-gate
46357c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_print_reply_addr: QKEY %x, PKEY %x, "
46367c478bd9Sstevel@tonic-gate "RQPN %x SL %x", cm_reply_addr->rcvd_addr.ia_q_key,
46377c478bd9Sstevel@tonic-gate cm_reply_addr->rcvd_addr.ia_p_key,
46387c478bd9Sstevel@tonic-gate cm_reply_addr->rcvd_addr.ia_remote_qno,
46397c478bd9Sstevel@tonic-gate cm_reply_addr->rcvd_addr.ia_service_level);
46407c478bd9Sstevel@tonic-gate
46417c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_print_reply_addr: CM SGID %llX:%llX ",
46427c478bd9Sstevel@tonic-gate cm_reply_addr->grh_hdr.ig_sender_gid.gid_prefix,
46437c478bd9Sstevel@tonic-gate cm_reply_addr->grh_hdr.ig_sender_gid.gid_guid);
46447c478bd9Sstevel@tonic-gate
46457c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_print_reply_addr: CM DGID %llX:%llX",
46467c478bd9Sstevel@tonic-gate cm_reply_addr->grh_hdr.ig_recver_gid.gid_prefix,
46477c478bd9Sstevel@tonic-gate cm_reply_addr->grh_hdr.ig_recver_gid.gid_guid);
46487c478bd9Sstevel@tonic-gate
46497c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_print_reply_addr: CM FL %x TC %x HL %x",
46507c478bd9Sstevel@tonic-gate cm_reply_addr->grh_hdr.ig_flow_label,
46517c478bd9Sstevel@tonic-gate cm_reply_addr->grh_hdr.ig_tclass,
46527c478bd9Sstevel@tonic-gate cm_reply_addr->grh_hdr.ig_hop_limit);
46537c478bd9Sstevel@tonic-gate }
46547c478bd9Sstevel@tonic-gate
46557c478bd9Sstevel@tonic-gate #endif
46567c478bd9Sstevel@tonic-gate
4657f07a6d2aSShantkumar Hiremath /* For MCG List search */
4658f07a6d2aSShantkumar Hiremath typedef struct ibcm_mcg_list_s {
4659f07a6d2aSShantkumar Hiremath struct ibcm_mcg_list_s *ml_next;
4660f07a6d2aSShantkumar Hiremath ib_gid_t ml_sgid;
4661f07a6d2aSShantkumar Hiremath ib_gid_t ml_mgid;
4662f07a6d2aSShantkumar Hiremath ib_pkey_t ml_pkey;
4663f07a6d2aSShantkumar Hiremath ib_qkey_t ml_qkey;
4664f07a6d2aSShantkumar Hiremath uint_t ml_refcnt;
4665f07a6d2aSShantkumar Hiremath uint8_t ml_jstate;
4666f07a6d2aSShantkumar Hiremath } ibcm_mcg_list_t;
4667f07a6d2aSShantkumar Hiremath
4668f07a6d2aSShantkumar Hiremath ibcm_mcg_list_t *ibcm_mcglist = NULL;
4669f07a6d2aSShantkumar Hiremath
4670f07a6d2aSShantkumar Hiremath _NOTE(MUTEX_PROTECTS_DATA(ibcm_mcglist_lock, ibcm_mcg_list_s))
4671f07a6d2aSShantkumar Hiremath _NOTE(MUTEX_PROTECTS_DATA(ibcm_mcglist_lock, ibcm_mcglist))
4672f07a6d2aSShantkumar Hiremath
46737c478bd9Sstevel@tonic-gate typedef struct ibcm_join_mcg_tqarg_s {
46747c478bd9Sstevel@tonic-gate ib_gid_t rgid;
46757c478bd9Sstevel@tonic-gate ibt_mcg_attr_t mcg_attr;
46767c478bd9Sstevel@tonic-gate ibt_mcg_info_t *mcg_infop;
46777c478bd9Sstevel@tonic-gate ibt_mcg_handler_t func;
46787c478bd9Sstevel@tonic-gate void *arg;
46797c478bd9Sstevel@tonic-gate } ibcm_join_mcg_tqarg_t;
46807c478bd9Sstevel@tonic-gate
_NOTE(READ_ONLY_DATA (ibcm_join_mcg_tqarg_s))46817c478bd9Sstevel@tonic-gate _NOTE(READ_ONLY_DATA(ibcm_join_mcg_tqarg_s))
46827c478bd9Sstevel@tonic-gate
4683f07a6d2aSShantkumar Hiremath void
4684f07a6d2aSShantkumar Hiremath ibcm_add_incr_mcg_entry(sa_mcmember_record_t *mcg_req,
4685f07a6d2aSShantkumar Hiremath sa_mcmember_record_t *mcg_resp)
4686f07a6d2aSShantkumar Hiremath {
4687f07a6d2aSShantkumar Hiremath ibcm_mcg_list_t *new = NULL;
4688f07a6d2aSShantkumar Hiremath ibcm_mcg_list_t *head = NULL;
4689f07a6d2aSShantkumar Hiremath
4690f07a6d2aSShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibcm_add_incr_mcg_entry: MGID %llX:%llX"
4691f07a6d2aSShantkumar Hiremath "\n SGID %llX:%llX, JState %X)", mcg_req->MGID.gid_prefix,
4692f07a6d2aSShantkumar Hiremath mcg_req->MGID.gid_guid, mcg_req->PortGID.gid_prefix,
4693f07a6d2aSShantkumar Hiremath mcg_req->PortGID.gid_guid, mcg_req->JoinState);
4694f07a6d2aSShantkumar Hiremath
4695f07a6d2aSShantkumar Hiremath mutex_enter(&ibcm_mcglist_lock);
4696f07a6d2aSShantkumar Hiremath head = ibcm_mcglist;
4697f07a6d2aSShantkumar Hiremath
4698f07a6d2aSShantkumar Hiremath while (head != NULL) {
4699f07a6d2aSShantkumar Hiremath if ((head->ml_mgid.gid_guid == mcg_resp->MGID.gid_guid) &&
4700f07a6d2aSShantkumar Hiremath (head->ml_mgid.gid_prefix == mcg_resp->MGID.gid_prefix) &&
4701f07a6d2aSShantkumar Hiremath (head->ml_sgid.gid_guid == mcg_resp->PortGID.gid_guid)) {
4702f07a6d2aSShantkumar Hiremath /* Increment the count */
4703f07a6d2aSShantkumar Hiremath head->ml_refcnt++;
4704f07a6d2aSShantkumar Hiremath /* OR the join_state value, we need this during leave */
4705f07a6d2aSShantkumar Hiremath head->ml_jstate |= mcg_req->JoinState;
4706f07a6d2aSShantkumar Hiremath
4707f07a6d2aSShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibcm_add_incr_mcg_entry: Entry "
4708f07a6d2aSShantkumar Hiremath "FOUND: refcnt %d JState %X", head->ml_refcnt,
4709f07a6d2aSShantkumar Hiremath head->ml_jstate);
4710f07a6d2aSShantkumar Hiremath
4711f07a6d2aSShantkumar Hiremath mutex_exit(&ibcm_mcglist_lock);
4712f07a6d2aSShantkumar Hiremath return;
4713f07a6d2aSShantkumar Hiremath }
4714f07a6d2aSShantkumar Hiremath head = head->ml_next;
4715f07a6d2aSShantkumar Hiremath }
4716f07a6d2aSShantkumar Hiremath mutex_exit(&ibcm_mcglist_lock);
4717f07a6d2aSShantkumar Hiremath
4718f07a6d2aSShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibcm_add_incr_mcg_entry: Create NEW Entry ");
4719f07a6d2aSShantkumar Hiremath
4720f07a6d2aSShantkumar Hiremath /* If we are here, either list is empty or match couldn't be found */
4721f07a6d2aSShantkumar Hiremath new = kmem_zalloc(sizeof (ibcm_mcg_list_t), KM_SLEEP);
4722f07a6d2aSShantkumar Hiremath
4723f07a6d2aSShantkumar Hiremath mutex_enter(&ibcm_mcglist_lock);
4724f07a6d2aSShantkumar Hiremath /* Initialize the fields */
4725f07a6d2aSShantkumar Hiremath new->ml_sgid = mcg_resp->PortGID;
4726f07a6d2aSShantkumar Hiremath new->ml_mgid = mcg_resp->MGID;
4727f07a6d2aSShantkumar Hiremath new->ml_qkey = mcg_req->Q_Key;
4728f07a6d2aSShantkumar Hiremath new->ml_pkey = mcg_req->P_Key;
4729f07a6d2aSShantkumar Hiremath new->ml_refcnt = 1; /* As this is the first entry */
4730f07a6d2aSShantkumar Hiremath new->ml_jstate = mcg_req->JoinState;
4731f07a6d2aSShantkumar Hiremath new->ml_next = NULL;
4732f07a6d2aSShantkumar Hiremath
4733f07a6d2aSShantkumar Hiremath new->ml_next = ibcm_mcglist;
4734f07a6d2aSShantkumar Hiremath ibcm_mcglist = new;
4735f07a6d2aSShantkumar Hiremath mutex_exit(&ibcm_mcglist_lock);
4736f07a6d2aSShantkumar Hiremath }
4737f07a6d2aSShantkumar Hiremath
4738f07a6d2aSShantkumar Hiremath /*
4739f07a6d2aSShantkumar Hiremath * ibcm_del_decr_mcg_entry
4740f07a6d2aSShantkumar Hiremath *
4741f07a6d2aSShantkumar Hiremath * Return value:
4742f07a6d2aSShantkumar Hiremath * IBCM_SUCCESS Entry found and ref_cnt is now zero. So go-ahead and
4743f07a6d2aSShantkumar Hiremath * leave the MCG group. The return arg *jstate will have
4744f07a6d2aSShantkumar Hiremath * a valid join_state value that needed to be used by
4745f07a6d2aSShantkumar Hiremath * xxx_leave_mcg().
4746f07a6d2aSShantkumar Hiremath * IBCM_LOOKUP_EXISTS Entry found and ref_cnt is decremented but is NOT zero.
4747f07a6d2aSShantkumar Hiremath * So do not leave the MCG group yet.
4748f07a6d2aSShantkumar Hiremath * IBCM_LOOKUP_FAIL Entry is NOT found.
4749f07a6d2aSShantkumar Hiremath */
4750f07a6d2aSShantkumar Hiremath ibcm_status_t
ibcm_del_decr_mcg_entry(sa_mcmember_record_t * mcg_req,uint8_t * jstate)4751f07a6d2aSShantkumar Hiremath ibcm_del_decr_mcg_entry(sa_mcmember_record_t *mcg_req, uint8_t *jstate)
4752f07a6d2aSShantkumar Hiremath {
4753f07a6d2aSShantkumar Hiremath ibcm_mcg_list_t *head, *prev;
4754f07a6d2aSShantkumar Hiremath
4755f07a6d2aSShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibcm_del_decr_mcg_entry: MGID %llX:%llX"
4756f07a6d2aSShantkumar Hiremath "\n SGID %llX:%llX, JState %X)", mcg_req->MGID.gid_prefix,
4757f07a6d2aSShantkumar Hiremath mcg_req->MGID.gid_guid, mcg_req->PortGID.gid_prefix,
4758f07a6d2aSShantkumar Hiremath mcg_req->PortGID.gid_guid, mcg_req->JoinState);
4759f07a6d2aSShantkumar Hiremath
4760f07a6d2aSShantkumar Hiremath *jstate = 0;
4761f07a6d2aSShantkumar Hiremath
4762f07a6d2aSShantkumar Hiremath mutex_enter(&ibcm_mcglist_lock);
4763f07a6d2aSShantkumar Hiremath head = ibcm_mcglist;
4764f07a6d2aSShantkumar Hiremath prev = NULL;
4765f07a6d2aSShantkumar Hiremath
4766f07a6d2aSShantkumar Hiremath while (head != NULL) {
4767f07a6d2aSShantkumar Hiremath if ((head->ml_mgid.gid_guid == mcg_req->MGID.gid_guid) &&
4768f07a6d2aSShantkumar Hiremath (head->ml_mgid.gid_prefix == mcg_req->MGID.gid_prefix) &&
4769f07a6d2aSShantkumar Hiremath (head->ml_sgid.gid_guid == mcg_req->PortGID.gid_guid)) {
4770f07a6d2aSShantkumar Hiremath if (!(head->ml_jstate & mcg_req->JoinState)) {
4771f07a6d2aSShantkumar Hiremath IBTF_DPRINTF_L2(cmlog, "ibcm_del_decr_mcg_entry"
4772f07a6d2aSShantkumar Hiremath ": JoinState mismatch %X %X)",
4773f07a6d2aSShantkumar Hiremath head->ml_jstate, mcg_req->JoinState);
4774f07a6d2aSShantkumar Hiremath }
4775f07a6d2aSShantkumar Hiremath /* Decrement the count */
4776f07a6d2aSShantkumar Hiremath head->ml_refcnt--;
4777f07a6d2aSShantkumar Hiremath
4778f07a6d2aSShantkumar Hiremath if (head->ml_refcnt == 0) {
4779f07a6d2aSShantkumar Hiremath *jstate = head->ml_jstate;
4780f07a6d2aSShantkumar Hiremath
4781f07a6d2aSShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibcm_del_decr_mcg_entry"
4782f07a6d2aSShantkumar Hiremath ": refcnt is ZERO, so delete the entry ");
4783f07a6d2aSShantkumar Hiremath if ((head == ibcm_mcglist) || (prev == NULL)) {
4784f07a6d2aSShantkumar Hiremath ibcm_mcglist = head->ml_next;
4785f07a6d2aSShantkumar Hiremath } else if (prev != NULL) {
4786f07a6d2aSShantkumar Hiremath prev->ml_next = head->ml_next;
4787f07a6d2aSShantkumar Hiremath }
4788f07a6d2aSShantkumar Hiremath mutex_exit(&ibcm_mcglist_lock);
4789f07a6d2aSShantkumar Hiremath
4790f07a6d2aSShantkumar Hiremath kmem_free(head, sizeof (ibcm_mcg_list_t));
4791f07a6d2aSShantkumar Hiremath return (IBCM_SUCCESS);
4792f07a6d2aSShantkumar Hiremath }
4793f07a6d2aSShantkumar Hiremath mutex_exit(&ibcm_mcglist_lock);
4794f07a6d2aSShantkumar Hiremath return (IBCM_LOOKUP_EXISTS);
4795f07a6d2aSShantkumar Hiremath }
4796f07a6d2aSShantkumar Hiremath prev = head;
4797f07a6d2aSShantkumar Hiremath head = head->ml_next;
4798f07a6d2aSShantkumar Hiremath }
4799f07a6d2aSShantkumar Hiremath mutex_exit(&ibcm_mcglist_lock);
4800f07a6d2aSShantkumar Hiremath
4801f07a6d2aSShantkumar Hiremath /*
4802f07a6d2aSShantkumar Hiremath * If we are here, something went wrong, we don't have the entry
4803f07a6d2aSShantkumar Hiremath * for that MCG being joined.
4804f07a6d2aSShantkumar Hiremath */
4805f07a6d2aSShantkumar Hiremath IBTF_DPRINTF_L2(cmlog, "ibcm_del_decr_mcg_entry: Match NOT "
4806f07a6d2aSShantkumar Hiremath "Found ");
4807f07a6d2aSShantkumar Hiremath
4808f07a6d2aSShantkumar Hiremath return (IBCM_LOOKUP_FAIL);
4809f07a6d2aSShantkumar Hiremath }
4810f07a6d2aSShantkumar Hiremath
4811f07a6d2aSShantkumar Hiremath
48127c478bd9Sstevel@tonic-gate /*
48137c478bd9Sstevel@tonic-gate * Function:
48147c478bd9Sstevel@tonic-gate * ibt_join_mcg
48157c478bd9Sstevel@tonic-gate * Input:
48167c478bd9Sstevel@tonic-gate * rgid The request GID that defines the HCA port from which a
48177c478bd9Sstevel@tonic-gate * contact to SA Access is performed to add the specified
48187c478bd9Sstevel@tonic-gate * endport GID ((mcg_attr->mc_pgid) to a multicast group.
48197c478bd9Sstevel@tonic-gate * If mcg_attr->mc_pgid is null, then this (rgid) will be
48207c478bd9Sstevel@tonic-gate * treated as endport GID that is to be added to the
48217c478bd9Sstevel@tonic-gate * multicast group.
48227c478bd9Sstevel@tonic-gate *
48237c478bd9Sstevel@tonic-gate * mcg_attr A pointer to an ibt_mcg_attr_t structure that defines
48247c478bd9Sstevel@tonic-gate * the attributes of the desired multicast group to be
48257c478bd9Sstevel@tonic-gate * created or joined.
48267c478bd9Sstevel@tonic-gate *
48277c478bd9Sstevel@tonic-gate * func NULL or a pointer to a function to call when
48287c478bd9Sstevel@tonic-gate * ibt_join_mcg() completes. If 'func' is not NULL then
48297c478bd9Sstevel@tonic-gate * ibt_join_mcg() will return as soon as possible after
48307c478bd9Sstevel@tonic-gate * initiating the multicast group join/create process.
48317c478bd9Sstevel@tonic-gate * 'func' is then called when the process completes.
48327c478bd9Sstevel@tonic-gate *
48337c478bd9Sstevel@tonic-gate * arg Argument to the 'func'.
48347c478bd9Sstevel@tonic-gate *
48357c478bd9Sstevel@tonic-gate * Output:
48367c478bd9Sstevel@tonic-gate * mcg_info_p A pointer to the ibt_mcg_info_t structure, allocated
48377c478bd9Sstevel@tonic-gate * by the caller, where the attributes of the created or
48387c478bd9Sstevel@tonic-gate * joined multicast group are copied.
48397c478bd9Sstevel@tonic-gate * Returns:
48407c478bd9Sstevel@tonic-gate * IBT_SUCCESS
48417c478bd9Sstevel@tonic-gate * IBT_INVALID_PARAM
48427c478bd9Sstevel@tonic-gate * IBT_MCG_RECORDS_NOT_FOUND
48437c478bd9Sstevel@tonic-gate * IBT_INSUFF_RESOURCE
48447c478bd9Sstevel@tonic-gate * Description:
48457c478bd9Sstevel@tonic-gate * Join a multicast group. The first full member "join" causes the MCG
48467c478bd9Sstevel@tonic-gate * to be created.
48477c478bd9Sstevel@tonic-gate */
48487c478bd9Sstevel@tonic-gate ibt_status_t
ibt_join_mcg(ib_gid_t rgid,ibt_mcg_attr_t * mcg_attr,ibt_mcg_info_t * mcg_info_p,ibt_mcg_handler_t func,void * arg)48497c478bd9Sstevel@tonic-gate ibt_join_mcg(ib_gid_t rgid, ibt_mcg_attr_t *mcg_attr,
48507c478bd9Sstevel@tonic-gate ibt_mcg_info_t *mcg_info_p, ibt_mcg_handler_t func, void *arg)
48517c478bd9Sstevel@tonic-gate {
48527c478bd9Sstevel@tonic-gate ibcm_join_mcg_tqarg_t *mcg_tq;
48537c478bd9Sstevel@tonic-gate int flag = ((func == NULL) ? KM_SLEEP : KM_NOSLEEP);
48547c478bd9Sstevel@tonic-gate
48557c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_join_mcg(%llX:%llX, %p)", rgid.gid_prefix,
48567c478bd9Sstevel@tonic-gate rgid.gid_guid, mcg_attr);
48577c478bd9Sstevel@tonic-gate
48587c478bd9Sstevel@tonic-gate if ((rgid.gid_prefix == 0) || (rgid.gid_guid == 0)) {
48597c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: Request GID is required");
48607c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
48617c478bd9Sstevel@tonic-gate }
48627c478bd9Sstevel@tonic-gate
48637c478bd9Sstevel@tonic-gate if ((mcg_attr->mc_pkey == IB_PKEY_INVALID_LIMITED) ||
48647c478bd9Sstevel@tonic-gate (mcg_attr->mc_pkey == IB_PKEY_INVALID_FULL)) {
48657c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: Invalid P_Key specified");
48667c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
48677c478bd9Sstevel@tonic-gate }
48687c478bd9Sstevel@tonic-gate
48697c478bd9Sstevel@tonic-gate if (mcg_attr->mc_join_state == 0) {
48707c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: JoinState not specified");
48717c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
48727c478bd9Sstevel@tonic-gate }
48737c478bd9Sstevel@tonic-gate
48747c478bd9Sstevel@tonic-gate if (mcg_info_p == NULL) {
48757c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: mcg_info_p is NULL");
48767c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
48777c478bd9Sstevel@tonic-gate }
48787c478bd9Sstevel@tonic-gate
48797c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*mcg_tq))
48807c478bd9Sstevel@tonic-gate
48817c478bd9Sstevel@tonic-gate mcg_tq = kmem_alloc(sizeof (ibcm_join_mcg_tqarg_t), flag);
48827c478bd9Sstevel@tonic-gate if (mcg_tq == NULL) {
48837c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: "
48847c478bd9Sstevel@tonic-gate "Unable to allocate memory for local usage.");
48857c478bd9Sstevel@tonic-gate return (IBT_INSUFF_KERNEL_RESOURCE);
48867c478bd9Sstevel@tonic-gate }
48877c478bd9Sstevel@tonic-gate
48887c478bd9Sstevel@tonic-gate mcg_tq->rgid = rgid;
48897c478bd9Sstevel@tonic-gate bcopy(mcg_attr, &mcg_tq->mcg_attr, sizeof (ibt_mcg_attr_t));
48907c478bd9Sstevel@tonic-gate mcg_tq->mcg_infop = mcg_info_p;
48917c478bd9Sstevel@tonic-gate mcg_tq->func = func;
48927c478bd9Sstevel@tonic-gate mcg_tq->arg = arg;
48937c478bd9Sstevel@tonic-gate
48947c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*mcg_tq))
48957c478bd9Sstevel@tonic-gate
48967c478bd9Sstevel@tonic-gate if (func != NULL) { /* Non-Blocking */
48977c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_join_mcg: Non-Blocking Call");
48987c478bd9Sstevel@tonic-gate if (taskq_dispatch(ibcm_taskq, ibcm_process_async_join_mcg,
4899*fc8ae2ecSToomas Soome mcg_tq, TQ_NOSLEEP) == TASKQID_INVALID) {
49007c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: Failed to "
49017c478bd9Sstevel@tonic-gate "Dispatch the TaskQ");
49027c478bd9Sstevel@tonic-gate kmem_free(mcg_tq, sizeof (ibcm_join_mcg_tqarg_t));
49037c478bd9Sstevel@tonic-gate return (IBT_INSUFF_KERNEL_RESOURCE);
49047c478bd9Sstevel@tonic-gate } else
49057c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
49067c478bd9Sstevel@tonic-gate } else { /* Blocking */
49077c478bd9Sstevel@tonic-gate return (ibcm_process_join_mcg(mcg_tq));
49087c478bd9Sstevel@tonic-gate }
49097c478bd9Sstevel@tonic-gate }
49107c478bd9Sstevel@tonic-gate
49117c478bd9Sstevel@tonic-gate static void
ibcm_process_async_join_mcg(void * tq_arg)49127c478bd9Sstevel@tonic-gate ibcm_process_async_join_mcg(void *tq_arg)
49137c478bd9Sstevel@tonic-gate {
49147c478bd9Sstevel@tonic-gate (void) ibcm_process_join_mcg(tq_arg);
49157c478bd9Sstevel@tonic-gate }
49167c478bd9Sstevel@tonic-gate
49177c478bd9Sstevel@tonic-gate static ibt_status_t
ibcm_process_join_mcg(void * taskq_arg)49187c478bd9Sstevel@tonic-gate ibcm_process_join_mcg(void *taskq_arg)
49197c478bd9Sstevel@tonic-gate {
49207c478bd9Sstevel@tonic-gate sa_mcmember_record_t mcg_req;
49217c478bd9Sstevel@tonic-gate sa_mcmember_record_t *mcg_resp;
49227c478bd9Sstevel@tonic-gate ibmf_saa_access_args_t access_args;
49237c478bd9Sstevel@tonic-gate ibmf_saa_handle_t saa_handle;
49247c478bd9Sstevel@tonic-gate uint64_t component_mask = 0;
49257c478bd9Sstevel@tonic-gate ibt_status_t retval;
49267c478bd9Sstevel@tonic-gate ibtl_cm_hca_port_t hca_port;
49277c478bd9Sstevel@tonic-gate uint_t num_records;
49287c478bd9Sstevel@tonic-gate size_t length;
49297c478bd9Sstevel@tonic-gate ibcm_hca_info_t *hcap;
49307c478bd9Sstevel@tonic-gate ibcm_join_mcg_tqarg_t *mcg_arg = (ibcm_join_mcg_tqarg_t *)taskq_arg;
49317c478bd9Sstevel@tonic-gate ibt_mcg_info_t *mcg_info_p = mcg_arg->mcg_infop;
49327c478bd9Sstevel@tonic-gate
49337c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_join_mcg(%p)", mcg_arg);
49347c478bd9Sstevel@tonic-gate
49357c478bd9Sstevel@tonic-gate retval = ibtl_cm_get_hca_port(mcg_arg->rgid, 0, &hca_port);
49367c478bd9Sstevel@tonic-gate if (retval != IBT_SUCCESS) {
49377c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_join_mcg: Failed to get "
49387c478bd9Sstevel@tonic-gate "port info from specified RGID: status = %d", retval);
49397c478bd9Sstevel@tonic-gate goto ibcm_join_mcg_exit1;
49407c478bd9Sstevel@tonic-gate }
49417c478bd9Sstevel@tonic-gate
49427c478bd9Sstevel@tonic-gate bzero(&mcg_req, sizeof (sa_mcmember_record_t));
49437c478bd9Sstevel@tonic-gate
49447c478bd9Sstevel@tonic-gate if ((mcg_arg->mcg_attr.mc_pgid.gid_prefix == 0) ||
49457c478bd9Sstevel@tonic-gate (mcg_arg->mcg_attr.mc_pgid.gid_guid == 0)) {
49467c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_join_mcg: "
49477c478bd9Sstevel@tonic-gate "Request GID is Port GID");
49487c478bd9Sstevel@tonic-gate mcg_req.PortGID = mcg_arg->rgid;
49497c478bd9Sstevel@tonic-gate } else {
49507c478bd9Sstevel@tonic-gate mcg_req.PortGID = mcg_arg->mcg_attr.mc_pgid;
49517c478bd9Sstevel@tonic-gate }
49527c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_PORTGID;
49537c478bd9Sstevel@tonic-gate
49547c478bd9Sstevel@tonic-gate mcg_req.Q_Key = mcg_arg->mcg_attr.mc_qkey;
49557c478bd9Sstevel@tonic-gate mcg_req.P_Key = mcg_arg->mcg_attr.mc_pkey;
49567c478bd9Sstevel@tonic-gate mcg_req.JoinState = mcg_arg->mcg_attr.mc_join_state;
49577c478bd9Sstevel@tonic-gate mcg_req.TClass = mcg_arg->mcg_attr.mc_tclass;
49587c478bd9Sstevel@tonic-gate mcg_req.FlowLabel = mcg_arg->mcg_attr.mc_flow;
49597c478bd9Sstevel@tonic-gate mcg_req.SL = mcg_arg->mcg_attr.mc_sl;
49607c478bd9Sstevel@tonic-gate
49617c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_QKEY | SA_MC_COMPMASK_PKEY |
49627c478bd9Sstevel@tonic-gate SA_MC_COMPMASK_JOINSTATE | SA_MC_COMPMASK_TCLASS |
49637c478bd9Sstevel@tonic-gate SA_MC_COMPMASK_FLOWLABEL | SA_MC_COMPMASK_SL;
49647c478bd9Sstevel@tonic-gate
49657c478bd9Sstevel@tonic-gate /* If client has specified MGID, use it else SA will assign one. */
49667c478bd9Sstevel@tonic-gate if ((mcg_arg->mcg_attr.mc_mgid.gid_prefix >> 56ULL & 0xFF) == 0xFF) {
49677c478bd9Sstevel@tonic-gate mcg_req.MGID = mcg_arg->mcg_attr.mc_mgid;
49687c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_MGID;
49697c478bd9Sstevel@tonic-gate }
49707c478bd9Sstevel@tonic-gate
4971d3a82192SShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibcm_process_join_mcg: ");
4972d3a82192SShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "PGID=%016llX:%016llX, ",
4973d3a82192SShantkumar Hiremath mcg_req.PortGID.gid_prefix, mcg_req.PortGID.gid_guid);
4974d3a82192SShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "MGID=%016llX:%016llX",
4975d3a82192SShantkumar Hiremath mcg_req.MGID.gid_prefix, mcg_req.MGID.gid_guid);
4976d3a82192SShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "JoinState = %X",
4977d3a82192SShantkumar Hiremath mcg_arg->mcg_attr.mc_join_state);
4978d3a82192SShantkumar Hiremath IBTF_DPRINTF_L5(cmlog, "QKey %lX, PKey %lX",
4979d3a82192SShantkumar Hiremath mcg_arg->mcg_attr.mc_qkey, mcg_arg->mcg_attr.mc_pkey);
4980d3a82192SShantkumar Hiremath IBTF_DPRINTF_L5(cmlog, "Scope %X, MLID %X",
4981d3a82192SShantkumar Hiremath mcg_arg->mcg_attr.mc_scope, mcg_arg->mcg_attr.mc_mlid);
49827c478bd9Sstevel@tonic-gate
49837c478bd9Sstevel@tonic-gate /* Is MTU specified. */
49847c478bd9Sstevel@tonic-gate if (mcg_arg->mcg_attr.mc_mtu_req.r_mtu) {
49857c478bd9Sstevel@tonic-gate mcg_req.MTU = mcg_arg->mcg_attr.mc_mtu_req.r_mtu;
49867c478bd9Sstevel@tonic-gate mcg_req.MTUSelector = mcg_arg->mcg_attr.mc_mtu_req.r_selector;
49877c478bd9Sstevel@tonic-gate
49887c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_MTUSELECTOR |
49897c478bd9Sstevel@tonic-gate SA_MC_COMPMASK_MTU;
49907c478bd9Sstevel@tonic-gate }
49917c478bd9Sstevel@tonic-gate
49927c478bd9Sstevel@tonic-gate /* Is RATE specified. */
49937c478bd9Sstevel@tonic-gate if (mcg_arg->mcg_attr.mc_rate_req.r_srate) {
49947c478bd9Sstevel@tonic-gate mcg_req.Rate = mcg_arg->mcg_attr.mc_rate_req.r_srate;
49957c478bd9Sstevel@tonic-gate mcg_req.RateSelector =
49967c478bd9Sstevel@tonic-gate mcg_arg->mcg_attr.mc_rate_req.r_selector;
49977c478bd9Sstevel@tonic-gate
49987c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_RATESELECTOR |
49997c478bd9Sstevel@tonic-gate SA_MC_COMPMASK_RATE;
50007c478bd9Sstevel@tonic-gate }
50017c478bd9Sstevel@tonic-gate
50027c478bd9Sstevel@tonic-gate /* Is Packet Life Time specified. */
50037c478bd9Sstevel@tonic-gate if (mcg_arg->mcg_attr.mc_pkt_lt_req.p_pkt_lt) {
50047c478bd9Sstevel@tonic-gate mcg_req.Rate = mcg_arg->mcg_attr.mc_pkt_lt_req.p_pkt_lt;
50057c478bd9Sstevel@tonic-gate mcg_req.RateSelector =
50067c478bd9Sstevel@tonic-gate mcg_arg->mcg_attr.mc_pkt_lt_req.p_selector;
50077c478bd9Sstevel@tonic-gate
50087c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_PKTLTSELECTOR |
50097c478bd9Sstevel@tonic-gate SA_MC_COMPMASK_PKTLT;
50107c478bd9Sstevel@tonic-gate }
50117c478bd9Sstevel@tonic-gate
50127c478bd9Sstevel@tonic-gate if (mcg_arg->mcg_attr.mc_hop) {
50137c478bd9Sstevel@tonic-gate mcg_req.HopLimit = mcg_arg->mcg_attr.mc_hop;
50147c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_HOPLIMIT;
50157c478bd9Sstevel@tonic-gate }
50167c478bd9Sstevel@tonic-gate
50177c478bd9Sstevel@tonic-gate if (mcg_arg->mcg_attr.mc_scope) {
50187c478bd9Sstevel@tonic-gate mcg_req.Scope = mcg_arg->mcg_attr.mc_scope;
50197c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_SCOPE;
50207c478bd9Sstevel@tonic-gate }
50217c478bd9Sstevel@tonic-gate
50227c478bd9Sstevel@tonic-gate if (mcg_arg->mcg_attr.mc_mlid) {
50237c478bd9Sstevel@tonic-gate mcg_req.MLID = mcg_arg->mcg_attr.mc_mlid;
50247c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_MLID;
50257c478bd9Sstevel@tonic-gate }
50267c478bd9Sstevel@tonic-gate
50277c478bd9Sstevel@tonic-gate /* Get SA Access Handle. */
50287c478bd9Sstevel@tonic-gate hcap = ibcm_find_hca_entry(hca_port.hp_hca_guid);
50297c478bd9Sstevel@tonic-gate if (hcap == NULL) {
50307c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_join_mcg: NO HCA found");
50317c478bd9Sstevel@tonic-gate
50327c478bd9Sstevel@tonic-gate retval = IBT_HCA_BUSY_DETACHING;
50337c478bd9Sstevel@tonic-gate goto ibcm_join_mcg_exit1;
50347c478bd9Sstevel@tonic-gate }
50357c478bd9Sstevel@tonic-gate
50367c478bd9Sstevel@tonic-gate saa_handle = ibcm_get_saa_handle(hcap, hca_port.hp_port);
50377c478bd9Sstevel@tonic-gate if (saa_handle == NULL) {
50387c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_join_mcg: SA Handle NULL");
50397c478bd9Sstevel@tonic-gate
50407c478bd9Sstevel@tonic-gate retval = IBT_HCA_PORT_NOT_ACTIVE;
50417c478bd9Sstevel@tonic-gate goto ibcm_join_mcg_exit;
50427c478bd9Sstevel@tonic-gate }
50437c478bd9Sstevel@tonic-gate
50447c478bd9Sstevel@tonic-gate if ((mcg_arg->mcg_attr.mc_pgid.gid_prefix != 0) &&
50457c478bd9Sstevel@tonic-gate (mcg_arg->mcg_attr.mc_pgid.gid_guid != 0)) {
50467c478bd9Sstevel@tonic-gate retval = ibtl_cm_get_hca_port(mcg_arg->mcg_attr.mc_pgid, 0,
50477c478bd9Sstevel@tonic-gate &hca_port);
50487c478bd9Sstevel@tonic-gate if (retval != IBT_SUCCESS) {
50497c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_join_mcg: Failed "
50507c478bd9Sstevel@tonic-gate "to get PortInfo of specified PGID: status = %d",
50517c478bd9Sstevel@tonic-gate retval);
50527c478bd9Sstevel@tonic-gate goto ibcm_join_mcg_exit1;
50537c478bd9Sstevel@tonic-gate }
50547c478bd9Sstevel@tonic-gate }
50557c478bd9Sstevel@tonic-gate
50567c478bd9Sstevel@tonic-gate /* Contact SA Access */
50577c478bd9Sstevel@tonic-gate access_args.sq_attr_id = SA_MCMEMBERRECORD_ATTRID;
50587c478bd9Sstevel@tonic-gate access_args.sq_access_type = IBMF_SAA_UPDATE;
50597c478bd9Sstevel@tonic-gate access_args.sq_component_mask = component_mask;
50607c478bd9Sstevel@tonic-gate access_args.sq_template = &mcg_req;
50617c478bd9Sstevel@tonic-gate access_args.sq_template_length = sizeof (sa_mcmember_record_t);
50627c478bd9Sstevel@tonic-gate access_args.sq_callback = NULL;
50637c478bd9Sstevel@tonic-gate access_args.sq_callback_arg = NULL;
50647c478bd9Sstevel@tonic-gate
50657c478bd9Sstevel@tonic-gate retval = ibcm_contact_sa_access(saa_handle, &access_args, &length,
50667c478bd9Sstevel@tonic-gate (void **)&mcg_resp);
50677c478bd9Sstevel@tonic-gate if (retval != IBT_SUCCESS) {
50687c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_join_mcg: "
50697c478bd9Sstevel@tonic-gate "SA Access Failed");
50707c478bd9Sstevel@tonic-gate goto ibcm_join_mcg_exit;
50717c478bd9Sstevel@tonic-gate }
50727c478bd9Sstevel@tonic-gate
50737c478bd9Sstevel@tonic-gate num_records = length/sizeof (sa_mcmember_record_t);
50747c478bd9Sstevel@tonic-gate
50757c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_join_mcg: "
50767c478bd9Sstevel@tonic-gate "Found %d MCMember Records", num_records);
50777c478bd9Sstevel@tonic-gate
50787c478bd9Sstevel@tonic-gate /* Validate the returned number of records. */
50797c478bd9Sstevel@tonic-gate if ((mcg_resp != NULL) && (num_records > 0)) {
50807c478bd9Sstevel@tonic-gate /* Update the return values. */
50817c478bd9Sstevel@tonic-gate mcg_info_p->mc_adds_vect.av_dgid = mcg_resp->MGID;
50827c478bd9Sstevel@tonic-gate mcg_info_p->mc_adds_vect.av_sgid = mcg_resp->PortGID;
50837c478bd9Sstevel@tonic-gate mcg_info_p->mc_adds_vect.av_srate = mcg_resp->Rate;
50847c478bd9Sstevel@tonic-gate mcg_info_p->mc_adds_vect.av_srvl = mcg_resp->SL;
50857c478bd9Sstevel@tonic-gate mcg_info_p->mc_adds_vect.av_flow = mcg_resp->FlowLabel;
50867c478bd9Sstevel@tonic-gate mcg_info_p->mc_adds_vect.av_tclass = mcg_resp->TClass;
50877c478bd9Sstevel@tonic-gate mcg_info_p->mc_adds_vect.av_hop = mcg_resp->HopLimit;
50887c478bd9Sstevel@tonic-gate mcg_info_p->mc_adds_vect.av_send_grh = B_TRUE;
50897c478bd9Sstevel@tonic-gate mcg_info_p->mc_adds_vect.av_dlid = mcg_resp->MLID;
50907c478bd9Sstevel@tonic-gate mcg_info_p->mc_mtu = mcg_resp->MTU;
50917c478bd9Sstevel@tonic-gate mcg_info_p->mc_qkey = mcg_resp->Q_Key;
50927c478bd9Sstevel@tonic-gate
50937c478bd9Sstevel@tonic-gate retval = ibt_pkey2index_byguid(hca_port.hp_hca_guid,
50947c478bd9Sstevel@tonic-gate hca_port.hp_port, mcg_resp->P_Key, &mcg_info_p->mc_pkey_ix);
50957c478bd9Sstevel@tonic-gate if (retval != IBT_SUCCESS) {
50967c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_join_mcg: "
50977c478bd9Sstevel@tonic-gate "Pkey2Index Conversion failed<%d>", retval);
50987c478bd9Sstevel@tonic-gate mcg_info_p->mc_pkey_ix = 0;
50997c478bd9Sstevel@tonic-gate }
51007c478bd9Sstevel@tonic-gate
51017c478bd9Sstevel@tonic-gate mcg_info_p->mc_scope = mcg_resp->Scope;
51027c478bd9Sstevel@tonic-gate mcg_info_p->mc_pkt_lt = mcg_resp->PacketLifeTime;
51037c478bd9Sstevel@tonic-gate
51047c478bd9Sstevel@tonic-gate mcg_info_p->mc_adds_vect.av_port_num = hca_port.hp_port;
51057c478bd9Sstevel@tonic-gate mcg_info_p->mc_adds_vect.av_sgid_ix = hca_port.hp_sgid_ix;
51067c478bd9Sstevel@tonic-gate mcg_info_p->mc_adds_vect.av_src_path = 0;
51077c478bd9Sstevel@tonic-gate
5108f07a6d2aSShantkumar Hiremath /* Add or Incr the matching MCG entry. */
5109f07a6d2aSShantkumar Hiremath ibcm_add_incr_mcg_entry(&mcg_req, mcg_resp);
51107c478bd9Sstevel@tonic-gate /* Deallocate the memory allocated by SA for mcg_resp. */
51117c478bd9Sstevel@tonic-gate kmem_free(mcg_resp, length);
5112f07a6d2aSShantkumar Hiremath
51137c478bd9Sstevel@tonic-gate retval = IBT_SUCCESS;
51147c478bd9Sstevel@tonic-gate } else {
51157c478bd9Sstevel@tonic-gate retval = IBT_MCG_RECORDS_NOT_FOUND;
51167c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_join_mcg: "
51177c478bd9Sstevel@tonic-gate "MCG RECORDS NOT FOUND");
51187c478bd9Sstevel@tonic-gate }
51197c478bd9Sstevel@tonic-gate
51207c478bd9Sstevel@tonic-gate ibcm_join_mcg_exit:
51217c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
51227c478bd9Sstevel@tonic-gate
51237c478bd9Sstevel@tonic-gate ibcm_join_mcg_exit1:
51247c478bd9Sstevel@tonic-gate if (mcg_arg->func)
51257c478bd9Sstevel@tonic-gate (*(mcg_arg->func))(mcg_arg->arg, retval, mcg_info_p);
51267c478bd9Sstevel@tonic-gate
51277c478bd9Sstevel@tonic-gate kmem_free(mcg_arg, sizeof (ibcm_join_mcg_tqarg_t));
51287c478bd9Sstevel@tonic-gate
51297c478bd9Sstevel@tonic-gate return (retval);
51307c478bd9Sstevel@tonic-gate }
51317c478bd9Sstevel@tonic-gate
51327c478bd9Sstevel@tonic-gate
51337c478bd9Sstevel@tonic-gate /*
51347c478bd9Sstevel@tonic-gate * Function:
51357c478bd9Sstevel@tonic-gate * ibt_leave_mcg
51367c478bd9Sstevel@tonic-gate * Input:
51377c478bd9Sstevel@tonic-gate * rgid The request GID that defines the HCA port upon which
51387c478bd9Sstevel@tonic-gate * to send the request to the Subnet Administrator, to
51397c478bd9Sstevel@tonic-gate * remove the specified port (port_gid) from the multicast
51407c478bd9Sstevel@tonic-gate * group. If 'port_gid' is the Reserved GID (i.e.
51417c478bd9Sstevel@tonic-gate * port_gid.gid_prefix = 0 and port_gid.gid_guid = 0),
51427c478bd9Sstevel@tonic-gate * then the end-port associated with 'rgid' is removed
51437c478bd9Sstevel@tonic-gate * from the multicast group.
51447c478bd9Sstevel@tonic-gate *
51457c478bd9Sstevel@tonic-gate * mc_gid A multicast group GID as returned from ibt_join_mcg()
51467c478bd9Sstevel@tonic-gate * call. This is optional, if not specified (i.e.
51477c478bd9Sstevel@tonic-gate * mc_gid.gid_prefix has 0xFF in its upper 8 bits to
51487c478bd9Sstevel@tonic-gate * identify this as being a multicast GID), then the
51497c478bd9Sstevel@tonic-gate * port is removed from all the multicast groups of
51507c478bd9Sstevel@tonic-gate * which it is a member.
51517c478bd9Sstevel@tonic-gate *
51527c478bd9Sstevel@tonic-gate * port_gid This is optional, if not the Reserved GID (gid_prefix
51537c478bd9Sstevel@tonic-gate * and gid_guid not equal to 0), then this specifies the
51547c478bd9Sstevel@tonic-gate * endport GID of the multicast group member being deleted
51557c478bd9Sstevel@tonic-gate * from the group. If it is the Reserved GID (gid_prefix
51567c478bd9Sstevel@tonic-gate * and gid_guid equal to 0) then the member endport GID is
51577c478bd9Sstevel@tonic-gate * determined from 'rgid'.
51587c478bd9Sstevel@tonic-gate *
51597c478bd9Sstevel@tonic-gate * mc_join_state The Join State attribute used when the group was joined
51607c478bd9Sstevel@tonic-gate * using ibt_join_mcg(). This Join State component must
51617c478bd9Sstevel@tonic-gate * contains at least one bit set to 1 in the same position
51627c478bd9Sstevel@tonic-gate * as that used during ibt_join_mcg(). i.e. the logical
51637c478bd9Sstevel@tonic-gate * AND of the two JoinState components is not all zeros.
51647c478bd9Sstevel@tonic-gate * This Join State component must not have some bits set
51657c478bd9Sstevel@tonic-gate * which are not set using ibt_join_mcg().
51667c478bd9Sstevel@tonic-gate * Output:
51677c478bd9Sstevel@tonic-gate * None.
51687c478bd9Sstevel@tonic-gate * Returns:
51697c478bd9Sstevel@tonic-gate * IBT_SUCCESS
51707c478bd9Sstevel@tonic-gate * IBT_INVALID_PARAM
51717c478bd9Sstevel@tonic-gate * IBT_MC_GROUP_INVALID
51727c478bd9Sstevel@tonic-gate * IBT_INSUFF_RESOURCE
51737c478bd9Sstevel@tonic-gate * Description:
51747c478bd9Sstevel@tonic-gate * The port associated with the port GID shall be removed from the
51757c478bd9Sstevel@tonic-gate * multicast group specified by MGID (mc_gid) or from all the multicast
51767c478bd9Sstevel@tonic-gate * groups of which it is a member if the MGID (mc_gid) is not specified.
51777c478bd9Sstevel@tonic-gate *
51787c478bd9Sstevel@tonic-gate * The last full member to leave causes the destruction of the Multicast
51797c478bd9Sstevel@tonic-gate * Group.
51807c478bd9Sstevel@tonic-gate */
51817c478bd9Sstevel@tonic-gate ibt_status_t
ibt_leave_mcg(ib_gid_t rgid,ib_gid_t mc_gid,ib_gid_t port_gid,uint8_t mc_join_state)51827c478bd9Sstevel@tonic-gate ibt_leave_mcg(ib_gid_t rgid, ib_gid_t mc_gid, ib_gid_t port_gid,
51837c478bd9Sstevel@tonic-gate uint8_t mc_join_state)
51847c478bd9Sstevel@tonic-gate {
51857c478bd9Sstevel@tonic-gate sa_mcmember_record_t mcg_req;
51867c478bd9Sstevel@tonic-gate ibmf_saa_access_args_t access_args;
51877c478bd9Sstevel@tonic-gate ibmf_saa_handle_t saa_handle;
51887c478bd9Sstevel@tonic-gate uint64_t component_mask = 0;
51897c478bd9Sstevel@tonic-gate int sa_retval;
51907c478bd9Sstevel@tonic-gate ibt_status_t retval;
5191f07a6d2aSShantkumar Hiremath ibcm_status_t ret;
51927c478bd9Sstevel@tonic-gate ibtl_cm_hca_port_t hca_port;
51937c478bd9Sstevel@tonic-gate size_t length;
51947c478bd9Sstevel@tonic-gate void *results_p;
51957c478bd9Sstevel@tonic-gate ibcm_hca_info_t *hcap;
5196f07a6d2aSShantkumar Hiremath uint8_t jstate = 0;
51977c478bd9Sstevel@tonic-gate
51987c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_leave_mcg(%llX:%llX, %llX:%llX)",
51997c478bd9Sstevel@tonic-gate rgid.gid_prefix, rgid.gid_guid, mc_gid.gid_prefix, mc_gid.gid_guid);
52007c478bd9Sstevel@tonic-gate
52017c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_leave_mcg(%llX:%llX, 0x%X)",
52027c478bd9Sstevel@tonic-gate port_gid.gid_prefix, port_gid.gid_guid, mc_join_state);
52037c478bd9Sstevel@tonic-gate
52047c478bd9Sstevel@tonic-gate if ((rgid.gid_prefix == 0) || (rgid.gid_guid == 0)) {
52057c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_leave_mcg: RequestGID is required");
52067c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
52077c478bd9Sstevel@tonic-gate }
52087c478bd9Sstevel@tonic-gate
52097c478bd9Sstevel@tonic-gate bzero(&mcg_req, sizeof (sa_mcmember_record_t));
52107c478bd9Sstevel@tonic-gate
52117c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_leave_mcg: MGID: %llX%llX",
52127c478bd9Sstevel@tonic-gate mc_gid.gid_prefix, mc_gid.gid_guid);
52137c478bd9Sstevel@tonic-gate
52147c478bd9Sstevel@tonic-gate /* Validate MGID */
52157c478bd9Sstevel@tonic-gate if ((mc_gid.gid_prefix >> 56ULL & 0xFF) == 0xFF) {
52167c478bd9Sstevel@tonic-gate mcg_req.MGID = mc_gid;
52177c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_MGID;
52187c478bd9Sstevel@tonic-gate } else if ((mc_gid.gid_prefix != 0) || (mc_gid.gid_guid != 0)) {
52197c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_leave_mcg: Invalid MGID specified");
52207c478bd9Sstevel@tonic-gate return (IBT_MC_MGID_INVALID);
52217c478bd9Sstevel@tonic-gate }
52227c478bd9Sstevel@tonic-gate
52237c478bd9Sstevel@tonic-gate if ((port_gid.gid_prefix == 0) || (port_gid.gid_guid == 0)) {
52247c478bd9Sstevel@tonic-gate mcg_req.PortGID = rgid;
52257c478bd9Sstevel@tonic-gate } else {
52267c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_leave_mcg: Performing PROXY Leave");
52277c478bd9Sstevel@tonic-gate mcg_req.PortGID = port_gid;
52287c478bd9Sstevel@tonic-gate }
52297c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_PORTGID;
52307c478bd9Sstevel@tonic-gate
52317c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_leave_mcg: Port GID <%llX:%llX>",
52327c478bd9Sstevel@tonic-gate mcg_req.PortGID.gid_prefix, mcg_req.PortGID.gid_guid);
52337c478bd9Sstevel@tonic-gate
52347c478bd9Sstevel@tonic-gate /* Join State */
52357c478bd9Sstevel@tonic-gate mcg_req.JoinState = mc_join_state;
52367c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_JOINSTATE;
52377c478bd9Sstevel@tonic-gate
5238f07a6d2aSShantkumar Hiremath ret = ibcm_del_decr_mcg_entry(&mcg_req, &jstate);
5239f07a6d2aSShantkumar Hiremath if (ret == IBCM_LOOKUP_EXISTS) {
5240f07a6d2aSShantkumar Hiremath IBTF_DPRINTF_L3(cmlog, "ibt_leave_mcg: Multiple JoinMCG record "
5241f07a6d2aSShantkumar Hiremath " still exists, we shall leave for last leave_mcg call");
5242f07a6d2aSShantkumar Hiremath return (IBT_SUCCESS);
5243f07a6d2aSShantkumar Hiremath } else if (ret == IBCM_LOOKUP_FAIL) {
5244f07a6d2aSShantkumar Hiremath IBTF_DPRINTF_L2(cmlog, "ibt_leave_mcg: No Record found, "
5245f07a6d2aSShantkumar Hiremath "continue with leave_mcg call");
5246f07a6d2aSShantkumar Hiremath } else if ((ret == IBCM_SUCCESS) && (jstate != 0)) {
5247f07a6d2aSShantkumar Hiremath /*
5248f07a6d2aSShantkumar Hiremath * Update with cached "jstate", as this will be OR'ed of
5249f07a6d2aSShantkumar Hiremath * all ibt_join_mcg() calls for this record.
5250f07a6d2aSShantkumar Hiremath */
5251f07a6d2aSShantkumar Hiremath mcg_req.JoinState = jstate;
5252f07a6d2aSShantkumar Hiremath }
5253f07a6d2aSShantkumar Hiremath
52547c478bd9Sstevel@tonic-gate retval = ibtl_cm_get_hca_port(rgid, 0, &hca_port);
52557c478bd9Sstevel@tonic-gate if (retval != IBT_SUCCESS) {
52567c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_leave_mcg: Failed to get port info "
52577c478bd9Sstevel@tonic-gate "from specified RGID : status = %d", retval);
52587c478bd9Sstevel@tonic-gate return (retval);
52597c478bd9Sstevel@tonic-gate }
52607c478bd9Sstevel@tonic-gate
52617c478bd9Sstevel@tonic-gate /* Get SA Access Handle. */
52627c478bd9Sstevel@tonic-gate hcap = ibcm_find_hca_entry(hca_port.hp_hca_guid);
52637c478bd9Sstevel@tonic-gate if (hcap == NULL) {
52647c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_leave_mcg: "
52657c478bd9Sstevel@tonic-gate "NO HCA found");
52667c478bd9Sstevel@tonic-gate return (IBT_HCA_BUSY_DETACHING);
52677c478bd9Sstevel@tonic-gate }
52687c478bd9Sstevel@tonic-gate
52697c478bd9Sstevel@tonic-gate saa_handle = ibcm_get_saa_handle(hcap, hca_port.hp_port);
52707c478bd9Sstevel@tonic-gate if (saa_handle == NULL) {
52717c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_leave_mcg: saa_handle is NULL");
52727c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
52737c478bd9Sstevel@tonic-gate return (IBT_HCA_PORT_NOT_ACTIVE);
52747c478bd9Sstevel@tonic-gate }
52757c478bd9Sstevel@tonic-gate
52767c478bd9Sstevel@tonic-gate /* Contact SA Access */
52777c478bd9Sstevel@tonic-gate access_args.sq_attr_id = SA_MCMEMBERRECORD_ATTRID;
52787c478bd9Sstevel@tonic-gate access_args.sq_access_type = IBMF_SAA_DELETE;
52797c478bd9Sstevel@tonic-gate access_args.sq_component_mask = component_mask;
52807c478bd9Sstevel@tonic-gate access_args.sq_template = &mcg_req;
52817c478bd9Sstevel@tonic-gate access_args.sq_template_length = sizeof (sa_mcmember_record_t);
52827c478bd9Sstevel@tonic-gate access_args.sq_callback = NULL;
52837c478bd9Sstevel@tonic-gate access_args.sq_callback_arg = NULL;
52847c478bd9Sstevel@tonic-gate
52857c478bd9Sstevel@tonic-gate ibcm_sa_access_enter();
52867c478bd9Sstevel@tonic-gate
52877c478bd9Sstevel@tonic-gate sa_retval = ibmf_sa_access(saa_handle, &access_args, 0, &length,
52887c478bd9Sstevel@tonic-gate &results_p);
52897c478bd9Sstevel@tonic-gate if (sa_retval != IBMF_SUCCESS) {
52907c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_leave_mcg: SA access Failed: %d",
52917c478bd9Sstevel@tonic-gate sa_retval);
52927c478bd9Sstevel@tonic-gate (void) ibcm_ibmf_analyze_error(sa_retval);
52937c478bd9Sstevel@tonic-gate retval = IBT_MC_GROUP_INVALID;
52947c478bd9Sstevel@tonic-gate }
52957c478bd9Sstevel@tonic-gate
52967c478bd9Sstevel@tonic-gate ibcm_sa_access_exit();
52977c478bd9Sstevel@tonic-gate
52987c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
52997c478bd9Sstevel@tonic-gate
53007c478bd9Sstevel@tonic-gate return (retval);
53017c478bd9Sstevel@tonic-gate }
53027c478bd9Sstevel@tonic-gate
53037c478bd9Sstevel@tonic-gate
53047c478bd9Sstevel@tonic-gate /*
53057c478bd9Sstevel@tonic-gate * Function:
53067c478bd9Sstevel@tonic-gate * ibt_query_mcg
53077c478bd9Sstevel@tonic-gate * Input:
53087c478bd9Sstevel@tonic-gate * rgid The request GID that defines the HCA port upon which
53097c478bd9Sstevel@tonic-gate * to send the request to the Subnet Administrator, to
53107c478bd9Sstevel@tonic-gate * retrieve Multicast Records matching attributes as
53117c478bd9Sstevel@tonic-gate * specified through 'mcg_attr' argument.
53127c478bd9Sstevel@tonic-gate *
53137c478bd9Sstevel@tonic-gate * mcg_attr NULL or a pointer to an ibt_mcg_attr_t structure that
53147c478bd9Sstevel@tonic-gate * specifies MCG attributes that are to be matched.
53157c478bd9Sstevel@tonic-gate * Attributes that are not required can be wild carded
53167c478bd9Sstevel@tonic-gate * by specifying as '0'.
53177c478bd9Sstevel@tonic-gate *
53187c478bd9Sstevel@tonic-gate * mcgs_max_num The maximum number of matching multicast groups to
53197c478bd9Sstevel@tonic-gate * return. If zero, then all available matching multicast
53207c478bd9Sstevel@tonic-gate * groups are returned.
53217c478bd9Sstevel@tonic-gate * Output:
53227c478bd9Sstevel@tonic-gate * mcgs_info_p The address of an ibt_mcg_info_t pointer, where
53237c478bd9Sstevel@tonic-gate * multicast group information is returned. The actual
53247c478bd9Sstevel@tonic-gate * number of entries filled in the array is returned in
53257c478bd9Sstevel@tonic-gate * entries_p.
53267c478bd9Sstevel@tonic-gate *
53277c478bd9Sstevel@tonic-gate * entries_p The number of ibt_mcg_attr_t entries returned.
53287c478bd9Sstevel@tonic-gate * Returns:
53297c478bd9Sstevel@tonic-gate * IBT_SUCCESS
53307c478bd9Sstevel@tonic-gate * IBT_INVALID_PARAM
53317c478bd9Sstevel@tonic-gate * IBT_MCG_RECORDS_NOT_FOUND
53327c478bd9Sstevel@tonic-gate * Description:
53337c478bd9Sstevel@tonic-gate * Request information on multicast groups that match the parameters
53347c478bd9Sstevel@tonic-gate * specified in mcg_attr. Information on each multicast group is returned
53357c478bd9Sstevel@tonic-gate * to the caller in the form of an array of ibt_mcg_info_t.
53367c478bd9Sstevel@tonic-gate * ibt_query_mcg() allocates the memory for this array and returns a
53377c478bd9Sstevel@tonic-gate * pointer to the array (mcgs_p) and the number of entries in the array
53387c478bd9Sstevel@tonic-gate * (entries_p). This memory should be freed by the client using
53397c478bd9Sstevel@tonic-gate * ibt_free_mcg_info().
53407c478bd9Sstevel@tonic-gate */
53417c478bd9Sstevel@tonic-gate ibt_status_t
ibt_query_mcg(ib_gid_t rgid,ibt_mcg_attr_t * mcg_attr,uint_t mcgs_max_num,ibt_mcg_info_t ** mcgs_info_p,uint_t * entries_p)53427c478bd9Sstevel@tonic-gate ibt_query_mcg(ib_gid_t rgid, ibt_mcg_attr_t *mcg_attr, uint_t mcgs_max_num,
53437c478bd9Sstevel@tonic-gate ibt_mcg_info_t **mcgs_info_p, uint_t *entries_p)
53447c478bd9Sstevel@tonic-gate {
53457c478bd9Sstevel@tonic-gate sa_mcmember_record_t mcg_req;
53467c478bd9Sstevel@tonic-gate sa_mcmember_record_t *mcg_resp;
53477c478bd9Sstevel@tonic-gate ibt_mcg_info_t *mcg_infop;
53487c478bd9Sstevel@tonic-gate ibmf_saa_access_args_t access_args;
53497c478bd9Sstevel@tonic-gate ibmf_saa_handle_t saa_handle;
53507c478bd9Sstevel@tonic-gate uint64_t component_mask = 0;
53517c478bd9Sstevel@tonic-gate ibt_status_t retval;
53527c478bd9Sstevel@tonic-gate ibtl_cm_hca_port_t hport;
53537c478bd9Sstevel@tonic-gate uint_t num_records;
53547c478bd9Sstevel@tonic-gate size_t length;
53557c478bd9Sstevel@tonic-gate void *results_p;
53567c478bd9Sstevel@tonic-gate ib_gid_t port_gid;
53577c478bd9Sstevel@tonic-gate ibcm_hca_info_t *hcap;
53587c478bd9Sstevel@tonic-gate
53597c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_query_mcg(%p, %d)", mcg_attr, mcgs_max_num);
53607c478bd9Sstevel@tonic-gate
53617c478bd9Sstevel@tonic-gate if ((entries_p == NULL) || (mcgs_info_p == NULL)) {
53627c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_query_mcg: "
53637c478bd9Sstevel@tonic-gate "entries_p or mcgs_info_p is NULL");
53647c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
53657c478bd9Sstevel@tonic-gate }
53667c478bd9Sstevel@tonic-gate
53677c478bd9Sstevel@tonic-gate if ((rgid.gid_prefix == 0) || (rgid.gid_guid == 0)) {
53687c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_query_mcg: RequestGID is required");
53697c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
53707c478bd9Sstevel@tonic-gate }
53717c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_query_mcg: Request GID <%llX:%llX>",
53727c478bd9Sstevel@tonic-gate rgid.gid_prefix, rgid.gid_guid);
53737c478bd9Sstevel@tonic-gate
53747c478bd9Sstevel@tonic-gate bzero(&mcg_req, sizeof (sa_mcmember_record_t));
53757c478bd9Sstevel@tonic-gate port_gid.gid_prefix = port_gid.gid_guid = 0;
53767c478bd9Sstevel@tonic-gate
53777c478bd9Sstevel@tonic-gate if (mcg_attr != NULL) {
53787c478bd9Sstevel@tonic-gate port_gid = mcg_attr->mc_pgid;
53797c478bd9Sstevel@tonic-gate
53807c478bd9Sstevel@tonic-gate if ((port_gid.gid_prefix != 0) && (port_gid.gid_guid != 0)) {
53817c478bd9Sstevel@tonic-gate mcg_req.PortGID = mcg_attr->mc_pgid;
53827c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_PORTGID;
53837c478bd9Sstevel@tonic-gate
53847c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_query_mcg: PGID %llX:%llX",
53857c478bd9Sstevel@tonic-gate port_gid.gid_prefix, port_gid.gid_guid);
53867c478bd9Sstevel@tonic-gate }
53877c478bd9Sstevel@tonic-gate
53887c478bd9Sstevel@tonic-gate /* Is Q_Key specified. */
53897c478bd9Sstevel@tonic-gate if (mcg_attr->mc_qkey != 0) {
53907c478bd9Sstevel@tonic-gate mcg_req.Q_Key = mcg_attr->mc_qkey;
53917c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_QKEY;
53927c478bd9Sstevel@tonic-gate }
53937c478bd9Sstevel@tonic-gate
53947c478bd9Sstevel@tonic-gate /* Is P_Key specified. */
53957c478bd9Sstevel@tonic-gate if (mcg_attr->mc_pkey != 0) {
53967c478bd9Sstevel@tonic-gate mcg_req.P_Key = mcg_attr->mc_pkey;
53977c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_PKEY;
53987c478bd9Sstevel@tonic-gate }
53997c478bd9Sstevel@tonic-gate
54007c478bd9Sstevel@tonic-gate /* Is MGID specified. */
54017c478bd9Sstevel@tonic-gate if ((mcg_attr->mc_mgid.gid_prefix >> 56ULL & 0xFF) == 0xFF) {
54027c478bd9Sstevel@tonic-gate mcg_req.MGID = mcg_attr->mc_mgid;
54037c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_MGID;
54047c478bd9Sstevel@tonic-gate }
54057c478bd9Sstevel@tonic-gate
54067c478bd9Sstevel@tonic-gate /* Is MTU specified. */
54077c478bd9Sstevel@tonic-gate if (mcg_attr->mc_mtu_req.r_mtu) {
54087c478bd9Sstevel@tonic-gate mcg_req.MTU = mcg_attr->mc_mtu_req.r_mtu;
54097c478bd9Sstevel@tonic-gate mcg_req.MTUSelector = mcg_attr->mc_mtu_req.r_selector;
54107c478bd9Sstevel@tonic-gate
54117c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_MTUSELECTOR |
54127c478bd9Sstevel@tonic-gate SA_MC_COMPMASK_MTU;
54137c478bd9Sstevel@tonic-gate }
54147c478bd9Sstevel@tonic-gate
54157c478bd9Sstevel@tonic-gate if (mcg_attr->mc_tclass) {
54167c478bd9Sstevel@tonic-gate mcg_req.TClass = mcg_attr->mc_tclass;
54177c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_TCLASS;
54187c478bd9Sstevel@tonic-gate }
54197c478bd9Sstevel@tonic-gate
54207c478bd9Sstevel@tonic-gate /* Is RATE specified. */
54217c478bd9Sstevel@tonic-gate if (mcg_attr->mc_rate_req.r_srate) {
54227c478bd9Sstevel@tonic-gate mcg_req.Rate = mcg_attr->mc_rate_req.r_srate;
54237c478bd9Sstevel@tonic-gate mcg_req.RateSelector = mcg_attr->mc_rate_req.r_selector;
54247c478bd9Sstevel@tonic-gate
54257c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_RATESELECTOR |
54267c478bd9Sstevel@tonic-gate SA_MC_COMPMASK_RATE;
54277c478bd9Sstevel@tonic-gate }
54287c478bd9Sstevel@tonic-gate
54297c478bd9Sstevel@tonic-gate /* Is Packet Life Time specified. */
54307c478bd9Sstevel@tonic-gate if (mcg_attr->mc_pkt_lt_req.p_pkt_lt) {
54317c478bd9Sstevel@tonic-gate mcg_req.Rate = mcg_attr->mc_pkt_lt_req.p_pkt_lt;
54327c478bd9Sstevel@tonic-gate mcg_req.RateSelector =
54337c478bd9Sstevel@tonic-gate mcg_attr->mc_pkt_lt_req.p_selector;
54347c478bd9Sstevel@tonic-gate
54357c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_PKTLTSELECTOR |
54367c478bd9Sstevel@tonic-gate SA_MC_COMPMASK_PKTLT;
54377c478bd9Sstevel@tonic-gate }
54387c478bd9Sstevel@tonic-gate
54397c478bd9Sstevel@tonic-gate if (mcg_attr->mc_hop) {
54407c478bd9Sstevel@tonic-gate mcg_req.HopLimit = mcg_attr->mc_hop;
54417c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_HOPLIMIT;
54427c478bd9Sstevel@tonic-gate }
54437c478bd9Sstevel@tonic-gate
54447c478bd9Sstevel@tonic-gate if (mcg_attr->mc_flow) {
54457c478bd9Sstevel@tonic-gate mcg_req.FlowLabel = mcg_attr->mc_flow;
54467c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_FLOWLABEL;
54477c478bd9Sstevel@tonic-gate }
54487c478bd9Sstevel@tonic-gate
54497c478bd9Sstevel@tonic-gate if (mcg_attr->mc_sl) {
54507c478bd9Sstevel@tonic-gate mcg_req.SL = mcg_attr->mc_sl;
54517c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_SL;
54527c478bd9Sstevel@tonic-gate }
54537c478bd9Sstevel@tonic-gate
54547c478bd9Sstevel@tonic-gate if (mcg_attr->mc_scope) {
54557c478bd9Sstevel@tonic-gate mcg_req.Scope = mcg_attr->mc_scope;
54567c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_SCOPE;
54577c478bd9Sstevel@tonic-gate }
54587c478bd9Sstevel@tonic-gate
54597c478bd9Sstevel@tonic-gate if (mcg_attr->mc_join_state) {
54607c478bd9Sstevel@tonic-gate mcg_req.JoinState = mcg_attr->mc_join_state;
54617c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_JOINSTATE;
54627c478bd9Sstevel@tonic-gate }
54637c478bd9Sstevel@tonic-gate
54647c478bd9Sstevel@tonic-gate if (mcg_attr->mc_mlid) {
54657c478bd9Sstevel@tonic-gate mcg_req.MLID = mcg_attr->mc_mlid;
54667c478bd9Sstevel@tonic-gate component_mask |= SA_MC_COMPMASK_MLID;
54677c478bd9Sstevel@tonic-gate }
54687c478bd9Sstevel@tonic-gate }
54697c478bd9Sstevel@tonic-gate
54707c478bd9Sstevel@tonic-gate retval = ibtl_cm_get_hca_port(rgid, 0, &hport);
54717c478bd9Sstevel@tonic-gate if (retval != IBT_SUCCESS) {
54727c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_query_mcg: Failed to get port info "
54737c478bd9Sstevel@tonic-gate "from specified RGID : status = %d", retval);
54747c478bd9Sstevel@tonic-gate return (retval);
54757c478bd9Sstevel@tonic-gate }
54767c478bd9Sstevel@tonic-gate
54777c478bd9Sstevel@tonic-gate /* Get SA Access Handle. */
54787c478bd9Sstevel@tonic-gate hcap = ibcm_find_hca_entry(hport.hp_hca_guid);
54797c478bd9Sstevel@tonic-gate if (hcap == NULL) {
54807c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_query_mcg: NO HCA found");
54817c478bd9Sstevel@tonic-gate return (IBT_HCA_BUSY_DETACHING);
54827c478bd9Sstevel@tonic-gate }
54837c478bd9Sstevel@tonic-gate
54847c478bd9Sstevel@tonic-gate saa_handle = ibcm_get_saa_handle(hcap, hport.hp_port);
54857c478bd9Sstevel@tonic-gate if (saa_handle == NULL) {
54867c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_query_mcg: saa_handle is NULL");
54877c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
54887c478bd9Sstevel@tonic-gate return (IBT_HCA_PORT_NOT_ACTIVE);
54897c478bd9Sstevel@tonic-gate }
54907c478bd9Sstevel@tonic-gate
54917c478bd9Sstevel@tonic-gate /* Contact SA Access */
54927c478bd9Sstevel@tonic-gate access_args.sq_attr_id = SA_MCMEMBERRECORD_ATTRID;
54937c478bd9Sstevel@tonic-gate access_args.sq_access_type = IBMF_SAA_RETRIEVE;
54947c478bd9Sstevel@tonic-gate access_args.sq_component_mask = component_mask;
54957c478bd9Sstevel@tonic-gate access_args.sq_template = &mcg_req;
54967c478bd9Sstevel@tonic-gate access_args.sq_template_length = sizeof (sa_mcmember_record_t);
54977c478bd9Sstevel@tonic-gate access_args.sq_callback = NULL;
54987c478bd9Sstevel@tonic-gate access_args.sq_callback_arg = NULL;
54997c478bd9Sstevel@tonic-gate
55007c478bd9Sstevel@tonic-gate retval = ibcm_contact_sa_access(saa_handle, &access_args, &length,
55017c478bd9Sstevel@tonic-gate &results_p);
55027c478bd9Sstevel@tonic-gate if (retval != IBT_SUCCESS) {
55037c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_query_mcg: SA access Failed");
55047c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
55057c478bd9Sstevel@tonic-gate return (retval);
55067c478bd9Sstevel@tonic-gate }
55077c478bd9Sstevel@tonic-gate
55087c478bd9Sstevel@tonic-gate num_records = length/sizeof (sa_mcmember_record_t);
55097c478bd9Sstevel@tonic-gate
55107c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_query_mcg: Found %d MCMember Records",
55117c478bd9Sstevel@tonic-gate num_records);
55127c478bd9Sstevel@tonic-gate
55137c478bd9Sstevel@tonic-gate /* Validate the returned number of records. */
55147c478bd9Sstevel@tonic-gate if ((results_p != NULL) && (num_records > 0)) {
55157c478bd9Sstevel@tonic-gate uint_t i;
55167c478bd9Sstevel@tonic-gate
55177c478bd9Sstevel@tonic-gate /*
55187c478bd9Sstevel@tonic-gate * If mcgs_max_num is zero, then return all records else
55197c478bd9Sstevel@tonic-gate * return only requested number of records
55207c478bd9Sstevel@tonic-gate */
55217c478bd9Sstevel@tonic-gate if ((mcgs_max_num != 0) && (num_records > mcgs_max_num)) {
55227c478bd9Sstevel@tonic-gate /* we are interested in only mcgs_max_num records */
55237c478bd9Sstevel@tonic-gate num_records = mcgs_max_num;
55247c478bd9Sstevel@tonic-gate }
55257c478bd9Sstevel@tonic-gate
55267c478bd9Sstevel@tonic-gate /*
55277c478bd9Sstevel@tonic-gate * The SGID returned in "mcg_info_p" buffer should be PortGID,
55287c478bd9Sstevel@tonic-gate * (mcg_attr->mc_pgid), if 'mcg_attr->mc_pgid' was specified,
55297c478bd9Sstevel@tonic-gate * else RequestGID (rgid) should be returned.
55307c478bd9Sstevel@tonic-gate */
55317c478bd9Sstevel@tonic-gate if ((port_gid.gid_prefix != 0) && (port_gid.gid_guid != 0)) {
55327c478bd9Sstevel@tonic-gate
55337c478bd9Sstevel@tonic-gate /* Get sgid_ix and port number of 'port_gid' */
55347c478bd9Sstevel@tonic-gate retval = ibtl_cm_get_hca_port(port_gid, 0, &hport);
55357c478bd9Sstevel@tonic-gate if (retval != IBT_SUCCESS) {
55367c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_query_mcg: "
55377c478bd9Sstevel@tonic-gate "Failed to Get Portinfo for PortGID :"
55387c478bd9Sstevel@tonic-gate "status = %d", retval);
55397c478bd9Sstevel@tonic-gate return (retval);
55407c478bd9Sstevel@tonic-gate }
55417c478bd9Sstevel@tonic-gate } else {
55427c478bd9Sstevel@tonic-gate /*
55437c478bd9Sstevel@tonic-gate * The sgid_ix and port number related to RequestGID
55447c478bd9Sstevel@tonic-gate * are already obtained at the beginning.
55457c478bd9Sstevel@tonic-gate */
55467c478bd9Sstevel@tonic-gate port_gid = rgid;
55477c478bd9Sstevel@tonic-gate }
55487c478bd9Sstevel@tonic-gate
55497c478bd9Sstevel@tonic-gate /*
55507c478bd9Sstevel@tonic-gate * Allocate memory for return buffer, to be freed in
55517c478bd9Sstevel@tonic-gate * ibt_free_mcg_info().
55527c478bd9Sstevel@tonic-gate */
55537c478bd9Sstevel@tonic-gate mcg_infop = kmem_alloc((num_records * sizeof (ibt_mcg_info_t)),
55547c478bd9Sstevel@tonic-gate KM_SLEEP);
55557c478bd9Sstevel@tonic-gate
55567c478bd9Sstevel@tonic-gate *mcgs_info_p = mcg_infop;
55577c478bd9Sstevel@tonic-gate *entries_p = num_records;
55587c478bd9Sstevel@tonic-gate
55597c478bd9Sstevel@tonic-gate /* Update the return values. */
55607c478bd9Sstevel@tonic-gate for (i = 0; i < num_records; i++) {
55617c478bd9Sstevel@tonic-gate
55627c478bd9Sstevel@tonic-gate mcg_resp = (sa_mcmember_record_t *)((uchar_t *)
55637c478bd9Sstevel@tonic-gate results_p + i * sizeof (sa_mcmember_record_t));
55647c478bd9Sstevel@tonic-gate
55657c478bd9Sstevel@tonic-gate mcg_infop[i].mc_adds_vect.av_dgid = mcg_resp->MGID;
55667c478bd9Sstevel@tonic-gate mcg_infop[i].mc_adds_vect.av_sgid = port_gid;
55677c478bd9Sstevel@tonic-gate mcg_infop[i].mc_adds_vect.av_srate = mcg_resp->Rate;
55687c478bd9Sstevel@tonic-gate mcg_infop[i].mc_adds_vect.av_srvl = mcg_resp->SL;
55697c478bd9Sstevel@tonic-gate mcg_infop[i].mc_adds_vect.av_flow = mcg_resp->FlowLabel;
55707c478bd9Sstevel@tonic-gate mcg_infop[i].mc_adds_vect.av_tclass = mcg_resp->TClass;
55717c478bd9Sstevel@tonic-gate mcg_infop[i].mc_adds_vect.av_hop = mcg_resp->HopLimit;
55727c478bd9Sstevel@tonic-gate mcg_infop[i].mc_adds_vect.av_port_num = hport.hp_port;
55737c478bd9Sstevel@tonic-gate mcg_infop[i].mc_adds_vect.av_send_grh = B_TRUE;
55747c478bd9Sstevel@tonic-gate mcg_infop[i].mc_adds_vect.av_dlid = mcg_resp->MLID;
55757c478bd9Sstevel@tonic-gate mcg_infop[i].mc_adds_vect.av_sgid_ix = hport.hp_sgid_ix;
55767c478bd9Sstevel@tonic-gate mcg_infop[i].mc_adds_vect.av_src_path = 0;
55777c478bd9Sstevel@tonic-gate mcg_infop[i].mc_mtu = mcg_resp->MTU;
55787c478bd9Sstevel@tonic-gate mcg_infop[i].mc_qkey = mcg_resp->Q_Key;
55797c478bd9Sstevel@tonic-gate mcg_infop[i].mc_scope = mcg_resp->Scope;
55807c478bd9Sstevel@tonic-gate mcg_infop[i].mc_pkt_lt = mcg_resp->PacketLifeTime;
55817c478bd9Sstevel@tonic-gate
55827c478bd9Sstevel@tonic-gate if (ibt_pkey2index_byguid(hport.hp_hca_guid,
55837c478bd9Sstevel@tonic-gate hport.hp_port, mcg_resp->P_Key,
55847c478bd9Sstevel@tonic-gate &mcg_infop[i].mc_pkey_ix) != IBT_SUCCESS) {
55857c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_query_mcg: "
55867c478bd9Sstevel@tonic-gate "Pkey2Index Conversion failed");
55877c478bd9Sstevel@tonic-gate mcg_infop[i].mc_pkey_ix = 0;
55887c478bd9Sstevel@tonic-gate }
55897c478bd9Sstevel@tonic-gate }
55907c478bd9Sstevel@tonic-gate
55917c478bd9Sstevel@tonic-gate /*
55927c478bd9Sstevel@tonic-gate * Deallocate the memory allocated by SA for results_p.
55937c478bd9Sstevel@tonic-gate */
55947c478bd9Sstevel@tonic-gate kmem_free(results_p, length);
55957c478bd9Sstevel@tonic-gate retval = IBT_SUCCESS;
55967c478bd9Sstevel@tonic-gate
55977c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_query_mcg: returning %d MCGRecords",
55987c478bd9Sstevel@tonic-gate num_records);
55997c478bd9Sstevel@tonic-gate
56007c478bd9Sstevel@tonic-gate } else {
56017c478bd9Sstevel@tonic-gate retval = IBT_MCG_RECORDS_NOT_FOUND;
56027c478bd9Sstevel@tonic-gate *entries_p = 0;
56037c478bd9Sstevel@tonic-gate
56047c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_query_mcg: MCG RECORDS NOT FOUND");
56057c478bd9Sstevel@tonic-gate }
56067c478bd9Sstevel@tonic-gate
56077c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
56087c478bd9Sstevel@tonic-gate
56097c478bd9Sstevel@tonic-gate return (retval);
56107c478bd9Sstevel@tonic-gate }
56117c478bd9Sstevel@tonic-gate
56127c478bd9Sstevel@tonic-gate
56137c478bd9Sstevel@tonic-gate /*
56147c478bd9Sstevel@tonic-gate * ibt_free_mcg_info()
56157c478bd9Sstevel@tonic-gate * Free the memory allocated by successful ibt_query_mcg()
56167c478bd9Sstevel@tonic-gate *
56177c478bd9Sstevel@tonic-gate * mcgs_info Pointer returned by ibt_query_mcg().
56187c478bd9Sstevel@tonic-gate *
56197c478bd9Sstevel@tonic-gate * entries The number of ibt_mcg_info_t entries to free.
56207c478bd9Sstevel@tonic-gate */
56217c478bd9Sstevel@tonic-gate void
ibt_free_mcg_info(ibt_mcg_info_t * mcgs_info,uint_t entries)56227c478bd9Sstevel@tonic-gate ibt_free_mcg_info(ibt_mcg_info_t *mcgs_info, uint_t entries)
56237c478bd9Sstevel@tonic-gate {
56247c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_free_mcg_info: "
56257c478bd9Sstevel@tonic-gate "Free <%d> entries from 0x%p", entries, mcgs_info);
56267c478bd9Sstevel@tonic-gate
56277c478bd9Sstevel@tonic-gate if ((mcgs_info != NULL) && (entries > 0))
56287c478bd9Sstevel@tonic-gate kmem_free(mcgs_info, entries * sizeof (ibt_mcg_info_t));
56297c478bd9Sstevel@tonic-gate else
56307c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_free_mcg_info: "
56317c478bd9Sstevel@tonic-gate "ERROR: NULL buf pointer or length specified.");
56327c478bd9Sstevel@tonic-gate }
56337c478bd9Sstevel@tonic-gate
56347c478bd9Sstevel@tonic-gate
56357c478bd9Sstevel@tonic-gate /*
56367c478bd9Sstevel@tonic-gate * Function:
56377c478bd9Sstevel@tonic-gate * ibt_gid_to_node_info()
56387c478bd9Sstevel@tonic-gate * Input:
56397c478bd9Sstevel@tonic-gate * gid Identifies the IB Node and port for which to obtain
56407c478bd9Sstevel@tonic-gate * Node information.
56417c478bd9Sstevel@tonic-gate * Output:
56427c478bd9Sstevel@tonic-gate * node_info_p A pointer to an ibt_node_info_t structure (allocated
56437c478bd9Sstevel@tonic-gate * by the caller) in which to return the node information.
56447c478bd9Sstevel@tonic-gate * Returns:
56457c478bd9Sstevel@tonic-gate * IBT_SUCCESS
56467c478bd9Sstevel@tonic-gate * IBT_INVALID_PARAM
56477c478bd9Sstevel@tonic-gate * IBT_NODE_RECORDS_NOT_FOUND
56487c478bd9Sstevel@tonic-gate * IBT_NO_HCAS_AVAILABLE
56497c478bd9Sstevel@tonic-gate * Description:
56507c478bd9Sstevel@tonic-gate * Retrieve Node Information for the specified GID.
56517c478bd9Sstevel@tonic-gate */
56527c478bd9Sstevel@tonic-gate ibt_status_t
ibt_gid_to_node_info(ib_gid_t gid,ibt_node_info_t * node_info_p)56537c478bd9Sstevel@tonic-gate ibt_gid_to_node_info(ib_gid_t gid, ibt_node_info_t *node_info_p)
56547c478bd9Sstevel@tonic-gate {
56557c478bd9Sstevel@tonic-gate sa_node_record_t nr_req, *nr_resp;
56567c478bd9Sstevel@tonic-gate ibmf_saa_handle_t saa_handle;
56577c478bd9Sstevel@tonic-gate ibt_status_t retval;
56587c478bd9Sstevel@tonic-gate ibcm_hca_info_t *hcap;
56597c478bd9Sstevel@tonic-gate ibtl_cm_hca_port_t hport;
56607c478bd9Sstevel@tonic-gate int i, j;
56617c478bd9Sstevel@tonic-gate uint_t num_rec;
56627c478bd9Sstevel@tonic-gate ib_guid_t *guid_array = NULL;
56637c478bd9Sstevel@tonic-gate sa_path_record_t *path;
56647c478bd9Sstevel@tonic-gate size_t len;
56657c478bd9Sstevel@tonic-gate uint8_t npaths;
56667c478bd9Sstevel@tonic-gate uint32_t num_hcas = 0;
56677c478bd9Sstevel@tonic-gate ib_lid_t node_lid;
56687c478bd9Sstevel@tonic-gate boolean_t local_node = B_FALSE;
56697c478bd9Sstevel@tonic-gate void *res_p;
56707c478bd9Sstevel@tonic-gate uint8_t num_ports = 0;
56717c478bd9Sstevel@tonic-gate
56727c478bd9Sstevel@tonic-gate
56737c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_gid_to_node_info(%llX:%llX, %p)",
56747c478bd9Sstevel@tonic-gate gid.gid_prefix, gid.gid_guid, node_info_p);
56757c478bd9Sstevel@tonic-gate
56767c478bd9Sstevel@tonic-gate if ((gid.gid_prefix == 0) || (gid.gid_guid == 0)) {
56777c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_gid_to_node_info: GID is required");
56787c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
56797c478bd9Sstevel@tonic-gate }
56807c478bd9Sstevel@tonic-gate
56817c478bd9Sstevel@tonic-gate if (node_info_p == NULL) {
56827c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_gid_to_node_info: "
56837c478bd9Sstevel@tonic-gate "Return Buf (node_info_p) is NULL.");
56847c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
56857c478bd9Sstevel@tonic-gate }
56867c478bd9Sstevel@tonic-gate
56877c478bd9Sstevel@tonic-gate /*
56887c478bd9Sstevel@tonic-gate * If 'gid' is on local node, then get node lid (i.e. base lid of the
56897c478bd9Sstevel@tonic-gate * associated port) info via ibtl_cm_get_hca_port() call.
56907c478bd9Sstevel@tonic-gate */
56917c478bd9Sstevel@tonic-gate bzero(&hport, sizeof (ibtl_cm_hca_port_t));
56927c478bd9Sstevel@tonic-gate if (ibtl_cm_get_hca_port(gid, 0, &hport) == IBT_SUCCESS) {
56937c478bd9Sstevel@tonic-gate
56947c478bd9Sstevel@tonic-gate hcap = ibcm_find_hca_entry(hport.hp_hca_guid);
56957c478bd9Sstevel@tonic-gate if (hcap == NULL) {
56967c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_gid_to_node_info: "
56977c478bd9Sstevel@tonic-gate "HCA(%llX) info not found", hport.hp_hca_guid);
56987c478bd9Sstevel@tonic-gate return (IBT_NO_HCAS_AVAILABLE);
56997c478bd9Sstevel@tonic-gate }
57007c478bd9Sstevel@tonic-gate num_ports = 1;
57017c478bd9Sstevel@tonic-gate num_hcas = 1;
57027c478bd9Sstevel@tonic-gate node_lid = hport.hp_base_lid;
57037c478bd9Sstevel@tonic-gate local_node = B_TRUE;
57047c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_gid_to_node_info: Local Node: "
57057c478bd9Sstevel@tonic-gate "LID = 0x%X", node_lid);
57067c478bd9Sstevel@tonic-gate } else {
57077c478bd9Sstevel@tonic-gate /* Get the number of HCAs and their GUIDs */
57087c478bd9Sstevel@tonic-gate num_hcas = ibt_get_hca_list(&guid_array);
57097c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_gid_to_node_info: ibt_get_hca_list "
57107c478bd9Sstevel@tonic-gate "returned %d hcas", num_hcas);
57117c478bd9Sstevel@tonic-gate
57127c478bd9Sstevel@tonic-gate if (num_hcas == 0) {
57137c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_gid_to_node_info: "
57147c478bd9Sstevel@tonic-gate "NO HCA's Found on this system");
57157c478bd9Sstevel@tonic-gate return (IBT_NO_HCAS_AVAILABLE);
57167c478bd9Sstevel@tonic-gate }
57177c478bd9Sstevel@tonic-gate }
57187c478bd9Sstevel@tonic-gate
57197c478bd9Sstevel@tonic-gate for (i = 0; i < num_hcas; i++) {
57207c478bd9Sstevel@tonic-gate if (local_node == B_FALSE) {
57217c478bd9Sstevel@tonic-gate hcap = ibcm_find_hca_entry(guid_array[i]);
57227c478bd9Sstevel@tonic-gate if (hcap == NULL) {
57237c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_gid_to_node_info: "
57247c478bd9Sstevel@tonic-gate "HCA(%llX) info not found", guid_array[i]);
57257c478bd9Sstevel@tonic-gate retval = IBT_NO_HCAS_AVAILABLE;
57267c478bd9Sstevel@tonic-gate continue;
57277c478bd9Sstevel@tonic-gate }
57287c478bd9Sstevel@tonic-gate num_ports = hcap->hca_num_ports;
57297c478bd9Sstevel@tonic-gate }
57307c478bd9Sstevel@tonic-gate
57317c478bd9Sstevel@tonic-gate for (j = 0; j < num_ports; j++) {
57327c478bd9Sstevel@tonic-gate uint8_t port = 0;
57337c478bd9Sstevel@tonic-gate
57347c478bd9Sstevel@tonic-gate if (local_node == B_TRUE)
57357c478bd9Sstevel@tonic-gate port = hport.hp_port;
57367c478bd9Sstevel@tonic-gate else
57377c478bd9Sstevel@tonic-gate port = j + 1;
57387c478bd9Sstevel@tonic-gate
57397c478bd9Sstevel@tonic-gate /* Get SA Access Handle. */
57407c478bd9Sstevel@tonic-gate saa_handle = ibcm_get_saa_handle(hcap, port);
57417c478bd9Sstevel@tonic-gate if (saa_handle == NULL) {
57427c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_gid_to_node_info: "
57437c478bd9Sstevel@tonic-gate "Port %d of HCA (%llX) is NOT ACTIVE",
57447c478bd9Sstevel@tonic-gate port, hport.hp_hca_guid);
57457c478bd9Sstevel@tonic-gate retval = IBT_NODE_RECORDS_NOT_FOUND;
57467c478bd9Sstevel@tonic-gate continue;
57477c478bd9Sstevel@tonic-gate }
57487c478bd9Sstevel@tonic-gate
57497c478bd9Sstevel@tonic-gate if (local_node == B_FALSE) {
57507c478bd9Sstevel@tonic-gate ib_gid_t sgid;
57517c478bd9Sstevel@tonic-gate int sa_ret;
57527c478bd9Sstevel@tonic-gate
57537c478bd9Sstevel@tonic-gate /*
57547c478bd9Sstevel@tonic-gate * Check whether 'gid' and this port has same
57557c478bd9Sstevel@tonic-gate * subnet prefix. If not, then there is no use
57567c478bd9Sstevel@tonic-gate * in searching from this port.
57577c478bd9Sstevel@tonic-gate */
57587c478bd9Sstevel@tonic-gate sgid = hcap->hca_port_info[j].port_sgid0;
57597c478bd9Sstevel@tonic-gate if (gid.gid_prefix != sgid.gid_prefix) {
57607c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog,
57617c478bd9Sstevel@tonic-gate "ibt_gid_to_node_info:Sn_Prefix of "
57627c478bd9Sstevel@tonic-gate "GID(%llX) and Port's(%llX) differ",
57637c478bd9Sstevel@tonic-gate gid.gid_prefix, sgid.gid_prefix);
57647c478bd9Sstevel@tonic-gate retval = IBT_NODE_RECORDS_NOT_FOUND;
57657c478bd9Sstevel@tonic-gate continue;
57667c478bd9Sstevel@tonic-gate }
57677c478bd9Sstevel@tonic-gate
57687c478bd9Sstevel@tonic-gate /*
57697c478bd9Sstevel@tonic-gate * First Get Path Records for the specified DGID
57707c478bd9Sstevel@tonic-gate * from this port (SGID). From Path Records,
57717c478bd9Sstevel@tonic-gate * note down DLID, then use this DLID as Input
57727c478bd9Sstevel@tonic-gate * attribute to get NodeRecords from SA Access.
57737c478bd9Sstevel@tonic-gate */
57747c478bd9Sstevel@tonic-gate npaths = 1;
57757c478bd9Sstevel@tonic-gate path = NULL;
57767c478bd9Sstevel@tonic-gate
57777c478bd9Sstevel@tonic-gate sa_ret = ibmf_saa_gid_to_pathrecords(saa_handle,
57787c478bd9Sstevel@tonic-gate sgid, gid, 0, 0, B_TRUE, &npaths, 0, &len,
57797c478bd9Sstevel@tonic-gate &path);
57807c478bd9Sstevel@tonic-gate if (sa_ret != IBMF_SUCCESS) {
57817c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog,
57827c478bd9Sstevel@tonic-gate "ibt_gid_to_node_info: "
57837c478bd9Sstevel@tonic-gate "ibmf_saa_gid_to_pathrecords() "
57847c478bd9Sstevel@tonic-gate "returned error: %d ", sa_ret);
57857c478bd9Sstevel@tonic-gate retval =
57867c478bd9Sstevel@tonic-gate ibcm_ibmf_analyze_error(sa_ret);
57877c478bd9Sstevel@tonic-gate continue;
57887c478bd9Sstevel@tonic-gate } else if ((npaths == 0) || (path == NULL)) {
57897c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog,
57907c478bd9Sstevel@tonic-gate "ibt_gid_to_node_info: failed (%d) "
57917c478bd9Sstevel@tonic-gate "to get path records for the DGID "
57927c478bd9Sstevel@tonic-gate "0x%llX from SGID 0x%llX", sa_ret,
57937c478bd9Sstevel@tonic-gate gid.gid_guid, sgid.gid_guid);
57947c478bd9Sstevel@tonic-gate retval = IBT_NODE_RECORDS_NOT_FOUND;
57957c478bd9Sstevel@tonic-gate continue;
57967c478bd9Sstevel@tonic-gate }
57977c478bd9Sstevel@tonic-gate node_lid = path->DLID; /* LID */
57987c478bd9Sstevel@tonic-gate
57997c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_gid_to_node_info: "
58007c478bd9Sstevel@tonic-gate "Remote Node: LID = 0x%X", node_lid);
58017c478bd9Sstevel@tonic-gate
58027c478bd9Sstevel@tonic-gate /* Free SA_Access memory for path record. */
58037c478bd9Sstevel@tonic-gate kmem_free(path, len);
58047c478bd9Sstevel@tonic-gate }
58057c478bd9Sstevel@tonic-gate
58067c478bd9Sstevel@tonic-gate /* Retrieve Node Records from SA Access. */
58077c478bd9Sstevel@tonic-gate bzero(&nr_req, sizeof (sa_node_record_t));
58087c478bd9Sstevel@tonic-gate
58097c478bd9Sstevel@tonic-gate nr_req.LID = node_lid; /* LID */
58107c478bd9Sstevel@tonic-gate
58117c478bd9Sstevel@tonic-gate retval = ibcm_get_node_rec(saa_handle, &nr_req,
58127c478bd9Sstevel@tonic-gate SA_NODEINFO_COMPMASK_NODELID, &res_p, &len);
58137c478bd9Sstevel@tonic-gate if (retval == IBT_NODE_RECORDS_NOT_FOUND) {
58147c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_gid_to_node_info: "
58157c478bd9Sstevel@tonic-gate "failed (%d) to get Node records", retval);
58167c478bd9Sstevel@tonic-gate continue;
58177c478bd9Sstevel@tonic-gate } else if (retval != IBT_SUCCESS) {
58187c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_gid_to_node_info: "
58197c478bd9Sstevel@tonic-gate "failed (%d) to get Node records", retval);
58207c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
58217c478bd9Sstevel@tonic-gate goto gid_to_ni_exit;
58227c478bd9Sstevel@tonic-gate }
58237c478bd9Sstevel@tonic-gate
58247c478bd9Sstevel@tonic-gate num_rec = len/sizeof (sa_node_record_t);
58257c478bd9Sstevel@tonic-gate nr_resp = (sa_node_record_t *)(uchar_t *)res_p;
58267c478bd9Sstevel@tonic-gate
58277c478bd9Sstevel@tonic-gate /* Validate the returned number of records. */
58287c478bd9Sstevel@tonic-gate if ((nr_resp != NULL) && (num_rec > 0)) {
58297c478bd9Sstevel@tonic-gate
58307c478bd9Sstevel@tonic-gate IBCM_DUMP_NODE_REC(nr_resp);
58317c478bd9Sstevel@tonic-gate
58327c478bd9Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(
58337c478bd9Sstevel@tonic-gate *node_info_p))
58347c478bd9Sstevel@tonic-gate
58357c478bd9Sstevel@tonic-gate node_info_p->n_sys_img_guid =
58367c478bd9Sstevel@tonic-gate nr_resp->NodeInfo.SystemImageGUID;
58377c478bd9Sstevel@tonic-gate node_info_p->n_node_guid =
58387c478bd9Sstevel@tonic-gate nr_resp->NodeInfo.NodeGUID;
58397c478bd9Sstevel@tonic-gate node_info_p->n_port_guid =
58407c478bd9Sstevel@tonic-gate nr_resp->NodeInfo.PortGUID;
58417c478bd9Sstevel@tonic-gate node_info_p->n_dev_id =
58427c478bd9Sstevel@tonic-gate nr_resp->NodeInfo.DeviceID;
58437c478bd9Sstevel@tonic-gate node_info_p->n_revision =
58447c478bd9Sstevel@tonic-gate nr_resp->NodeInfo.Revision;
58457c478bd9Sstevel@tonic-gate node_info_p->n_vendor_id =
58467c478bd9Sstevel@tonic-gate nr_resp->NodeInfo.VendorID;
58477c478bd9Sstevel@tonic-gate node_info_p->n_num_ports =
58487c478bd9Sstevel@tonic-gate nr_resp->NodeInfo.NumPorts;
58497c478bd9Sstevel@tonic-gate node_info_p->n_port_num =
58507c478bd9Sstevel@tonic-gate nr_resp->NodeInfo.LocalPortNum;
58517c478bd9Sstevel@tonic-gate node_info_p->n_node_type =
58527c478bd9Sstevel@tonic-gate nr_resp->NodeInfo.NodeType;
58537c478bd9Sstevel@tonic-gate (void) strncpy(node_info_p->n_description,
58547c478bd9Sstevel@tonic-gate (char *)&nr_resp->NodeDescription, 64);
58557c478bd9Sstevel@tonic-gate
58567c478bd9Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(
58577c478bd9Sstevel@tonic-gate *node_info_p))
58587c478bd9Sstevel@tonic-gate
58597c478bd9Sstevel@tonic-gate /*
58607c478bd9Sstevel@tonic-gate * Deallocate the memory allocated by SA for
58617c478bd9Sstevel@tonic-gate * 'nr_resp'.
58627c478bd9Sstevel@tonic-gate */
58637c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
58647c478bd9Sstevel@tonic-gate kmem_free(nr_resp, len);
58657c478bd9Sstevel@tonic-gate retval = IBT_SUCCESS;
58667c478bd9Sstevel@tonic-gate
58677c478bd9Sstevel@tonic-gate goto gid_to_ni_exit;
58687c478bd9Sstevel@tonic-gate } else {
58697c478bd9Sstevel@tonic-gate retval = IBT_NODE_RECORDS_NOT_FOUND;
58707c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_gid_to_node_info: "
58717c478bd9Sstevel@tonic-gate "Node Records NOT found - PortGUID %016llX",
58727c478bd9Sstevel@tonic-gate gid.gid_guid);
58737c478bd9Sstevel@tonic-gate }
58747c478bd9Sstevel@tonic-gate }
58757c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
58767c478bd9Sstevel@tonic-gate
58777c478bd9Sstevel@tonic-gate if (local_node == B_TRUE)
58787c478bd9Sstevel@tonic-gate break;
58797c478bd9Sstevel@tonic-gate }
58807c478bd9Sstevel@tonic-gate
58817c478bd9Sstevel@tonic-gate gid_to_ni_exit:
58827c478bd9Sstevel@tonic-gate if (guid_array)
58837c478bd9Sstevel@tonic-gate ibt_free_hca_list(guid_array, num_hcas);
58847c478bd9Sstevel@tonic-gate
58857c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_gid_to_node_info: done. Status %d", retval);
58867c478bd9Sstevel@tonic-gate
58877c478bd9Sstevel@tonic-gate return (retval);
58887c478bd9Sstevel@tonic-gate }
58897c478bd9Sstevel@tonic-gate
58907c478bd9Sstevel@tonic-gate
589176c04273SRajkumar Sivaprakasam ibt_status_t
ibcm_get_node_rec(ibmf_saa_handle_t saa_handle,sa_node_record_t * nr_req,uint64_t component_mask,void * result_p,size_t * len)58927c478bd9Sstevel@tonic-gate ibcm_get_node_rec(ibmf_saa_handle_t saa_handle, sa_node_record_t *nr_req,
58937c478bd9Sstevel@tonic-gate uint64_t component_mask, void *result_p, size_t *len)
58947c478bd9Sstevel@tonic-gate {
58957c478bd9Sstevel@tonic-gate ibmf_saa_access_args_t args;
58967c478bd9Sstevel@tonic-gate size_t length;
58977c478bd9Sstevel@tonic-gate ibt_status_t retval;
58987c478bd9Sstevel@tonic-gate
58997c478bd9Sstevel@tonic-gate args.sq_attr_id = SA_NODERECORD_ATTRID;
59007c478bd9Sstevel@tonic-gate args.sq_template = nr_req;
59017c478bd9Sstevel@tonic-gate args.sq_access_type = IBMF_SAA_RETRIEVE;
59027c478bd9Sstevel@tonic-gate args.sq_template_length = sizeof (sa_node_record_t);
59037c478bd9Sstevel@tonic-gate args.sq_component_mask = component_mask;
59047c478bd9Sstevel@tonic-gate args.sq_callback = NULL;
59057c478bd9Sstevel@tonic-gate args.sq_callback_arg = NULL;
59067c478bd9Sstevel@tonic-gate
59077c478bd9Sstevel@tonic-gate retval = ibcm_contact_sa_access(saa_handle, &args, &length, result_p);
59087c478bd9Sstevel@tonic-gate if (retval != IBT_SUCCESS) {
59097c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_get_node_rec: SA Call Failed");
59107c478bd9Sstevel@tonic-gate return (retval);
59117c478bd9Sstevel@tonic-gate }
59127c478bd9Sstevel@tonic-gate
59137c478bd9Sstevel@tonic-gate *len = length;
59147c478bd9Sstevel@tonic-gate
59157c478bd9Sstevel@tonic-gate /* Validate the returned number of records. */
59167c478bd9Sstevel@tonic-gate if ((result_p != NULL) && (length > 0)) {
59177c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_get_node_rec: Node Records FOUND");
59187c478bd9Sstevel@tonic-gate
59197c478bd9Sstevel@tonic-gate /* Got it, done!. */
59207c478bd9Sstevel@tonic-gate return (IBT_SUCCESS);
59217c478bd9Sstevel@tonic-gate } else {
59227c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_get_node_rec: Node Rec NOT found");
59237c478bd9Sstevel@tonic-gate return (IBT_NODE_RECORDS_NOT_FOUND);
59247c478bd9Sstevel@tonic-gate }
59257c478bd9Sstevel@tonic-gate }
59267c478bd9Sstevel@tonic-gate
59277c478bd9Sstevel@tonic-gate
59287c478bd9Sstevel@tonic-gate /*
59297c478bd9Sstevel@tonic-gate * Function:
593017a2b317SBill Taylor * ibt_lid_to_node_info()
593117a2b317SBill Taylor * Input:
593217a2b317SBill Taylor * lid Identifies the IB Node and port for which to obtain
593317a2b317SBill Taylor * Node information.
593417a2b317SBill Taylor * Output:
593517a2b317SBill Taylor * node_info_p A pointer to an ibt_node_info_t structure (allocated
593617a2b317SBill Taylor * by the caller) in which to return the node information.
593717a2b317SBill Taylor * Returns:
593817a2b317SBill Taylor * IBT_SUCCESS
593917a2b317SBill Taylor * IBT_INVALID_PARAM
594017a2b317SBill Taylor * IBT_NODE_RECORDS_NOT_FOUND
594117a2b317SBill Taylor * IBT_NO_HCAS_AVAILABLE
594217a2b317SBill Taylor * Description:
594317a2b317SBill Taylor * Retrieve Node Information for the specified LID.
594417a2b317SBill Taylor */
594517a2b317SBill Taylor ibt_status_t
ibt_lid_to_node_info(ib_lid_t lid,ibt_node_info_t * node_info_p)594617a2b317SBill Taylor ibt_lid_to_node_info(ib_lid_t lid, ibt_node_info_t *node_info_p)
594717a2b317SBill Taylor {
594817a2b317SBill Taylor ibt_status_t retval;
594917a2b317SBill Taylor ibcm_hca_info_t *hcap;
595017a2b317SBill Taylor uint8_t i, j;
595117a2b317SBill Taylor ib_guid_t *guid_array = NULL;
595217a2b317SBill Taylor uint_t num_hcas = 0;
595317a2b317SBill Taylor
595417a2b317SBill Taylor
595517a2b317SBill Taylor IBTF_DPRINTF_L4(cmlog, "ibt_lid_to_node_info(0x%lX, %p)",
595617a2b317SBill Taylor lid, node_info_p);
595717a2b317SBill Taylor
595817a2b317SBill Taylor if ((lid == 0) || (node_info_p == NULL)) {
595917a2b317SBill Taylor IBTF_DPRINTF_L2(cmlog, "ibt_lid_to_node_info: "
596017a2b317SBill Taylor "Lid is zero, or node_info_p is NULL.");
596117a2b317SBill Taylor return (IBT_INVALID_PARAM);
596217a2b317SBill Taylor }
596317a2b317SBill Taylor
596417a2b317SBill Taylor /* Get the number of HCAs and their GUIDs */
596517a2b317SBill Taylor num_hcas = ibt_get_hca_list(&guid_array);
596617a2b317SBill Taylor IBTF_DPRINTF_L4(cmlog, "ibt_lid_to_node_info: ibt_get_hca_list "
596717a2b317SBill Taylor "returned %d hcas", num_hcas);
596817a2b317SBill Taylor
596917a2b317SBill Taylor if (num_hcas == 0) {
597017a2b317SBill Taylor IBTF_DPRINTF_L2(cmlog, "ibt_lid_to_node_info: "
597117a2b317SBill Taylor "NO HCA's Found on this system");
597217a2b317SBill Taylor return (IBT_NO_HCAS_AVAILABLE);
597317a2b317SBill Taylor }
597417a2b317SBill Taylor
597517a2b317SBill Taylor for (i = 0; i < num_hcas; i++) {
597617a2b317SBill Taylor hcap = ibcm_find_hca_entry(guid_array[i]);
597717a2b317SBill Taylor if (hcap == NULL) {
597817a2b317SBill Taylor IBTF_DPRINTF_L3(cmlog, "ibt_lid_to_node_info: "
597917a2b317SBill Taylor "HCA(%llX) info not found", guid_array[i]);
598017a2b317SBill Taylor retval = IBT_NO_HCAS_AVAILABLE;
598117a2b317SBill Taylor continue;
598217a2b317SBill Taylor }
598317a2b317SBill Taylor
598417a2b317SBill Taylor for (j = 0; j < hcap->hca_num_ports; j++) {
598517a2b317SBill Taylor uint8_t port;
598617a2b317SBill Taylor ibmf_saa_handle_t saa_handle;
598717a2b317SBill Taylor uint_t num_rec;
598817a2b317SBill Taylor size_t len;
598917a2b317SBill Taylor void *res_p;
599017a2b317SBill Taylor sa_node_record_t nr_req, *nr_resp;
599117a2b317SBill Taylor
599217a2b317SBill Taylor port = j + 1;
599317a2b317SBill Taylor
599417a2b317SBill Taylor /* Get SA Access Handle. */
599517a2b317SBill Taylor saa_handle = ibcm_get_saa_handle(hcap, port);
599617a2b317SBill Taylor if (saa_handle == NULL) {
599717a2b317SBill Taylor IBTF_DPRINTF_L3(cmlog, "ibt_lid_to_node_info: "
599817a2b317SBill Taylor "Port %d of HCA (%llX) is NOT ACTIVE",
599917a2b317SBill Taylor port, guid_array[i]);
600017a2b317SBill Taylor retval = IBT_NODE_RECORDS_NOT_FOUND;
600117a2b317SBill Taylor continue;
600217a2b317SBill Taylor }
600317a2b317SBill Taylor
600417a2b317SBill Taylor /* Retrieve Node Records from SA Access. */
600517a2b317SBill Taylor bzero(&nr_req, sizeof (sa_node_record_t));
600617a2b317SBill Taylor
600717a2b317SBill Taylor nr_req.LID = lid; /* LID */
600817a2b317SBill Taylor
600917a2b317SBill Taylor retval = ibcm_get_node_rec(saa_handle, &nr_req,
601017a2b317SBill Taylor SA_NODEINFO_COMPMASK_NODELID, &res_p, &len);
601117a2b317SBill Taylor if (retval == IBT_NODE_RECORDS_NOT_FOUND) {
601217a2b317SBill Taylor IBTF_DPRINTF_L2(cmlog, "ibt_lid_to_node_info: "
601317a2b317SBill Taylor "failed (%d) to get Node records", retval);
601417a2b317SBill Taylor continue;
601517a2b317SBill Taylor } else if (retval != IBT_SUCCESS) {
601617a2b317SBill Taylor IBTF_DPRINTF_L2(cmlog, "ibt_lid_to_node_info: "
601717a2b317SBill Taylor "failed (%d) to get Node records", retval);
601817a2b317SBill Taylor ibcm_dec_hca_acc_cnt(hcap);
601917a2b317SBill Taylor goto lid_to_ni_exit;
602017a2b317SBill Taylor }
602117a2b317SBill Taylor
602217a2b317SBill Taylor num_rec = len/sizeof (sa_node_record_t);
602317a2b317SBill Taylor nr_resp = (sa_node_record_t *)(uchar_t *)res_p;
602417a2b317SBill Taylor
602517a2b317SBill Taylor /* Validate the returned number of records. */
602617a2b317SBill Taylor if ((nr_resp != NULL) && (num_rec > 0)) {
602717a2b317SBill Taylor
602817a2b317SBill Taylor IBCM_DUMP_NODE_REC(nr_resp);
602917a2b317SBill Taylor
603017a2b317SBill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(
603117a2b317SBill Taylor *node_info_p))
603217a2b317SBill Taylor
603317a2b317SBill Taylor node_info_p->n_sys_img_guid =
603417a2b317SBill Taylor nr_resp->NodeInfo.SystemImageGUID;
603517a2b317SBill Taylor node_info_p->n_node_guid =
603617a2b317SBill Taylor nr_resp->NodeInfo.NodeGUID;
603717a2b317SBill Taylor node_info_p->n_port_guid =
603817a2b317SBill Taylor nr_resp->NodeInfo.PortGUID;
603917a2b317SBill Taylor node_info_p->n_dev_id =
604017a2b317SBill Taylor nr_resp->NodeInfo.DeviceID;
604117a2b317SBill Taylor node_info_p->n_revision =
604217a2b317SBill Taylor nr_resp->NodeInfo.Revision;
604317a2b317SBill Taylor node_info_p->n_vendor_id =
604417a2b317SBill Taylor nr_resp->NodeInfo.VendorID;
604517a2b317SBill Taylor node_info_p->n_num_ports =
604617a2b317SBill Taylor nr_resp->NodeInfo.NumPorts;
604717a2b317SBill Taylor node_info_p->n_port_num =
604817a2b317SBill Taylor nr_resp->NodeInfo.LocalPortNum;
604917a2b317SBill Taylor node_info_p->n_node_type =
605017a2b317SBill Taylor nr_resp->NodeInfo.NodeType;
605117a2b317SBill Taylor (void) strncpy(node_info_p->n_description,
605217a2b317SBill Taylor (char *)&nr_resp->NodeDescription, 64);
605317a2b317SBill Taylor
605417a2b317SBill Taylor _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(
605517a2b317SBill Taylor *node_info_p))
605617a2b317SBill Taylor
605717a2b317SBill Taylor /*
605817a2b317SBill Taylor * Deallocate the memory allocated by SA for
605917a2b317SBill Taylor * 'nr_resp'.
606017a2b317SBill Taylor */
606117a2b317SBill Taylor ibcm_dec_hca_acc_cnt(hcap);
606217a2b317SBill Taylor kmem_free(nr_resp, len);
606317a2b317SBill Taylor retval = IBT_SUCCESS;
606417a2b317SBill Taylor
606517a2b317SBill Taylor goto lid_to_ni_exit;
606617a2b317SBill Taylor } else {
606717a2b317SBill Taylor retval = IBT_NODE_RECORDS_NOT_FOUND;
606817a2b317SBill Taylor IBTF_DPRINTF_L3(cmlog, "ibt_lid_to_node_info: "
606917a2b317SBill Taylor "Node Records NOT found - LID 0x%lX",
607017a2b317SBill Taylor lid);
607117a2b317SBill Taylor }
607217a2b317SBill Taylor }
607317a2b317SBill Taylor ibcm_dec_hca_acc_cnt(hcap);
607417a2b317SBill Taylor }
607517a2b317SBill Taylor
607617a2b317SBill Taylor lid_to_ni_exit:
607717a2b317SBill Taylor if (guid_array)
607817a2b317SBill Taylor ibt_free_hca_list(guid_array, num_hcas);
607917a2b317SBill Taylor
608017a2b317SBill Taylor IBTF_DPRINTF_L3(cmlog, "ibt_lid_to_node_info: done. Status %d", retval);
608117a2b317SBill Taylor
608217a2b317SBill Taylor return (retval);
608317a2b317SBill Taylor }
608417a2b317SBill Taylor
608517a2b317SBill Taylor /*
608617a2b317SBill Taylor * Function:
60877c478bd9Sstevel@tonic-gate * ibt_get_companion_port_gids()
60887c478bd9Sstevel@tonic-gate * Description:
60897c478bd9Sstevel@tonic-gate * Get list of GID's available on a companion port(s) of the specified
60907c478bd9Sstevel@tonic-gate * GID or list of GIDs available on a specified Node GUID/SystemImage GUID.
60917c478bd9Sstevel@tonic-gate */
60927c478bd9Sstevel@tonic-gate ibt_status_t
ibt_get_companion_port_gids(ib_gid_t gid,ib_guid_t hca_guid,ib_guid_t sysimg_guid,ib_gid_t ** gids_p,uint_t * num_gids_p)60937c478bd9Sstevel@tonic-gate ibt_get_companion_port_gids(ib_gid_t gid, ib_guid_t hca_guid,
60947c478bd9Sstevel@tonic-gate ib_guid_t sysimg_guid, ib_gid_t **gids_p, uint_t *num_gids_p)
60957c478bd9Sstevel@tonic-gate {
60967c478bd9Sstevel@tonic-gate sa_node_record_t nr_req, *nr_resp;
60977c478bd9Sstevel@tonic-gate void *res_p;
60987c478bd9Sstevel@tonic-gate ibmf_saa_handle_t saa_handle;
60997c478bd9Sstevel@tonic-gate int sa_ret;
6100448978d3Shiremath ibt_status_t retval = IBT_SUCCESS;
61017c478bd9Sstevel@tonic-gate ibcm_hca_info_t *hcap;
61027c478bd9Sstevel@tonic-gate ibtl_cm_hca_port_t hport;
61037c478bd9Sstevel@tonic-gate int i, j;
61047c478bd9Sstevel@tonic-gate uint_t num_rec;
61057c478bd9Sstevel@tonic-gate ib_guid_t *guid_array = NULL;
61067c478bd9Sstevel@tonic-gate sa_path_record_t *path;
61077c478bd9Sstevel@tonic-gate size_t len;
61087c478bd9Sstevel@tonic-gate uint8_t npaths;
61097c478bd9Sstevel@tonic-gate uint32_t num_hcas = 0;
61107c478bd9Sstevel@tonic-gate boolean_t local_node = B_FALSE;
61117c478bd9Sstevel@tonic-gate boolean_t local_hca = B_FALSE;
61127c478bd9Sstevel@tonic-gate ib_guid_t h_guid = hca_guid;
61137c478bd9Sstevel@tonic-gate ib_gid_t *gidp = NULL, *t_gidp = NULL;
611424b28d04Shiremath int multi_hca_loop = 0;
61157c478bd9Sstevel@tonic-gate
61167c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_get_companion_port_gids(%llX:%llX, %llX, "
61177c478bd9Sstevel@tonic-gate "%llX)", gid.gid_prefix, gid.gid_guid, hca_guid, sysimg_guid);
61187c478bd9Sstevel@tonic-gate
61197c478bd9Sstevel@tonic-gate if (((gid.gid_prefix == 0) || (gid.gid_guid == 0)) && (hca_guid == 0) &&
61207c478bd9Sstevel@tonic-gate (sysimg_guid == 0)) {
61217c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_get_companion_port_gids: "
61227c478bd9Sstevel@tonic-gate "Null Input attribute specified.");
61237c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
61247c478bd9Sstevel@tonic-gate }
61257c478bd9Sstevel@tonic-gate
61267c478bd9Sstevel@tonic-gate if ((num_gids_p == NULL) || (gids_p == NULL)) {
61277c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_get_companion_port_gids: "
61287c478bd9Sstevel@tonic-gate "num_gids_p or gids_p is NULL");
61297c478bd9Sstevel@tonic-gate return (IBT_INVALID_PARAM);
61307c478bd9Sstevel@tonic-gate }
61317c478bd9Sstevel@tonic-gate
61327c478bd9Sstevel@tonic-gate *num_gids_p = 0;
61337c478bd9Sstevel@tonic-gate
61347c478bd9Sstevel@tonic-gate /* Get the number of HCAs and their GUIDs */
61357c478bd9Sstevel@tonic-gate if ((num_hcas = ibt_get_hca_list(&guid_array)) == 0) {
61367c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_get_companion_port_gids: "
61377c478bd9Sstevel@tonic-gate "NO HCA's Found on this system");
61387c478bd9Sstevel@tonic-gate return (IBT_NO_HCAS_AVAILABLE);
61397c478bd9Sstevel@tonic-gate }
61407c478bd9Sstevel@tonic-gate
61417c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_get_companion_port_gids: "
61427c478bd9Sstevel@tonic-gate "ibt_get_hca_list() returned %d hcas", num_hcas);
61437c478bd9Sstevel@tonic-gate
61447c478bd9Sstevel@tonic-gate /*
61457c478bd9Sstevel@tonic-gate * If 'gid' is on local node, then get node lid (i.e. base lid of the
61467c478bd9Sstevel@tonic-gate * associated port) info via ibtl_cm_get_hca_port() call.
61477c478bd9Sstevel@tonic-gate */
61487c478bd9Sstevel@tonic-gate bzero(&hport, sizeof (ibtl_cm_hca_port_t));
61497c478bd9Sstevel@tonic-gate if ((gid.gid_prefix != 0) && (gid.gid_guid != 0) &&
61507c478bd9Sstevel@tonic-gate (ibtl_cm_get_hca_port(gid, 0, &hport) == IBT_SUCCESS)) {
61517c478bd9Sstevel@tonic-gate
61527c478bd9Sstevel@tonic-gate if ((hca_guid != 0) && (hca_guid != hport.hp_hca_guid)) {
61537c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibt_get_companion_port_gids: "
61547c478bd9Sstevel@tonic-gate "Invalid GID<->HCAGUID combination specified.");
61557c478bd9Sstevel@tonic-gate retval = IBT_INVALID_PARAM;
61567c478bd9Sstevel@tonic-gate goto get_comp_pgid_exit;
61577c478bd9Sstevel@tonic-gate }
61587c478bd9Sstevel@tonic-gate h_guid = hport.hp_hca_guid;
61597c478bd9Sstevel@tonic-gate local_node = B_TRUE;
61607c478bd9Sstevel@tonic-gate
61617c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibt_get_companion_port_gids: "
61627c478bd9Sstevel@tonic-gate "Local Node: HCA (0x%llX)", h_guid);
61637c478bd9Sstevel@tonic-gate } else if (h_guid) { /* Is specified HCA GUID - local? */
61647c478bd9Sstevel@tonic-gate for (i = 0; i < num_hcas; i++) {
61657c478bd9Sstevel@tonic-gate if (h_guid == guid_array[i]) {
61667c478bd9Sstevel@tonic-gate local_hca = B_TRUE;
61677c478bd9Sstevel@tonic-gate break;
61687c478bd9Sstevel@tonic-gate }
61697c478bd9Sstevel@tonic-gate }
61707c478bd9Sstevel@tonic-gate } else if (sysimg_guid) { /* Is specified SystemImage GUID - local? */
61717c478bd9Sstevel@tonic-gate for (i = 0; i < num_hcas; i++) {
61727c478bd9Sstevel@tonic-gate ibt_status_t ret;
61737c478bd9Sstevel@tonic-gate ibt_hca_attr_t hca_attr;
61747c478bd9Sstevel@tonic-gate
61757c478bd9Sstevel@tonic-gate ret = ibt_query_hca_byguid(guid_array[i], &hca_attr);
61767c478bd9Sstevel@tonic-gate if (ret != IBT_SUCCESS) {
61777c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog,
61787c478bd9Sstevel@tonic-gate "ibt_get_companion_port_gids: HCA(%llX) "
61797c478bd9Sstevel@tonic-gate "info not found", guid_array[i]);
61807c478bd9Sstevel@tonic-gate retval = IBT_NO_HCAS_AVAILABLE;
61817c478bd9Sstevel@tonic-gate continue;
61827c478bd9Sstevel@tonic-gate }
61837c478bd9Sstevel@tonic-gate if (hca_attr.hca_si_guid == sysimg_guid) {
61847c478bd9Sstevel@tonic-gate if ((hca_guid != 0) &&
61857c478bd9Sstevel@tonic-gate (hca_guid != hca_attr.hca_node_guid)) {
61867c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog,
61877c478bd9Sstevel@tonic-gate "ibt_get_companion_port_gids: "
61887c478bd9Sstevel@tonic-gate "Invalid SysImg<->HCA GUID "
61897c478bd9Sstevel@tonic-gate "combination specified.");
61907c478bd9Sstevel@tonic-gate retval = IBT_INVALID_PARAM;
61917c478bd9Sstevel@tonic-gate goto get_comp_pgid_exit;
61927c478bd9Sstevel@tonic-gate }
61937c478bd9Sstevel@tonic-gate local_hca = B_TRUE;
61947c478bd9Sstevel@tonic-gate h_guid = hca_attr.hca_node_guid;
61957c478bd9Sstevel@tonic-gate break;
61967c478bd9Sstevel@tonic-gate }
61977c478bd9Sstevel@tonic-gate }
61987c478bd9Sstevel@tonic-gate }
61997c478bd9Sstevel@tonic-gate
62007c478bd9Sstevel@tonic-gate if ((local_node == B_TRUE) || (local_hca == B_TRUE)) {
62017c478bd9Sstevel@tonic-gate retval = ibtl_cm_get_local_comp_gids(h_guid, gid, gids_p,
62027c478bd9Sstevel@tonic-gate num_gids_p);
62037c478bd9Sstevel@tonic-gate goto get_comp_pgid_exit;
62047c478bd9Sstevel@tonic-gate }
62057c478bd9Sstevel@tonic-gate
620624b28d04Shiremath get_comp_for_multihca:
62077c478bd9Sstevel@tonic-gate /* We will be here, if request is for remote node */
62087c478bd9Sstevel@tonic-gate for (i = 0; i < num_hcas; i++) {
62097c478bd9Sstevel@tonic-gate int multism;
62105c42ea03Shiremath uint_t count = 0;
62117c478bd9Sstevel@tonic-gate int multi_sm_loop = 0;
62127c478bd9Sstevel@tonic-gate uint_t k = 0, l;
62137c478bd9Sstevel@tonic-gate
62147c478bd9Sstevel@tonic-gate hcap = ibcm_find_hca_entry(guid_array[i]);
62157c478bd9Sstevel@tonic-gate if (hcap == NULL) {
62167c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_get_companion_port_gids: "
62177c478bd9Sstevel@tonic-gate "HCA(%llX) info not found", guid_array[i]);
62187c478bd9Sstevel@tonic-gate retval = IBT_NO_HCAS_AVAILABLE;
62197c478bd9Sstevel@tonic-gate continue;
62207c478bd9Sstevel@tonic-gate }
62217c478bd9Sstevel@tonic-gate
62227c478bd9Sstevel@tonic-gate /* 1 - MultiSM, 0 - Single SM */
62237c478bd9Sstevel@tonic-gate multism = ibtl_cm_is_multi_sm(guid_array[i]);
62247c478bd9Sstevel@tonic-gate
62257c478bd9Sstevel@tonic-gate for (j = 0; j < hcap->hca_num_ports; j++) {
62267c478bd9Sstevel@tonic-gate ib_gid_t sgid;
62277c478bd9Sstevel@tonic-gate uint64_t c_mask = 0;
62287c478bd9Sstevel@tonic-gate ib_guid_t pg;
62297c478bd9Sstevel@tonic-gate uint_t port = j;
62307c478bd9Sstevel@tonic-gate
62317c478bd9Sstevel@tonic-gate get_comp_for_multism:
62327c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_get_companion_port_gids: "
62337c478bd9Sstevel@tonic-gate "Port %d, HCA %llX, MultiSM= %d, Loop=%d",
62347c478bd9Sstevel@tonic-gate port + 1, h_guid, multism, multi_sm_loop);
62357c478bd9Sstevel@tonic-gate
62367c478bd9Sstevel@tonic-gate /* Get SA Access Handle. */
62377c478bd9Sstevel@tonic-gate saa_handle = ibcm_get_saa_handle(hcap, port + 1);
62387c478bd9Sstevel@tonic-gate if (saa_handle == NULL) {
62397c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog,
62407c478bd9Sstevel@tonic-gate "ibt_get_companion_port_gids: "
6241448978d3Shiremath "Port (%d) - NOT ACTIVE", port + 1);
6242448978d3Shiremath retval = IBT_GIDS_NOT_FOUND;
62437c478bd9Sstevel@tonic-gate continue;
62447c478bd9Sstevel@tonic-gate }
62457c478bd9Sstevel@tonic-gate
62467c478bd9Sstevel@tonic-gate /*
62477c478bd9Sstevel@tonic-gate * Check whether 'gid' and this port has same subnet
62487c478bd9Sstevel@tonic-gate * prefix. If not, then there is no use in searching
62497c478bd9Sstevel@tonic-gate * from this port.
62507c478bd9Sstevel@tonic-gate */
62517c478bd9Sstevel@tonic-gate sgid = hcap->hca_port_info[port].port_sgid0;
625224b28d04Shiremath if ((h_guid == 0) && (gid.gid_prefix != 0) &&
625324b28d04Shiremath (multi_sm_loop == 0) &&
62547c478bd9Sstevel@tonic-gate (gid.gid_prefix != sgid.gid_prefix)) {
62557c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog,
62567c478bd9Sstevel@tonic-gate "ibt_get_companion_port_gids: SnPrefix of "
62577c478bd9Sstevel@tonic-gate "GID(%llX) and Port SN_Pfx(%llX) differ",
62587c478bd9Sstevel@tonic-gate gid.gid_prefix, sgid.gid_prefix);
6259448978d3Shiremath retval = IBT_GIDS_NOT_FOUND;
62607c478bd9Sstevel@tonic-gate continue;
62617c478bd9Sstevel@tonic-gate }
62627c478bd9Sstevel@tonic-gate
62637c478bd9Sstevel@tonic-gate /*
62647c478bd9Sstevel@tonic-gate * If HCA GUID or System Image GUID is specified, then
62657c478bd9Sstevel@tonic-gate * we can achieve our goal sooner!.
62667c478bd9Sstevel@tonic-gate */
62677c478bd9Sstevel@tonic-gate if ((h_guid == 0) && (sysimg_guid == 0)) {
62687c478bd9Sstevel@tonic-gate /* So only GID info is provided. */
62697c478bd9Sstevel@tonic-gate
62707c478bd9Sstevel@tonic-gate /*
62717c478bd9Sstevel@tonic-gate * First Get Path Records for the specified DGID
62727c478bd9Sstevel@tonic-gate * from this port (SGID). From Path Records,
62737c478bd9Sstevel@tonic-gate * note down DLID, then use this DLID as Input
62747c478bd9Sstevel@tonic-gate * attribute to get NodeRecords.
62757c478bd9Sstevel@tonic-gate */
62767c478bd9Sstevel@tonic-gate npaths = 1;
62777c478bd9Sstevel@tonic-gate path = NULL;
62787c478bd9Sstevel@tonic-gate
62797c478bd9Sstevel@tonic-gate sa_ret = ibmf_saa_gid_to_pathrecords(saa_handle,
62807c478bd9Sstevel@tonic-gate sgid, gid, 0, 0, B_TRUE, &npaths, 0, &len,
62817c478bd9Sstevel@tonic-gate &path);
62827c478bd9Sstevel@tonic-gate if (sa_ret != IBMF_SUCCESS) {
62837c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog,
62847c478bd9Sstevel@tonic-gate "ibt_get_companion_port_gids: "
62857c478bd9Sstevel@tonic-gate "ibmf_saa_gid_to_pathrecords() "
62867c478bd9Sstevel@tonic-gate "returned error: %d ", sa_ret);
62877c478bd9Sstevel@tonic-gate retval =
62887c478bd9Sstevel@tonic-gate ibcm_ibmf_analyze_error(sa_ret);
62897c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
62907c478bd9Sstevel@tonic-gate goto get_comp_pgid_exit;
62917c478bd9Sstevel@tonic-gate } else if ((npaths == 0) || (path == NULL)) {
62927c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog,
62937c478bd9Sstevel@tonic-gate "ibt_get_companion_port_gids: "
62947c478bd9Sstevel@tonic-gate "failed (%d) to get path records "
62957c478bd9Sstevel@tonic-gate "for the DGID (0x%llX) from SGID "
62967c478bd9Sstevel@tonic-gate "(0x%llX)", sa_ret, gid.gid_guid,
62977c478bd9Sstevel@tonic-gate sgid.gid_guid);
6298448978d3Shiremath retval = IBT_GIDS_NOT_FOUND;
62997c478bd9Sstevel@tonic-gate continue;
63007c478bd9Sstevel@tonic-gate }
630124b28d04Shiremath
630224b28d04Shiremath bzero(&nr_req, sizeof (sa_node_record_t));
63037c478bd9Sstevel@tonic-gate nr_req.LID = path->DLID; /* LID */
63047c478bd9Sstevel@tonic-gate
63057c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog,
63067c478bd9Sstevel@tonic-gate "ibt_get_companion_port_gids: "
63077c478bd9Sstevel@tonic-gate "Remote Node: LID = 0x%X", nr_req.LID);
63087c478bd9Sstevel@tonic-gate
63097c478bd9Sstevel@tonic-gate /* Free SA_Access memory for path record. */
63107c478bd9Sstevel@tonic-gate kmem_free(path, len);
63117c478bd9Sstevel@tonic-gate
63127c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog,
63137c478bd9Sstevel@tonic-gate "ibt_get_companion_port_gids: SAA Call: "
63147c478bd9Sstevel@tonic-gate "based on LID ");
63157c478bd9Sstevel@tonic-gate
63167c478bd9Sstevel@tonic-gate retval = ibcm_get_node_rec(saa_handle, &nr_req,
63177c478bd9Sstevel@tonic-gate SA_NODEINFO_COMPMASK_NODELID, &res_p, &len);
63187c478bd9Sstevel@tonic-gate if (retval == IBT_NODE_RECORDS_NOT_FOUND) {
63197c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog,
63207c478bd9Sstevel@tonic-gate "ibt_get_companion_port_gids: "
63217c478bd9Sstevel@tonic-gate "failed (%d) to get Node records",
63227c478bd9Sstevel@tonic-gate retval);
63237c478bd9Sstevel@tonic-gate continue;
63247c478bd9Sstevel@tonic-gate } else if (retval != IBT_SUCCESS) {
63257c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog,
63267c478bd9Sstevel@tonic-gate "ibt_get_companion_port_gids: "
63277c478bd9Sstevel@tonic-gate "failed (%d) to get Node records",
63287c478bd9Sstevel@tonic-gate retval);
63297c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
63307c478bd9Sstevel@tonic-gate goto get_comp_pgid_exit;
63317c478bd9Sstevel@tonic-gate }
63327c478bd9Sstevel@tonic-gate
63337c478bd9Sstevel@tonic-gate nr_resp = (sa_node_record_t *)(uchar_t *)res_p;
63347c478bd9Sstevel@tonic-gate /* Note down HCA GUID info. */
63357c478bd9Sstevel@tonic-gate h_guid = nr_resp->NodeInfo.NodeGUID;
63367c478bd9Sstevel@tonic-gate
63377c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog,
63387c478bd9Sstevel@tonic-gate "ibt_get_companion_port_gids: "
63397c478bd9Sstevel@tonic-gate "Remote HCA GUID: 0x%llX", h_guid);
63407c478bd9Sstevel@tonic-gate
63417c478bd9Sstevel@tonic-gate IBCM_DUMP_NODE_REC(nr_resp);
63427c478bd9Sstevel@tonic-gate
63437c478bd9Sstevel@tonic-gate kmem_free(res_p, len);
63447c478bd9Sstevel@tonic-gate }
63457c478bd9Sstevel@tonic-gate
634624b28d04Shiremath bzero(&nr_req, sizeof (sa_node_record_t));
63477c478bd9Sstevel@tonic-gate if (h_guid != 0) {
63487c478bd9Sstevel@tonic-gate nr_req.NodeInfo.NodeGUID = h_guid;
63497c478bd9Sstevel@tonic-gate c_mask = SA_NODEINFO_COMPMASK_NODEGUID;
63507c478bd9Sstevel@tonic-gate }
63517c478bd9Sstevel@tonic-gate
63527c478bd9Sstevel@tonic-gate if (sysimg_guid != 0) {
63537c478bd9Sstevel@tonic-gate nr_req.NodeInfo.SystemImageGUID = sysimg_guid;
63547c478bd9Sstevel@tonic-gate c_mask |= SA_NODEINFO_COMPMASK_SYSIMAGEGUID;
63557c478bd9Sstevel@tonic-gate }
63567c478bd9Sstevel@tonic-gate
63577c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_get_companion_port_gids: "
63587c478bd9Sstevel@tonic-gate "SAA Call: CMASK= 0x%llX", c_mask);
63597c478bd9Sstevel@tonic-gate
63607c478bd9Sstevel@tonic-gate retval = ibcm_get_node_rec(saa_handle, &nr_req, c_mask,
63617c478bd9Sstevel@tonic-gate &res_p, &len);
63627c478bd9Sstevel@tonic-gate if (retval == IBT_NODE_RECORDS_NOT_FOUND) {
63637c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog,
63647c478bd9Sstevel@tonic-gate "ibt_get_companion_port_gids: "
63657c478bd9Sstevel@tonic-gate "failed (%d) to get Node records", retval);
63667c478bd9Sstevel@tonic-gate continue;
63677c478bd9Sstevel@tonic-gate } else if (retval != IBT_SUCCESS) {
63687c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog,
63697c478bd9Sstevel@tonic-gate "ibt_get_companion_port_gids: Error: (%d) "
63707c478bd9Sstevel@tonic-gate "while getting Node records", retval);
63717c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
63727c478bd9Sstevel@tonic-gate goto get_comp_pgid_exit;
63737c478bd9Sstevel@tonic-gate }
63747c478bd9Sstevel@tonic-gate
63757c478bd9Sstevel@tonic-gate num_rec = len/sizeof (sa_node_record_t);
63767c478bd9Sstevel@tonic-gate
63777c478bd9Sstevel@tonic-gate /* We will be here, only if we found some NodeRec */
63787c478bd9Sstevel@tonic-gate if (gid.gid_prefix && gid.gid_guid) {
63797c478bd9Sstevel@tonic-gate nr_resp = (sa_node_record_t *)res_p;
63807c478bd9Sstevel@tonic-gate for (l = 0; l < num_rec; l++, nr_resp++) {
63817c478bd9Sstevel@tonic-gate pg = nr_resp->NodeInfo.PortGUID;
63827c478bd9Sstevel@tonic-gate if (gid.gid_guid != pg)
63837c478bd9Sstevel@tonic-gate count++;
63847c478bd9Sstevel@tonic-gate }
63857c478bd9Sstevel@tonic-gate } else {
63867c478bd9Sstevel@tonic-gate count = num_rec;
63877c478bd9Sstevel@tonic-gate }
63887c478bd9Sstevel@tonic-gate
63897c478bd9Sstevel@tonic-gate if (count != 0) {
63907c478bd9Sstevel@tonic-gate if (multi_sm_loop == 1) {
63917c478bd9Sstevel@tonic-gate count += k;
63927c478bd9Sstevel@tonic-gate t_gidp = kmem_zalloc(count *
63937c478bd9Sstevel@tonic-gate sizeof (ib_gid_t), KM_SLEEP);
63947c478bd9Sstevel@tonic-gate
63957c478bd9Sstevel@tonic-gate if ((k != 0) && (gidp != NULL)) {
63967c478bd9Sstevel@tonic-gate bcopy(gidp, t_gidp,
63977c478bd9Sstevel@tonic-gate k * sizeof (ib_gid_t));
63987c478bd9Sstevel@tonic-gate kmem_free(gidp,
63997c478bd9Sstevel@tonic-gate k * sizeof (ib_gid_t));
64007c478bd9Sstevel@tonic-gate }
64017c478bd9Sstevel@tonic-gate gidp = t_gidp;
64027c478bd9Sstevel@tonic-gate } else {
64037c478bd9Sstevel@tonic-gate gidp = kmem_zalloc(count *
64047c478bd9Sstevel@tonic-gate sizeof (ib_gid_t), KM_SLEEP);
64057c478bd9Sstevel@tonic-gate }
64067c478bd9Sstevel@tonic-gate *num_gids_p = count;
64077c478bd9Sstevel@tonic-gate *gids_p = gidp;
64087c478bd9Sstevel@tonic-gate
64097c478bd9Sstevel@tonic-gate nr_resp = (sa_node_record_t *)res_p;
64107c478bd9Sstevel@tonic-gate for (l = 0; l < num_rec; l++, nr_resp++) {
64117c478bd9Sstevel@tonic-gate IBCM_DUMP_NODE_REC(nr_resp);
64127c478bd9Sstevel@tonic-gate
64137c478bd9Sstevel@tonic-gate pg = nr_resp->NodeInfo.PortGUID;
64147c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog,
64157c478bd9Sstevel@tonic-gate "ibt_get_companion_port_gids: "
64167c478bd9Sstevel@tonic-gate "PortGID %llX", pg);
64177c478bd9Sstevel@tonic-gate
64187c478bd9Sstevel@tonic-gate if (pg != gid.gid_guid) {
64197c478bd9Sstevel@tonic-gate gidp[k].gid_prefix =
64207c478bd9Sstevel@tonic-gate sgid.gid_prefix;
64217c478bd9Sstevel@tonic-gate gidp[k].gid_guid = pg;
64227c478bd9Sstevel@tonic-gate
64237c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog,
64247c478bd9Sstevel@tonic-gate "ibt_get_companion_pgids: "
64257c478bd9Sstevel@tonic-gate "GID[%d] = %llX:%llX", k,
64267c478bd9Sstevel@tonic-gate gidp[k].gid_prefix,
64277c478bd9Sstevel@tonic-gate gidp[k].gid_guid);
64287c478bd9Sstevel@tonic-gate
64297c478bd9Sstevel@tonic-gate k++;
64307c478bd9Sstevel@tonic-gate if (k == count)
64317c478bd9Sstevel@tonic-gate break;
64327c478bd9Sstevel@tonic-gate }
64337c478bd9Sstevel@tonic-gate }
64347c478bd9Sstevel@tonic-gate retval = IBT_SUCCESS; /* done!. */
643524b28d04Shiremath kmem_free(res_p, len);
643624b28d04Shiremath ibcm_dec_hca_acc_cnt(hcap);
643724b28d04Shiremath goto get_comp_pgid_exit;
64387c478bd9Sstevel@tonic-gate } else {
64397c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog,
64407c478bd9Sstevel@tonic-gate "ibt_get_companion_port_gids: "
64417c478bd9Sstevel@tonic-gate "Companion PortGIDs not available");
64427c478bd9Sstevel@tonic-gate retval = IBT_GIDS_NOT_FOUND;
64437c478bd9Sstevel@tonic-gate }
64447c478bd9Sstevel@tonic-gate /* Deallocate the memory for 'res_p'. */
64457c478bd9Sstevel@tonic-gate kmem_free(res_p, len);
64467c478bd9Sstevel@tonic-gate
64477c478bd9Sstevel@tonic-gate /*
64487c478bd9Sstevel@tonic-gate * If we are on MultiSM setup, then we need to lookout
64497c478bd9Sstevel@tonic-gate * from that subnet port too.
64507c478bd9Sstevel@tonic-gate */
64517c478bd9Sstevel@tonic-gate if (multism) {
64527c478bd9Sstevel@tonic-gate /* break if already searched both the subnet */
64537c478bd9Sstevel@tonic-gate if (multi_sm_loop == 1)
64547c478bd9Sstevel@tonic-gate break;
64557c478bd9Sstevel@tonic-gate
64567c478bd9Sstevel@tonic-gate port = (j == 0) ? 1 : 0;
64577c478bd9Sstevel@tonic-gate multi_sm_loop = 1;
64587c478bd9Sstevel@tonic-gate goto get_comp_for_multism;
64597c478bd9Sstevel@tonic-gate } else {
64607c478bd9Sstevel@tonic-gate break;
64617c478bd9Sstevel@tonic-gate }
64627c478bd9Sstevel@tonic-gate }
64637c478bd9Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
646424b28d04Shiremath
646524b28d04Shiremath /*
646624b28d04Shiremath * We may be on dual HCA with dual SM configured system. And
646724b28d04Shiremath * the input attr GID was visible from second HCA. So in order
646824b28d04Shiremath * to get the companion portgid we need to re-look from the
646924b28d04Shiremath * first HCA ports.
647024b28d04Shiremath */
647124b28d04Shiremath if ((num_hcas > 1) && (i > 0) && (h_guid != 0) &&
647224b28d04Shiremath (multi_hca_loop != 1)) {
647324b28d04Shiremath multi_hca_loop = 1;
647424b28d04Shiremath goto get_comp_for_multihca;
647524b28d04Shiremath }
64767c478bd9Sstevel@tonic-gate }
6477448978d3Shiremath if (*num_gids_p == 0)
6478448978d3Shiremath retval = IBT_GIDS_NOT_FOUND;
64797c478bd9Sstevel@tonic-gate
64807c478bd9Sstevel@tonic-gate get_comp_pgid_exit:
64817c478bd9Sstevel@tonic-gate if (guid_array)
64827c478bd9Sstevel@tonic-gate ibt_free_hca_list(guid_array, num_hcas);
64837c478bd9Sstevel@tonic-gate
64847c478bd9Sstevel@tonic-gate if ((retval != IBT_SUCCESS) && (*num_gids_p != 0)) {
64857c478bd9Sstevel@tonic-gate retval = IBT_SUCCESS;
64867c478bd9Sstevel@tonic-gate }
64877c478bd9Sstevel@tonic-gate
64887c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibt_get_companion_port_gids: done. Status %d, "
64897c478bd9Sstevel@tonic-gate "Found %d GIDs", retval, *num_gids_p);
64907c478bd9Sstevel@tonic-gate
64917c478bd9Sstevel@tonic-gate return (retval);
64927c478bd9Sstevel@tonic-gate }
64937c478bd9Sstevel@tonic-gate
6494015f8fffShiremath /* RDMA IP CM Support routines */
6495015f8fffShiremath ibt_status_t
ibt_get_src_ip(ibt_srcip_attr_t * sattr,ibt_srcip_info_t ** src_info_p,uint_t * entries_p)649617a2b317SBill Taylor ibt_get_src_ip(ibt_srcip_attr_t *sattr, ibt_srcip_info_t **src_info_p,
649717a2b317SBill Taylor uint_t *entries_p)
6498015f8fffShiremath {
649917a2b317SBill Taylor ibt_srcip_info_t *s_ip;
6500015f8fffShiremath ibcm_arp_ip_t *ipp;
6501015f8fffShiremath ibcm_arp_ibd_insts_t ibds;
650217a2b317SBill Taylor uint8_t i, j;
650317a2b317SBill Taylor uint_t count;
6504015f8fffShiremath ibt_status_t retval = IBT_SUCCESS;
6505015f8fffShiremath
650617a2b317SBill Taylor IBTF_DPRINTF_L4(cmlog, "ibt_get_src_ip(%p, %p, %p)",
650717a2b317SBill Taylor sattr, src_info_p, entries_p);
6508015f8fffShiremath
650917a2b317SBill Taylor if (sattr == NULL || entries_p == NULL) {
651017a2b317SBill Taylor IBTF_DPRINTF_L3(cmlog, "ibt_get_src_ip: Invalid I/P Args.");
651117a2b317SBill Taylor return (IBT_INVALID_PARAM);
651217a2b317SBill Taylor }
651317a2b317SBill Taylor
651417a2b317SBill Taylor if (sattr->sip_gid.gid_prefix == 0 || sattr->sip_gid.gid_guid == 0) {
6515015f8fffShiremath IBTF_DPRINTF_L3(cmlog, "ibt_get_src_ip: Invalid GID.");
6516015f8fffShiremath return (IBT_INVALID_PARAM);
6517015f8fffShiremath }
6518015f8fffShiremath
651917a2b317SBill Taylor /* TBD: Zoneid */
652017a2b317SBill Taylor retval = ibcm_arp_get_ibds(&ibds, sattr->sip_family);
6521015f8fffShiremath if (retval != IBT_SUCCESS) {
6522015f8fffShiremath IBTF_DPRINTF_L2(cmlog, "ibt_get_src_ip: ibcm_arp_get_ibds "
6523015f8fffShiremath "failed to get IBD Instances: ret 0x%x", retval);
6524015f8fffShiremath goto get_src_ip_end;
6525015f8fffShiremath }
6526015f8fffShiremath
652717a2b317SBill Taylor count = 0;
6528015f8fffShiremath for (i = 0, ipp = ibds.ibcm_arp_ip; i < ibds.ibcm_arp_ibd_cnt;
6529015f8fffShiremath i++, ipp++) {
65309c468ea9SPramod Gunjikar if (ipp->ip_inet_family == AF_UNSPEC)
65319c468ea9SPramod Gunjikar continue;
653217a2b317SBill Taylor if (ipp->ip_port_gid.gid_prefix == sattr->sip_gid.gid_prefix &&
653317a2b317SBill Taylor ipp->ip_port_gid.gid_guid == sattr->sip_gid.gid_guid) {
653417a2b317SBill Taylor if ((sattr->sip_pkey) &&
653517a2b317SBill Taylor (ipp->ip_pkey != sattr->sip_pkey))
6536015f8fffShiremath continue;
653717a2b317SBill Taylor
653817a2b317SBill Taylor if ((sattr->sip_zoneid != ALL_ZONES) &&
653917a2b317SBill Taylor (sattr->sip_zoneid != ipp->ip_zoneid))
654017a2b317SBill Taylor continue;
654117a2b317SBill Taylor
654217a2b317SBill Taylor count++;
6543015f8fffShiremath break;
6544015f8fffShiremath }
6545015f8fffShiremath }
6546015f8fffShiremath
654717a2b317SBill Taylor if (count) {
654817a2b317SBill Taylor /*
654917a2b317SBill Taylor * Allocate memory for return buffer, to be freed by
655017a2b317SBill Taylor * ibt_free_srcip_info().
655117a2b317SBill Taylor */
655217a2b317SBill Taylor s_ip = kmem_alloc((count * sizeof (ibt_srcip_info_t)),
655317a2b317SBill Taylor KM_SLEEP);
655417a2b317SBill Taylor
655517a2b317SBill Taylor *src_info_p = s_ip;
655617a2b317SBill Taylor *entries_p = count;
655717a2b317SBill Taylor
655817a2b317SBill Taylor j = 0;
655917a2b317SBill Taylor for (i = 0, ipp = ibds.ibcm_arp_ip; i < ibds.ibcm_arp_ibd_cnt;
656017a2b317SBill Taylor i++, ipp++) {
656117a2b317SBill Taylor if (ipp->ip_inet_family == AF_UNSPEC)
656217a2b317SBill Taylor continue;
656317a2b317SBill Taylor if ((ipp->ip_port_gid.gid_prefix ==
656417a2b317SBill Taylor sattr->sip_gid.gid_prefix) &&
656517a2b317SBill Taylor (ipp->ip_port_gid.gid_guid ==
656617a2b317SBill Taylor sattr->sip_gid.gid_guid)) {
656717a2b317SBill Taylor if ((sattr->sip_pkey) &&
656817a2b317SBill Taylor (ipp->ip_pkey != sattr->sip_pkey))
656917a2b317SBill Taylor continue;
657017a2b317SBill Taylor
657117a2b317SBill Taylor if ((sattr->sip_zoneid != ALL_ZONES) &&
657217a2b317SBill Taylor (sattr->sip_zoneid != ipp->ip_zoneid))
657317a2b317SBill Taylor continue;
657417a2b317SBill Taylor
657517a2b317SBill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*s_ip))
657617a2b317SBill Taylor s_ip[j].ip_addr.family = ipp->ip_inet_family;
657717a2b317SBill Taylor _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*s_ip))
657817a2b317SBill Taylor if (s_ip[j].ip_addr.family == AF_INET) {
657917a2b317SBill Taylor bcopy(&ipp->ip_cm_sin.sin_addr,
658017a2b317SBill Taylor &s_ip[j].ip_addr.un.ip4addr,
6581015f8fffShiremath sizeof (in_addr_t));
658217a2b317SBill Taylor } else if (s_ip[j].ip_addr.family == AF_INET6) {
658317a2b317SBill Taylor bcopy(&ipp->ip_cm_sin6.sin6_addr,
658417a2b317SBill Taylor &s_ip[j].ip_addr.un.ip6addr,
6585015f8fffShiremath sizeof (in6_addr_t));
658617a2b317SBill Taylor /* TBD: scope_id */
6587015f8fffShiremath }
658817a2b317SBill Taylor IBCM_PRINT_IP("ibt_get_src_ip",
658917a2b317SBill Taylor &s_ip[j].ip_addr);
659017a2b317SBill Taylor j++;
659117a2b317SBill Taylor }
659217a2b317SBill Taylor }
659317a2b317SBill Taylor } else {
659417a2b317SBill Taylor retval = IBT_SRC_IP_NOT_FOUND;
6595015f8fffShiremath }
6596015f8fffShiremath
6597015f8fffShiremath get_src_ip_end:
65981cfa752fSRamaswamy Tummala ibcm_arp_free_ibds(&ibds);
6599015f8fffShiremath return (retval);
6600015f8fffShiremath }
6601015f8fffShiremath
660217a2b317SBill Taylor /*
660317a2b317SBill Taylor * ibt_free_srcip_info()
660417a2b317SBill Taylor * Free the memory allocated by successful ibt_get_src_ip()
660517a2b317SBill Taylor *
660617a2b317SBill Taylor * src_info Pointer returned by ibt_get_src_ip().
660717a2b317SBill Taylor *
660817a2b317SBill Taylor * entries The number of ibt_ip_addr_t entries to free.
660917a2b317SBill Taylor */
661017a2b317SBill Taylor void
ibt_free_srcip_info(ibt_srcip_info_t * src_info,uint_t entries)661117a2b317SBill Taylor ibt_free_srcip_info(ibt_srcip_info_t *src_info, uint_t entries)
661217a2b317SBill Taylor {
661317a2b317SBill Taylor IBTF_DPRINTF_L3(cmlog, "ibt_free_srcip_info: "
661417a2b317SBill Taylor "Free <%d> entries from 0x%p", entries, src_info);
661517a2b317SBill Taylor
661617a2b317SBill Taylor if ((src_info != NULL) && (entries > 0))
661717a2b317SBill Taylor kmem_free(src_info, entries * sizeof (ibt_srcip_info_t));
661817a2b317SBill Taylor else
661917a2b317SBill Taylor IBTF_DPRINTF_L2(cmlog, "ibt_free_srcip_info: "
662017a2b317SBill Taylor "ERROR: NULL buf pointer or ZERO length specified.");
662117a2b317SBill Taylor }
662217a2b317SBill Taylor
662317a2b317SBill Taylor
6624015f8fffShiremath ib_svc_id_t
ibt_get_ip_sid(uint8_t protocol_num,in_port_t dst_port)6625015f8fffShiremath ibt_get_ip_sid(uint8_t protocol_num, in_port_t dst_port)
6626015f8fffShiremath {
6627015f8fffShiremath ib_svc_id_t sid;
6628015f8fffShiremath
6629015f8fffShiremath IBTF_DPRINTF_L4(cmlog, "ibt_get_ip_sid(%X, %lX)", protocol_num,
6630015f8fffShiremath dst_port);
6631015f8fffShiremath
6632015f8fffShiremath /*
6633015f8fffShiremath * If protocol_num is non-zero, then formulate the SID and return it.
6634015f8fffShiremath * If protocol_num is zero, then we need to assign a locally generated
6635015f8fffShiremath * IP SID with IB_SID_IPADDR_PREFIX.
6636015f8fffShiremath */
6637015f8fffShiremath if (protocol_num) {
6638015f8fffShiremath sid = IB_SID_IPADDR_PREFIX | protocol_num << 16 | dst_port;
6639015f8fffShiremath } else {
6640015f8fffShiremath sid = ibcm_alloc_ip_sid();
6641015f8fffShiremath }
6642015f8fffShiremath
6643015f8fffShiremath IBTF_DPRINTF_L3(cmlog, "ibt_get_ip_sid: SID: 0x%016llX", sid);
6644015f8fffShiremath return (sid);
6645015f8fffShiremath }
6646015f8fffShiremath
6647015f8fffShiremath ibt_status_t
ibt_release_ip_sid(ib_svc_id_t ip_sid)6648015f8fffShiremath ibt_release_ip_sid(ib_svc_id_t ip_sid)
6649015f8fffShiremath {
6650015f8fffShiremath IBTF_DPRINTF_L4(cmlog, "ibt_release_ip_sid(%llX)", ip_sid);
6651015f8fffShiremath
6652015f8fffShiremath if (((ip_sid & IB_SID_IPADDR_PREFIX_MASK) != 0) ||
6653015f8fffShiremath (!(ip_sid & IB_SID_IPADDR_PREFIX))) {
6654015f8fffShiremath IBTF_DPRINTF_L2(cmlog, "ibt_release_ip_sid(0x%016llX): ERROR: "
6655015f8fffShiremath "Called for Non-RDMA IP SID", ip_sid);
6656015f8fffShiremath return (IBT_INVALID_PARAM);
6657015f8fffShiremath }
6658015f8fffShiremath
6659015f8fffShiremath /*
6660015f8fffShiremath * If protocol_num in ip_sid are all ZEROs, then this SID is allocated
6661015f8fffShiremath * by IBTF. If not, then the specified ip_sid is invalid.
6662015f8fffShiremath */
6663015f8fffShiremath if (ip_sid & IB_SID_IPADDR_IPNUM_MASK) {
6664015f8fffShiremath IBTF_DPRINTF_L2(cmlog, "ibt_release_ip_sid(0x%016llX): ERROR: "
6665015f8fffShiremath "Called for Non-IBTF assigned RDMA IP SID", ip_sid);
6666015f8fffShiremath return (IBT_INVALID_PARAM);
6667015f8fffShiremath }
6668015f8fffShiremath
6669015f8fffShiremath ibcm_free_ip_sid(ip_sid);
6670015f8fffShiremath
6671015f8fffShiremath return (IBT_SUCCESS);
6672015f8fffShiremath }
6673015f8fffShiremath
6674015f8fffShiremath
6675015f8fffShiremath uint8_t
ibt_get_ip_protocol_num(ib_svc_id_t sid)6676015f8fffShiremath ibt_get_ip_protocol_num(ib_svc_id_t sid)
6677015f8fffShiremath {
6678015f8fffShiremath return ((sid & IB_SID_IPADDR_IPNUM_MASK) >> 16);
6679015f8fffShiremath }
6680015f8fffShiremath
6681015f8fffShiremath in_port_t
ibt_get_ip_dst_port(ib_svc_id_t sid)6682015f8fffShiremath ibt_get_ip_dst_port(ib_svc_id_t sid)
6683015f8fffShiremath {
6684015f8fffShiremath return (sid & IB_SID_IPADDR_PORTNUM_MASK);
6685015f8fffShiremath }
6686015f8fffShiremath
6687015f8fffShiremath _NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibt_ip_cm_info_t))
6688015f8fffShiremath _NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibcm_ip_pvtdata_t))
6689015f8fffShiremath
6690015f8fffShiremath ibt_status_t
ibt_format_ip_private_data(ibt_ip_cm_info_t * ip_cm_info,ibt_priv_data_len_t priv_data_len,void * priv_data_p)6691015f8fffShiremath ibt_format_ip_private_data(ibt_ip_cm_info_t *ip_cm_info,
6692015f8fffShiremath ibt_priv_data_len_t priv_data_len, void *priv_data_p)
6693015f8fffShiremath {
66947fce3d37Shiremath ibcm_ip_pvtdata_t ip_data;
6695015f8fffShiremath
6696015f8fffShiremath IBTF_DPRINTF_L4(cmlog, "ibt_format_ip_private_data(%p, %d, %p)",
6697015f8fffShiremath ip_cm_info, priv_data_len, priv_data_p);
6698015f8fffShiremath
6699015f8fffShiremath if ((ip_cm_info == NULL) || (priv_data_p == NULL) ||
6700015f8fffShiremath (priv_data_len < IBT_IP_HDR_PRIV_DATA_SZ)) {
6701015f8fffShiremath IBTF_DPRINTF_L2(cmlog, "ibt_format_ip_private_data: ERROR "
6702015f8fffShiremath "Invalid Inputs.");
6703015f8fffShiremath return (IBT_INVALID_PARAM);
6704015f8fffShiremath }
6705015f8fffShiremath
67067fce3d37Shiremath bzero(&ip_data, sizeof (ibcm_ip_pvtdata_t));
67077fce3d37Shiremath ip_data.ip_srcport = ip_cm_info->src_port; /* Source Port */
6708015f8fffShiremath
6709d3a82192SShantkumar Hiremath IBCM_PRINT_IP("format_ip_pvt: src", &ip_cm_info->src_addr);
6710d3a82192SShantkumar Hiremath IBCM_PRINT_IP("format_ip_pvt: dst", &ip_cm_info->dst_addr);
6711015f8fffShiremath /* IPV = 0x4, if IP-Addr are IPv4 format, else 0x6 for IPv6 */
6712015f8fffShiremath if (ip_cm_info->src_addr.family == AF_INET) {
67137fce3d37Shiremath ip_data.ip_ipv = IBT_CM_IP_IPV_V4;
67147fce3d37Shiremath ip_data.ip_srcv4 = ip_cm_info->src_addr.un.ip4addr;
67157fce3d37Shiremath ip_data.ip_dstv4 = ip_cm_info->dst_addr.un.ip4addr;
6716015f8fffShiremath } else if (ip_cm_info->src_addr.family == AF_INET6) {
67177fce3d37Shiremath ip_data.ip_ipv = IBT_CM_IP_IPV_V6;
6718015f8fffShiremath bcopy(&ip_cm_info->src_addr.un.ip6addr,
67197fce3d37Shiremath &ip_data.ip_srcv6, sizeof (in6_addr_t));
6720015f8fffShiremath bcopy(&ip_cm_info->dst_addr.un.ip6addr,
67217fce3d37Shiremath &ip_data.ip_dstv6, sizeof (in6_addr_t));
6722015f8fffShiremath } else {
6723015f8fffShiremath IBTF_DPRINTF_L2(cmlog, "ibt_format_ip_private_data: ERROR "
6724015f8fffShiremath "IP Addr needs to be either AF_INET or AF_INET6 family.");
6725015f8fffShiremath return (IBT_INVALID_PARAM);
6726015f8fffShiremath }
6727015f8fffShiremath
67287fce3d37Shiremath ip_data.ip_MajV = IBT_CM_IP_MAJ_VER;
67297fce3d37Shiremath ip_data.ip_MinV = IBT_CM_IP_MIN_VER;
67307fce3d37Shiremath
67317fce3d37Shiremath bcopy(&ip_data, priv_data_p, IBT_IP_HDR_PRIV_DATA_SZ);
6732015f8fffShiremath
6733015f8fffShiremath return (IBT_SUCCESS);
6734015f8fffShiremath }
6735015f8fffShiremath
6736015f8fffShiremath
6737015f8fffShiremath ibt_status_t
ibt_get_ip_data(ibt_priv_data_len_t priv_data_len,void * priv_data,ibt_ip_cm_info_t * ip_cm_infop)6738015f8fffShiremath ibt_get_ip_data(ibt_priv_data_len_t priv_data_len, void *priv_data,
6739015f8fffShiremath ibt_ip_cm_info_t *ip_cm_infop)
6740015f8fffShiremath {
67417fce3d37Shiremath ibcm_ip_pvtdata_t ip_data;
6742015f8fffShiremath
6743015f8fffShiremath IBTF_DPRINTF_L4(cmlog, "ibt_get_ip_data(%d, %p, %p)",
6744015f8fffShiremath priv_data_len, priv_data, ip_cm_infop);
6745015f8fffShiremath
6746015f8fffShiremath if ((ip_cm_infop == NULL) || (priv_data == NULL) ||
6747015f8fffShiremath (priv_data_len < IBT_IP_HDR_PRIV_DATA_SZ)) {
6748015f8fffShiremath IBTF_DPRINTF_L2(cmlog, "ibt_get_ip_data: ERROR Invalid Inputs");
6749015f8fffShiremath return (IBT_INVALID_PARAM);
6750015f8fffShiremath }
6751015f8fffShiremath
67527fce3d37Shiremath bcopy(priv_data, &ip_data, IBT_IP_HDR_PRIV_DATA_SZ);
67537fce3d37Shiremath ip_cm_infop->src_port = ip_data.ip_srcport; /* Source Port */
6754015f8fffShiremath
6755015f8fffShiremath /* IPV = 0x4, if IP Address are IPv4 format, else 0x6 for IPv6 */
67567fce3d37Shiremath if (ip_data.ip_ipv == IBT_CM_IP_IPV_V4) {
6757015f8fffShiremath /* Copy IPv4 Addr */
6758d3a82192SShantkumar Hiremath ip_cm_infop->src_addr.family = ip_cm_infop->dst_addr.family =
6759d3a82192SShantkumar Hiremath AF_INET;
67607fce3d37Shiremath ip_cm_infop->src_addr.un.ip4addr = ip_data.ip_srcv4;
67617fce3d37Shiremath ip_cm_infop->dst_addr.un.ip4addr = ip_data.ip_dstv4;
67627fce3d37Shiremath } else if (ip_data.ip_ipv == IBT_CM_IP_IPV_V6) {
6763015f8fffShiremath /* Copy IPv6 Addr */
6764d3a82192SShantkumar Hiremath ip_cm_infop->src_addr.family = ip_cm_infop->dst_addr.family =
6765d3a82192SShantkumar Hiremath AF_INET6;
67667fce3d37Shiremath bcopy(&ip_data.ip_srcv6, &ip_cm_infop->src_addr.un.ip6addr,
6767015f8fffShiremath sizeof (in6_addr_t));
67687fce3d37Shiremath bcopy(&ip_data.ip_dstv6, &ip_cm_infop->dst_addr.un.ip6addr,
6769015f8fffShiremath sizeof (in6_addr_t));
6770015f8fffShiremath } else {
6771015f8fffShiremath IBTF_DPRINTF_L2(cmlog, "ibt_get_ip_data: ERROR: IP Addr needs"
6772015f8fffShiremath " to be either AF_INET or AF_INET6 family.");
6773015f8fffShiremath return (IBT_INVALID_PARAM);
6774015f8fffShiremath }
6775d3a82192SShantkumar Hiremath IBCM_PRINT_IP("ibt_get_ip_data: src", &ip_cm_infop->src_addr);
6776d3a82192SShantkumar Hiremath IBCM_PRINT_IP("ibt_get_ip_data: dst", &ip_cm_infop->dst_addr);
6777015f8fffShiremath
6778015f8fffShiremath return (IBT_SUCCESS);
6779015f8fffShiremath }
6780015f8fffShiremath
67817c478bd9Sstevel@tonic-gate
67827c478bd9Sstevel@tonic-gate /* Routines for warlock */
67837c478bd9Sstevel@tonic-gate
67847c478bd9Sstevel@tonic-gate /* ARGSUSED */
67857c478bd9Sstevel@tonic-gate static void
ibcm_dummy_mcg_handler(void * arg,ibt_status_t retval,ibt_mcg_info_t * minfo)67867c478bd9Sstevel@tonic-gate ibcm_dummy_mcg_handler(void *arg, ibt_status_t retval, ibt_mcg_info_t *minfo)
67877c478bd9Sstevel@tonic-gate {
67887c478bd9Sstevel@tonic-gate ibcm_join_mcg_tqarg_t dummy_mcg;
67897c478bd9Sstevel@tonic-gate
67907c478bd9Sstevel@tonic-gate dummy_mcg.func = ibcm_dummy_mcg_handler;
67917c478bd9Sstevel@tonic-gate
67927c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_dummy_mcg_handler: "
67937c478bd9Sstevel@tonic-gate "dummy_mcg.func %p", dummy_mcg.func);
67947c478bd9Sstevel@tonic-gate }
67957c478bd9Sstevel@tonic-gate
67967c478bd9Sstevel@tonic-gate
67977c478bd9Sstevel@tonic-gate /* ARGSUSED */
67987c478bd9Sstevel@tonic-gate static void
ibcm_dummy_recycle_rc_handler(ibt_status_t retval,void * arg)67997c478bd9Sstevel@tonic-gate ibcm_dummy_recycle_rc_handler(ibt_status_t retval, void *arg)
68007c478bd9Sstevel@tonic-gate {
68017c478bd9Sstevel@tonic-gate ibcm_taskq_recycle_arg_t dummy_rc_recycle;
68027c478bd9Sstevel@tonic-gate
68037c478bd9Sstevel@tonic-gate dummy_rc_recycle.func = ibcm_dummy_recycle_rc_handler;
68047c478bd9Sstevel@tonic-gate
68057c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_dummy_recycle_rc_handler: "
68067c478bd9Sstevel@tonic-gate "dummy_rc_recycle.func %p", dummy_rc_recycle.func);
68077c478bd9Sstevel@tonic-gate }
68087c478bd9Sstevel@tonic-gate
68097c478bd9Sstevel@tonic-gate
68107c478bd9Sstevel@tonic-gate /* ARGSUSED */
68117c478bd9Sstevel@tonic-gate static ibt_cm_status_t
ibcm_dummy_ud_handler(void * priv,ibt_cm_ud_event_t * event,ibt_cm_ud_return_args_t * ret_args,void * priv_data,ibt_priv_data_len_t len)68127c478bd9Sstevel@tonic-gate ibcm_dummy_ud_handler(void *priv, ibt_cm_ud_event_t *event,
68137c478bd9Sstevel@tonic-gate ibt_cm_ud_return_args_t *ret_args,
68147c478bd9Sstevel@tonic-gate void *priv_data, ibt_priv_data_len_t len)
68157c478bd9Sstevel@tonic-gate {
68167c478bd9Sstevel@tonic-gate /*
68177c478bd9Sstevel@tonic-gate * Let warlock see that ibcm_local_handler_s::actual_cm_handler
68187c478bd9Sstevel@tonic-gate * points to this routine.
68197c478bd9Sstevel@tonic-gate */
68207c478bd9Sstevel@tonic-gate ibcm_local_handler_t p;
68217c478bd9Sstevel@tonic-gate ibcm_ud_state_data_t dummy_ud;
68227c478bd9Sstevel@tonic-gate
68237c478bd9Sstevel@tonic-gate p.actual_cm_handler = ibcm_dummy_ud_handler;
68247c478bd9Sstevel@tonic-gate dummy_ud.ud_cm_handler = ibcm_dummy_ud_handler;
68257c478bd9Sstevel@tonic-gate
68267c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_dummy_ud_handler: p.actual_cm_handler %p"
68277c478bd9Sstevel@tonic-gate "dummy_ud.ud_cm_handler %p", p.actual_cm_handler,
68287c478bd9Sstevel@tonic-gate dummy_ud.ud_cm_handler);
68297c478bd9Sstevel@tonic-gate /*
68307c478bd9Sstevel@tonic-gate * Call all routines that the client's callback routine could call.
68317c478bd9Sstevel@tonic-gate */
68327c478bd9Sstevel@tonic-gate
68337c478bd9Sstevel@tonic-gate return (IBT_CM_ACCEPT);
68347c478bd9Sstevel@tonic-gate }
68357c478bd9Sstevel@tonic-gate
68367c478bd9Sstevel@tonic-gate /* ARGSUSED */
68377c478bd9Sstevel@tonic-gate static ibt_cm_status_t
ibcm_dummy_rc_handler(void * priv,ibt_cm_event_t * event,ibt_cm_return_args_t * ret_args,void * priv_data,ibt_priv_data_len_t len)68387c478bd9Sstevel@tonic-gate ibcm_dummy_rc_handler(void *priv, ibt_cm_event_t *event,
68397c478bd9Sstevel@tonic-gate ibt_cm_return_args_t *ret_args, void *priv_data, ibt_priv_data_len_t len)
68407c478bd9Sstevel@tonic-gate {
68417c478bd9Sstevel@tonic-gate ibcm_state_data_t dummy_rc;
68427c478bd9Sstevel@tonic-gate
68437c478bd9Sstevel@tonic-gate dummy_rc.cm_handler = ibcm_dummy_rc_handler;
68447c478bd9Sstevel@tonic-gate
68457c478bd9Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_dummy_rc_handler: "
68467c478bd9Sstevel@tonic-gate "dummy_ud.ud_cm_handler %p", dummy_rc.cm_handler);
68477c478bd9Sstevel@tonic-gate /*
68487c478bd9Sstevel@tonic-gate * Call all routines that the client's callback routine could call.
68497c478bd9Sstevel@tonic-gate */
68507c478bd9Sstevel@tonic-gate
68517c478bd9Sstevel@tonic-gate return (IBT_CM_ACCEPT);
68527c478bd9Sstevel@tonic-gate }
6853