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
5015f8fffShiremath  * Common Development and Distribution License (the "License").
6015f8fffShiremath  * 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 /*
22ae0581d1SShantkumar Hiremath  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate  * ibcm_utils.c
287c478bd9Sstevel@tonic-gate  *
297c478bd9Sstevel@tonic-gate  * contains internal lookup functions of IB CM module
307c478bd9Sstevel@tonic-gate  * along with some other miscellaneous stuff
317c478bd9Sstevel@tonic-gate  *
327c478bd9Sstevel@tonic-gate  * TBD:
337c478bd9Sstevel@tonic-gate  * 1. Code needed to ensure that if any clients are using a service then
347c478bd9Sstevel@tonic-gate  * don't de-register it.
357c478bd9Sstevel@tonic-gate  */
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #include <sys/ib/mgt/ibcm/ibcm_impl.h>
387c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /* statics */
427c478bd9Sstevel@tonic-gate static vmem_t		*ibcm_local_sid_arena;
43015f8fffShiremath static vmem_t		*ibcm_ip_sid_arena;
447c478bd9Sstevel@tonic-gate static ib_svc_id_t	ibcm_local_sid_seed;
457c478bd9Sstevel@tonic-gate static ib_com_id_t	ibcm_local_cid_seed;
467c478bd9Sstevel@tonic-gate _NOTE(READ_ONLY_DATA({ibcm_local_sid_arena ibcm_local_sid_seed
47015f8fffShiremath     ibcm_ip_sid_arena ibcm_local_cid_seed}))
487c478bd9Sstevel@tonic-gate static void		ibcm_delete_state_from_avl(ibcm_state_data_t *statep);
497c478bd9Sstevel@tonic-gate static void		ibcm_init_conn_trace(ibcm_state_data_t *statep);
507c478bd9Sstevel@tonic-gate static void		ibcm_fini_conn_trace(ibcm_state_data_t *statep);
517c478bd9Sstevel@tonic-gate static void		ibcm_dump_conn_trbuf(void *statep, char *line_prefix,
527c478bd9Sstevel@tonic-gate 			    char *buf, int buf_size);
53*76c04273SRajkumar Sivaprakasam extern ibt_status_t	ibcm_get_node_rec(ibmf_saa_handle_t, sa_node_record_t *,
54*76c04273SRajkumar Sivaprakasam 			    uint64_t c_mask, void *, size_t *);
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate /*
577c478bd9Sstevel@tonic-gate  * ibcm_lookup_msg:
587c478bd9Sstevel@tonic-gate  *
597c478bd9Sstevel@tonic-gate  * Retrieves an existing state structure or creates a new one if none found.
607c478bd9Sstevel@tonic-gate  * This function is used during
617c478bd9Sstevel@tonic-gate  *	Passive connection side for INCOMING REQ/REJ/RTU/MRA/DREQ/DREP/LAP msgs
627c478bd9Sstevel@tonic-gate  *	Active connection side for INCOMING REP/REJ/MRA/DREQ/DREP/APR msgs
637c478bd9Sstevel@tonic-gate  *	Active side CM for outgoing REQ message.
647c478bd9Sstevel@tonic-gate  *
657c478bd9Sstevel@tonic-gate  * NOTE: Only return IBCM_LOOKUP_FAIL if lookup failed to find a match.
667c478bd9Sstevel@tonic-gate  *
677c478bd9Sstevel@tonic-gate  * Arguments are:-
687c478bd9Sstevel@tonic-gate  *	event_type	- type of message
697c478bd9Sstevel@tonic-gate  *			incoming REQ, REP, REJ, MRA, RTU
707c478bd9Sstevel@tonic-gate  *	remote_qpn	- Remote QP number
717c478bd9Sstevel@tonic-gate  *	comid		- local/remote comid
727c478bd9Sstevel@tonic-gate  *	remote_hca_guid	- Remote HCA GUID
737c478bd9Sstevel@tonic-gate  *	hcap		- HCA entry ptr
747c478bd9Sstevel@tonic-gate  *	rstatep		- return statep pointer
757c478bd9Sstevel@tonic-gate  *
767c478bd9Sstevel@tonic-gate  * Return Values:
777c478bd9Sstevel@tonic-gate  *	IBCM_LOOKUP_NEW		- new statep allocated
787c478bd9Sstevel@tonic-gate  *	IBCM_LOOKUP_EXISTS	- found an existing entry
797c478bd9Sstevel@tonic-gate  *	IBCM_LOOKUP_FAIL	- No lookup entry found
807c478bd9Sstevel@tonic-gate  *	IBCM_MEMORY_FAILURE	- Memory allocs failed
817c478bd9Sstevel@tonic-gate  */
827c478bd9Sstevel@tonic-gate ibcm_status_t
ibcm_lookup_msg(ibcm_event_type_t event_type,ib_com_id_t comid,ib_qpn_t remote_qpn,ib_guid_t remote_hca_guid,ibcm_hca_info_t * hcap,ibcm_state_data_t ** rstatep)837c478bd9Sstevel@tonic-gate ibcm_lookup_msg(ibcm_event_type_t event_type, ib_com_id_t comid,
847c478bd9Sstevel@tonic-gate     ib_qpn_t remote_qpn, ib_guid_t remote_hca_guid, ibcm_hca_info_t *hcap,
857c478bd9Sstevel@tonic-gate     ibcm_state_data_t **rstatep)
867c478bd9Sstevel@tonic-gate {
877c478bd9Sstevel@tonic-gate 	avl_index_t		where;
887c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*sp;
897c478bd9Sstevel@tonic-gate 
909d3d2ed0Shiremath 	IBTF_DPRINTF_L4(cmlog, "ibcm_lookup_msg: event = 0x%x, comid = 0x%x",
917c478bd9Sstevel@tonic-gate 	    event_type, comid);
927c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_lookup_msg: rem_qpn = 0x%lX, "
937c478bd9Sstevel@tonic-gate 	    "rem_hca_guid = 0x%llX", remote_qpn, remote_hca_guid);
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate 	ASSERT(rw_lock_held(&hcap->hca_state_rwlock));
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate 	/*
987c478bd9Sstevel@tonic-gate 	 * Lookup in "hca_passive_tree" for IBCM_INCOMING_REQ and
997c478bd9Sstevel@tonic-gate 	 * IBCM_INCOMING_REP_STALE;
1007c478bd9Sstevel@tonic-gate 	 *
1017c478bd9Sstevel@tonic-gate 	 * Lookup in "hca_passive_comid_tree" for IBCM_INCOMING_REQ_STALE
1027c478bd9Sstevel@tonic-gate 	 *
1037c478bd9Sstevel@tonic-gate 	 * All other lookups in "hca_active_tree".
1047c478bd9Sstevel@tonic-gate 	 *
1057c478bd9Sstevel@tonic-gate 	 * NOTE: "hca_active_tree" lookups are based on the local comid.
1067c478bd9Sstevel@tonic-gate 	 * "hca_passive_state_tree" lookups are based on remote QPN
1077c478bd9Sstevel@tonic-gate 	 * and remote hca GUID.
1087c478bd9Sstevel@tonic-gate 	 *
1097c478bd9Sstevel@tonic-gate 	 * Call avl_find to lookup in the respective tree and save result in
1107c478bd9Sstevel@tonic-gate 	 * "sp". If "sp" is null it implies that no match was found. If so,
1117c478bd9Sstevel@tonic-gate 	 * allocate a new ibcm_state_data_t and insert it into the AVL tree(s).
1127c478bd9Sstevel@tonic-gate 	 */
1137c478bd9Sstevel@tonic-gate 	if ((event_type == IBCM_INCOMING_REQ) ||
1147c478bd9Sstevel@tonic-gate 	    (event_type == IBCM_INCOMING_REP_STALE)) {
1157c478bd9Sstevel@tonic-gate 		ibcm_passive_node_info_t	info;
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate 		info.info_qpn = remote_qpn;
1187c478bd9Sstevel@tonic-gate 		info.info_hca_guid = remote_hca_guid;
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate 		/* Lookup based on Remote QPN and Remote GUID in Passive Tree */
1217c478bd9Sstevel@tonic-gate 		sp = avl_find(&hcap->hca_passive_tree, &info, &where);
1227c478bd9Sstevel@tonic-gate 	} else if ((event_type == IBCM_INCOMING_REQ_STALE) ||
1237c478bd9Sstevel@tonic-gate 	    (event_type == IBCM_INCOMING_REJ_RCOMID)) {
1247c478bd9Sstevel@tonic-gate 		ibcm_passive_comid_node_info_t	info;
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate 		info.info_comid = comid;
1277c478bd9Sstevel@tonic-gate 		info.info_hca_guid = remote_hca_guid;
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 		/* Lookup based on Remote COMID in Passive Tree */
1307c478bd9Sstevel@tonic-gate 		sp = avl_find(&hcap->hca_passive_comid_tree, &info, &where);
1317c478bd9Sstevel@tonic-gate 	} else {	/* any other event including IBCM_OUTGOING_REQ */
1327c478bd9Sstevel@tonic-gate 		/* Lookup based on Local comid in Active Tree */
1337c478bd9Sstevel@tonic-gate 		sp = avl_find(&hcap->hca_active_tree, &comid, &where);
1347c478bd9Sstevel@tonic-gate 	}
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 	/* matching entry found !! */
1377c478bd9Sstevel@tonic-gate 	if (sp != NULL) {
1387c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_lookup_msg: match found "
1397c478bd9Sstevel@tonic-gate 		    "statep = %p", sp);
1407c478bd9Sstevel@tonic-gate 		if (event_type == IBCM_INCOMING_REQ)
1417c478bd9Sstevel@tonic-gate 			kmem_free(*rstatep, sizeof (ibcm_state_data_t));
1427c478bd9Sstevel@tonic-gate 		*rstatep = sp;		/* return the matched statep */
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate 		mutex_enter(&(sp->state_mutex));
1457c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_INCR(sp); /* increment the ref count */
1467c478bd9Sstevel@tonic-gate 		mutex_exit(&(sp->state_mutex));
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate 		return (IBCM_LOOKUP_EXISTS);
1497c478bd9Sstevel@tonic-gate 	}
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate 	/*
1527c478bd9Sstevel@tonic-gate 	 * If we came here then it implies that CM didn't
1537c478bd9Sstevel@tonic-gate 	 * find a matching entry. We will create a new entry in avl tree,
1547c478bd9Sstevel@tonic-gate 	 * if event_type is INCOMING/OUTGOING REQ, REQ_STALE/REP_STALE.
1557c478bd9Sstevel@tonic-gate 	 * statep is created for INCOMING/OUTGOING REQ.
1567c478bd9Sstevel@tonic-gate 	 * For all other event_types we return lookup failure
1577c478bd9Sstevel@tonic-gate 	 */
1587c478bd9Sstevel@tonic-gate 	if (!((event_type == IBCM_INCOMING_REQ) ||
1597c478bd9Sstevel@tonic-gate 	    (event_type == IBCM_INCOMING_REQ_STALE) ||
1607c478bd9Sstevel@tonic-gate 	    (event_type == IBCM_INCOMING_REP_STALE) ||
1617c478bd9Sstevel@tonic-gate 	    (event_type == IBCM_OUTGOING_REQ))) {
1627c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_lookup_msg: failed for "
1639d3d2ed0Shiremath 		    "event type %x remote_comid = 0x%x",
1649d3d2ed0Shiremath 		    event_type, comid);
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate 		return (IBCM_LOOKUP_FAIL);
1677c478bd9Sstevel@tonic-gate 	}
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 	if ((event_type == IBCM_INCOMING_REQ) ||
1707c478bd9Sstevel@tonic-gate 	    (event_type == IBCM_OUTGOING_REQ)) {
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate 		/* fill in the new ibcm_state_data */
1737c478bd9Sstevel@tonic-gate 		sp = *rstatep;
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate 		_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sp))
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 		/* initialize statep */
1787c478bd9Sstevel@tonic-gate 		mutex_init(&sp->state_mutex, NULL, MUTEX_DEFAULT, NULL);
1797c478bd9Sstevel@tonic-gate 		cv_init(&sp->block_client_cv, NULL, CV_DRIVER, NULL);
1807c478bd9Sstevel@tonic-gate 		cv_init(&sp->block_mad_cv, NULL, CV_DRIVER, NULL);
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate 		sp->hcap = hcap;
1837c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_INCR(sp);
1847c478bd9Sstevel@tonic-gate 		sp->local_comid = comid;
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate 		if (ibcm_enable_trace != 0)
1877c478bd9Sstevel@tonic-gate 			ibcm_init_conn_trace(sp);
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate 		if (event_type == IBCM_INCOMING_REQ) {	/* Passive side */
1907c478bd9Sstevel@tonic-gate 			sp->state = IBCM_STATE_REQ_RCVD;
1917c478bd9Sstevel@tonic-gate 			sp->clnt_proceed = IBCM_BLOCK;
1927c478bd9Sstevel@tonic-gate 			sp->close_nocb_state = IBCM_UNBLOCK;
1937c478bd9Sstevel@tonic-gate 			sp->remote_hca_guid = remote_hca_guid;
1947c478bd9Sstevel@tonic-gate 			sp->remote_qpn = remote_qpn;
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate 		} else if (event_type == IBCM_OUTGOING_REQ) { /* Active side */
1977c478bd9Sstevel@tonic-gate 			sp->close_nocb_state = IBCM_UNBLOCK;
1987c478bd9Sstevel@tonic-gate 			sp->state = IBCM_STATE_IDLE;
1997c478bd9Sstevel@tonic-gate 		}
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate 		_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*sp))
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	} else {
2047c478bd9Sstevel@tonic-gate 		sp = *rstatep;	/* for incoming REQ/REP STALE only */
2057c478bd9Sstevel@tonic-gate 	}
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	if ((event_type == IBCM_INCOMING_REQ) ||
2087c478bd9Sstevel@tonic-gate 	    (event_type == IBCM_INCOMING_REP_STALE)) {
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate 		/* First, insert a new "sp" into "hca_passive_tree" @ "where" */
2117c478bd9Sstevel@tonic-gate 		avl_insert(&(hcap->hca_passive_tree), (void *)sp, where);
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate 		if (event_type == IBCM_INCOMING_REQ) {	/* Only INCOMING_REQ */
2147c478bd9Sstevel@tonic-gate 			/*
2157c478bd9Sstevel@tonic-gate 			 * We have to do an avl_find() to figure out
2167c478bd9Sstevel@tonic-gate 			 * "where" to insert the statep into the active tree.
2177c478bd9Sstevel@tonic-gate 			 *
2187c478bd9Sstevel@tonic-gate 			 * CM doesn't care for avl_find's retval.
2197c478bd9Sstevel@tonic-gate 			 */
2207c478bd9Sstevel@tonic-gate 			(void) avl_find(&hcap->hca_active_tree,
2217c478bd9Sstevel@tonic-gate 			    &sp->local_comid, &where);
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate 			/* Next, insert the "sp" into "hca_active_tree" */
2247c478bd9Sstevel@tonic-gate 			avl_insert(&hcap->hca_active_tree, (void *)sp, where);
2257c478bd9Sstevel@tonic-gate 		}
2267c478bd9Sstevel@tonic-gate 	} else if (event_type == IBCM_INCOMING_REQ_STALE) {
2277c478bd9Sstevel@tonic-gate 		avl_insert(&(hcap->hca_passive_comid_tree), (void *)sp, where);
2287c478bd9Sstevel@tonic-gate 	} else {	/* IBCM_OUTGOING_REQ */
2297c478bd9Sstevel@tonic-gate 		/* Insert the new sp only into "hca_active_tree", @ "where" */
2307c478bd9Sstevel@tonic-gate 		avl_insert(&(hcap->hca_active_tree), (void *)sp, where);
2317c478bd9Sstevel@tonic-gate 	}
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate 	return (IBCM_LOOKUP_NEW);	/* return new lookup */
2347c478bd9Sstevel@tonic-gate }
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate /*
2387c478bd9Sstevel@tonic-gate  * ibcm_active_node_compare:
2397c478bd9Sstevel@tonic-gate  * 	- AVL active tree node compare
2407c478bd9Sstevel@tonic-gate  *
2417c478bd9Sstevel@tonic-gate  * Arguments:
2427c478bd9Sstevel@tonic-gate  *	p1	: pointer to local comid
2437c478bd9Sstevel@tonic-gate  *	p2	: pointer to passed ibcm_state_data_t
2447c478bd9Sstevel@tonic-gate  *
2457c478bd9Sstevel@tonic-gate  * Return values:
2467c478bd9Sstevel@tonic-gate  *	0	: match found
2477c478bd9Sstevel@tonic-gate  *	-1	: no match but insert to left side of the tree
2487c478bd9Sstevel@tonic-gate  *	+1	: no match but insert to right side of the tree
2497c478bd9Sstevel@tonic-gate  */
2507c478bd9Sstevel@tonic-gate int
ibcm_active_node_compare(const void * p1,const void * p2)2517c478bd9Sstevel@tonic-gate ibcm_active_node_compare(const void *p1, const void *p2)
2527c478bd9Sstevel@tonic-gate {
2537c478bd9Sstevel@tonic-gate 	ib_com_id_t		*local_comid = (ib_com_id_t *)p1;
2547c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = (ibcm_state_data_t *)p2;
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_active_node_compare: "
2577c478bd9Sstevel@tonic-gate 	    "comid: 0x%x, statep: 0x%p", *local_comid, statep);
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate 	if (*local_comid > statep->local_comid) {
2607c478bd9Sstevel@tonic-gate 		return (+1);
2617c478bd9Sstevel@tonic-gate 	} else if (*local_comid < statep->local_comid) {
2627c478bd9Sstevel@tonic-gate 		return (-1);
2637c478bd9Sstevel@tonic-gate 	} else {
2647c478bd9Sstevel@tonic-gate 		return (0);
2657c478bd9Sstevel@tonic-gate 	}
2667c478bd9Sstevel@tonic-gate }
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate /*
2707c478bd9Sstevel@tonic-gate  * ibcm_passive_node_compare:
2717c478bd9Sstevel@tonic-gate  * 	- AVL passive tree node compare (passive side)
2727c478bd9Sstevel@tonic-gate  *
2737c478bd9Sstevel@tonic-gate  * Arguments:
2747c478bd9Sstevel@tonic-gate  *	p1	: pointer to ibcm_passive_node_info (remote qpn and remote guid)
2757c478bd9Sstevel@tonic-gate  *	p2	: pointer to passed ibcm_state_data_t
2767c478bd9Sstevel@tonic-gate  *
2777c478bd9Sstevel@tonic-gate  * Return values:
2787c478bd9Sstevel@tonic-gate  *	0	: match found
2797c478bd9Sstevel@tonic-gate  *	-1	: no match but insert to left side of the tree
2807c478bd9Sstevel@tonic-gate  *	+1	: no match but insert to right side of the tree
2817c478bd9Sstevel@tonic-gate  */
2827c478bd9Sstevel@tonic-gate int
ibcm_passive_node_compare(const void * p1,const void * p2)2837c478bd9Sstevel@tonic-gate ibcm_passive_node_compare(const void *p1, const void *p2)
2847c478bd9Sstevel@tonic-gate {
2857c478bd9Sstevel@tonic-gate 	ibcm_state_data_t		*statep = (ibcm_state_data_t *)p2;
2867c478bd9Sstevel@tonic-gate 	ibcm_passive_node_info_t	*infop = (ibcm_passive_node_info_t *)p1;
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_passive_node_compare: "
2897c478bd9Sstevel@tonic-gate 	    "statep: 0x%p, p1: 0x%p", statep, p1);
2907c478bd9Sstevel@tonic-gate 
2917c478bd9Sstevel@tonic-gate 	/*
2927c478bd9Sstevel@tonic-gate 	 * PASSIVE SIDE: (REQ, REP, MRA, REJ)
2937c478bd9Sstevel@tonic-gate 	 *	always search by active COMID
2947c478bd9Sstevel@tonic-gate 	 */
2957c478bd9Sstevel@tonic-gate 	if (infop->info_qpn > statep->remote_qpn) {
2967c478bd9Sstevel@tonic-gate 		return (+1);
2977c478bd9Sstevel@tonic-gate 	} else if (infop->info_qpn < statep->remote_qpn) {
2987c478bd9Sstevel@tonic-gate 		return (-1);
2997c478bd9Sstevel@tonic-gate 	} else {
3007c478bd9Sstevel@tonic-gate 		if (infop->info_hca_guid < statep->remote_hca_guid) {
3017c478bd9Sstevel@tonic-gate 			return (-1);
3027c478bd9Sstevel@tonic-gate 		} else if (infop->info_hca_guid > statep->remote_hca_guid) {
3037c478bd9Sstevel@tonic-gate 			return (+1);
3047c478bd9Sstevel@tonic-gate 		} else {
3057c478bd9Sstevel@tonic-gate 			return (0);
3067c478bd9Sstevel@tonic-gate 		}
3077c478bd9Sstevel@tonic-gate 	}
3087c478bd9Sstevel@tonic-gate }
3097c478bd9Sstevel@tonic-gate 
3107c478bd9Sstevel@tonic-gate /*
3117c478bd9Sstevel@tonic-gate  * ibcm_passive_comid_node_compare:
3127c478bd9Sstevel@tonic-gate  * 	- AVL passive comid tree node compare (passive side)
3137c478bd9Sstevel@tonic-gate  *
3147c478bd9Sstevel@tonic-gate  * Arguments:
3157c478bd9Sstevel@tonic-gate  *	p1	: pointer to ibcm_passive_comid_node_info
3167c478bd9Sstevel@tonic-gate  *		  (remote comid and remote guid)
3177c478bd9Sstevel@tonic-gate  *	p2	: pointer to passed ibcm_state_data_t
3187c478bd9Sstevel@tonic-gate  *
3197c478bd9Sstevel@tonic-gate  * Return values:
3207c478bd9Sstevel@tonic-gate  *	0	: match found
3217c478bd9Sstevel@tonic-gate  *	-1	: no match but insert to left side of the tree
3227c478bd9Sstevel@tonic-gate  *	+1	: no match but insert to right side of the tree
3237c478bd9Sstevel@tonic-gate  */
3247c478bd9Sstevel@tonic-gate int
ibcm_passive_comid_node_compare(const void * p1,const void * p2)3257c478bd9Sstevel@tonic-gate ibcm_passive_comid_node_compare(const void *p1, const void *p2)
3267c478bd9Sstevel@tonic-gate {
3277c478bd9Sstevel@tonic-gate 	ibcm_state_data_t		*statep = (ibcm_state_data_t *)p2;
3287c478bd9Sstevel@tonic-gate 	ibcm_passive_comid_node_info_t	*infop =
3297c478bd9Sstevel@tonic-gate 	    (ibcm_passive_comid_node_info_t *)p1;
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_passive_comid_node_compare: "
3327c478bd9Sstevel@tonic-gate 	    "statep: 0x%p, p1: 0x%p", statep, p1);
3337c478bd9Sstevel@tonic-gate 
3347c478bd9Sstevel@tonic-gate 	if (infop->info_comid > statep->remote_comid) {
3357c478bd9Sstevel@tonic-gate 		return (+1);
3367c478bd9Sstevel@tonic-gate 	} else if (infop->info_comid < statep->remote_comid) {
3377c478bd9Sstevel@tonic-gate 		return (-1);
3387c478bd9Sstevel@tonic-gate 	} else {
3397c478bd9Sstevel@tonic-gate 		if (infop->info_hca_guid < statep->remote_hca_guid) {
3407c478bd9Sstevel@tonic-gate 			return (-1);
3417c478bd9Sstevel@tonic-gate 		} else if (infop->info_hca_guid > statep->remote_hca_guid) {
3427c478bd9Sstevel@tonic-gate 			return (+1);
3437c478bd9Sstevel@tonic-gate 		} else {
3447c478bd9Sstevel@tonic-gate 			return (0);
3457c478bd9Sstevel@tonic-gate 		}
3467c478bd9Sstevel@tonic-gate 	}
3477c478bd9Sstevel@tonic-gate }
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate void
ibcm_delete_state_from_avl(ibcm_state_data_t * statep)3517c478bd9Sstevel@tonic-gate ibcm_delete_state_from_avl(ibcm_state_data_t *statep)
3527c478bd9Sstevel@tonic-gate {
3537c478bd9Sstevel@tonic-gate 	avl_index_t			a_where = 0;
3547c478bd9Sstevel@tonic-gate 	avl_index_t			p_where = 0;
3557c478bd9Sstevel@tonic-gate 	avl_index_t			pcomid_where = 0;
3567c478bd9Sstevel@tonic-gate 	ibcm_hca_info_t			*hcap;
357015f8fffShiremath 	ibcm_state_data_t		*active_nodep, *passive_nodep;
358015f8fffShiremath 	ibcm_state_data_t		*passive_comid_nodep;
3597c478bd9Sstevel@tonic-gate 	ibcm_passive_node_info_t	info;
3607c478bd9Sstevel@tonic-gate 	ibcm_passive_comid_node_info_t	info_comid;
3617c478bd9Sstevel@tonic-gate 
3627c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_delete_state_from_avl: statep 0x%p",
3637c478bd9Sstevel@tonic-gate 	    statep);
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate 	if (statep == NULL) {
3667c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_delete_state_from_avl: statep"
3677c478bd9Sstevel@tonic-gate 		    " NULL");
3687c478bd9Sstevel@tonic-gate 		return;
3697c478bd9Sstevel@tonic-gate 	}
3707c478bd9Sstevel@tonic-gate 
3717c478bd9Sstevel@tonic-gate 	hcap = statep->hcap;
3727c478bd9Sstevel@tonic-gate 
3737c478bd9Sstevel@tonic-gate 	/*
3747c478bd9Sstevel@tonic-gate 	 * Once the avl tree lock is acquired, no other thread can increment
3757c478bd9Sstevel@tonic-gate 	 * ref cnt, until tree lock is exit'ed. Since the statep is removed
3767c478bd9Sstevel@tonic-gate 	 * from the avl's after acquiring lock below, no other thread can
3777c478bd9Sstevel@tonic-gate 	 * increment the ref cnt after acquiring the lock below
3787c478bd9Sstevel@tonic-gate 	 */
3797c478bd9Sstevel@tonic-gate 
3807c478bd9Sstevel@tonic-gate 	rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
3817c478bd9Sstevel@tonic-gate 
3827c478bd9Sstevel@tonic-gate 	/* Lookup based on Local comid in the active tree */
3837c478bd9Sstevel@tonic-gate 	active_nodep = avl_find(&hcap->hca_active_tree, &(statep->local_comid),
3847c478bd9Sstevel@tonic-gate 	    &a_where);
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate 	/* Lookup based on Remote QPN and Remote GUID in the passive tree */
3877c478bd9Sstevel@tonic-gate 	info.info_qpn = statep->remote_qpn;
3887c478bd9Sstevel@tonic-gate 	info.info_hca_guid = statep->remote_hca_guid;
3897c478bd9Sstevel@tonic-gate 	passive_nodep =  avl_find(&hcap->hca_passive_tree, &info, &p_where);
3907c478bd9Sstevel@tonic-gate 
3917c478bd9Sstevel@tonic-gate 	/* Lookup based on Remote Comid and Remote GUID in the passive tree */
3927c478bd9Sstevel@tonic-gate 	info_comid.info_comid = statep->remote_comid;
3937c478bd9Sstevel@tonic-gate 	info_comid.info_hca_guid = statep->remote_hca_guid;
3947c478bd9Sstevel@tonic-gate 	passive_comid_nodep =  avl_find(&hcap->hca_passive_comid_tree,
3957c478bd9Sstevel@tonic-gate 	    &info_comid, &pcomid_where);
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate 	/* remove it from the tree, destroy record and the nodep */
3987c478bd9Sstevel@tonic-gate 	if (active_nodep == statep) {
3997c478bd9Sstevel@tonic-gate 		avl_remove(&hcap->hca_active_tree, active_nodep);
4007c478bd9Sstevel@tonic-gate 	}
4017c478bd9Sstevel@tonic-gate 
4027c478bd9Sstevel@tonic-gate 	if (passive_nodep == statep) {
4037c478bd9Sstevel@tonic-gate 		avl_remove(&hcap->hca_passive_tree, passive_nodep);
4047c478bd9Sstevel@tonic-gate 	}
4057c478bd9Sstevel@tonic-gate 
4067c478bd9Sstevel@tonic-gate 	if (passive_comid_nodep == statep) {
4077c478bd9Sstevel@tonic-gate 		avl_remove(&hcap->hca_passive_comid_tree, passive_comid_nodep);
4087c478bd9Sstevel@tonic-gate 	}
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate 	rw_exit(&hcap->hca_state_rwlock);
4117c478bd9Sstevel@tonic-gate }
4127c478bd9Sstevel@tonic-gate 
4137c478bd9Sstevel@tonic-gate /*
4147c478bd9Sstevel@tonic-gate  * ibcm_dealloc_state_data:
4157c478bd9Sstevel@tonic-gate  *	Deallocates all buffers and the memory of state structure
4167c478bd9Sstevel@tonic-gate  * This routine can be called on statep that has ref_cnt of 0, and that is
4177c478bd9Sstevel@tonic-gate  * already deleted from the avl tree's
4187c478bd9Sstevel@tonic-gate  *
4197c478bd9Sstevel@tonic-gate  * Arguments are:-
4207c478bd9Sstevel@tonic-gate  *	statep	- statep to be deleted
4217c478bd9Sstevel@tonic-gate  *
4227c478bd9Sstevel@tonic-gate  * Return Values:	NONE
4237c478bd9Sstevel@tonic-gate  */
4247c478bd9Sstevel@tonic-gate void
ibcm_dealloc_state_data(ibcm_state_data_t * statep)4257c478bd9Sstevel@tonic-gate ibcm_dealloc_state_data(ibcm_state_data_t *statep)
4267c478bd9Sstevel@tonic-gate {
4277c478bd9Sstevel@tonic-gate 	timeout_id_t timer_val;
4289d3d2ed0Shiremath 	int dump_trace;
4297c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_dealloc_state_data: statep 0x%p", statep);
4307c478bd9Sstevel@tonic-gate 
4317c478bd9Sstevel@tonic-gate 	if (statep == NULL) {
4327c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_dealloc_state_data: statep NULL");
4337c478bd9Sstevel@tonic-gate 		return;
4347c478bd9Sstevel@tonic-gate 	}
4357c478bd9Sstevel@tonic-gate 
4367c478bd9Sstevel@tonic-gate 	/* ref_cnt is 0 */
4377c478bd9Sstevel@tonic-gate 	/* If timer is running - expire it */
4387c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
4397c478bd9Sstevel@tonic-gate 	timer_val = statep->timerid;
4407c478bd9Sstevel@tonic-gate 	if (timer_val != 0) {
4417c478bd9Sstevel@tonic-gate 		statep->timerid = 0;
4427c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
4437c478bd9Sstevel@tonic-gate 		(void) untimeout(timer_val);
4447c478bd9Sstevel@tonic-gate 	} else
4457c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
4467c478bd9Sstevel@tonic-gate 
4477c478bd9Sstevel@tonic-gate 	/* release the ref cnt on the associated ibmf qp */
4487c478bd9Sstevel@tonic-gate 	if (statep->stored_reply_addr.cm_qp_entry != NULL)
4497c478bd9Sstevel@tonic-gate 		ibcm_release_qp(statep->stored_reply_addr.cm_qp_entry);
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate 	if (statep->stored_msg != NULL)
4527c478bd9Sstevel@tonic-gate 		(void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
4537c478bd9Sstevel@tonic-gate 		    &statep->stored_msg);
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate 	if (statep->dreq_msg != NULL)
4567c478bd9Sstevel@tonic-gate 		(void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
4577c478bd9Sstevel@tonic-gate 		    &statep->dreq_msg);
4587c478bd9Sstevel@tonic-gate 
4597c478bd9Sstevel@tonic-gate 	if (statep->drep_msg != NULL)
4607c478bd9Sstevel@tonic-gate 		(void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
4617c478bd9Sstevel@tonic-gate 		    &statep->drep_msg);
4627c478bd9Sstevel@tonic-gate 
4637c478bd9Sstevel@tonic-gate 	if (statep->mra_msg != NULL)
4647c478bd9Sstevel@tonic-gate 		(void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
4657c478bd9Sstevel@tonic-gate 		    &statep->mra_msg);
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate 	if (statep->lapr_msg != NULL)
4687c478bd9Sstevel@tonic-gate 		(void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
4697c478bd9Sstevel@tonic-gate 		    &statep->lapr_msg);
4707c478bd9Sstevel@tonic-gate 
4717c478bd9Sstevel@tonic-gate 	if (statep->defer_cm_msg != NULL)
4727c478bd9Sstevel@tonic-gate 		kmem_free(statep->defer_cm_msg, IBCM_MSG_SIZE);
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_dealloc_state_data: done for sp = 0x%p",
4757c478bd9Sstevel@tonic-gate 	    statep);
4767c478bd9Sstevel@tonic-gate 
4777c478bd9Sstevel@tonic-gate 	/* Ensure the thread doing ref cnt decr releases the mutex */
4787c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
4799d3d2ed0Shiremath 	dump_trace = statep->cm_retries > 0;
4807c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate 	/*
4837c478bd9Sstevel@tonic-gate 	 * now call the mutex_destroy() and cv_destroy()
4847c478bd9Sstevel@tonic-gate 	 */
4857c478bd9Sstevel@tonic-gate 	mutex_destroy(&statep->state_mutex);
4867c478bd9Sstevel@tonic-gate 
4877c478bd9Sstevel@tonic-gate 	cv_destroy(&statep->block_client_cv);
4887c478bd9Sstevel@tonic-gate 	cv_destroy(&statep->block_mad_cv);
4897c478bd9Sstevel@tonic-gate 
4907c478bd9Sstevel@tonic-gate 	/* free the comid */
4917c478bd9Sstevel@tonic-gate 	ibcm_free_comid(statep->hcap, statep->local_comid);
4927c478bd9Sstevel@tonic-gate 
4937c478bd9Sstevel@tonic-gate 	/* Decrement the resource on hcap */
4947c478bd9Sstevel@tonic-gate 	ibcm_dec_hca_res_cnt(statep->hcap);
4957c478bd9Sstevel@tonic-gate 
4967c478bd9Sstevel@tonic-gate 	/* dump the trace data into ibtf_debug_buf */
4979d3d2ed0Shiremath 	if ((ibcm_enable_trace & 4) || dump_trace)
4987c478bd9Sstevel@tonic-gate 		ibcm_dump_conn_trace(statep);
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate 	ibcm_fini_conn_trace(statep);
5017c478bd9Sstevel@tonic-gate 
5027c478bd9Sstevel@tonic-gate 	/* free the statep */
5037c478bd9Sstevel@tonic-gate 	kmem_free(statep, sizeof (ibcm_state_data_t));
5047c478bd9Sstevel@tonic-gate }
5057c478bd9Sstevel@tonic-gate 
5067c478bd9Sstevel@tonic-gate /*
5077c478bd9Sstevel@tonic-gate  * ibcm_delete_state_data:
5087c478bd9Sstevel@tonic-gate  *	Deletes the state from avl trees, and tries to deallocate state
5097c478bd9Sstevel@tonic-gate  *
5107c478bd9Sstevel@tonic-gate  * Arguments are:-
5117c478bd9Sstevel@tonic-gate  *	statep	- statep to be deleted
5127c478bd9Sstevel@tonic-gate  *
5137c478bd9Sstevel@tonic-gate  * Return Values:	NONE
5147c478bd9Sstevel@tonic-gate  */
5157c478bd9Sstevel@tonic-gate void
ibcm_delete_state_data(ibcm_state_data_t * statep)5167c478bd9Sstevel@tonic-gate ibcm_delete_state_data(ibcm_state_data_t *statep)
5177c478bd9Sstevel@tonic-gate {
5187c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_delete_state_data:");
5197c478bd9Sstevel@tonic-gate 
5207c478bd9Sstevel@tonic-gate 	ibcm_delete_state_from_avl(statep);
5217c478bd9Sstevel@tonic-gate 
5227c478bd9Sstevel@tonic-gate 	/* Must acquire the state mutex to set delete_state_data */
5237c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
5247c478bd9Sstevel@tonic-gate 	if (statep->ref_cnt > 0) {
5257c478bd9Sstevel@tonic-gate 		statep->delete_state_data = B_TRUE;
5267c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_delete_state_data: statep 0x%p "
5277c478bd9Sstevel@tonic-gate 		    "ref_cnt = %x", statep, statep->ref_cnt);
5287c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
5297c478bd9Sstevel@tonic-gate 		return;
5307c478bd9Sstevel@tonic-gate 	}
5317c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
5327c478bd9Sstevel@tonic-gate 
5337c478bd9Sstevel@tonic-gate 	ibcm_dealloc_state_data(statep);
5347c478bd9Sstevel@tonic-gate }
5357c478bd9Sstevel@tonic-gate 
5367c478bd9Sstevel@tonic-gate /*
5377c478bd9Sstevel@tonic-gate  * ibcm_find_sidr_entry:
5387c478bd9Sstevel@tonic-gate  *	Routines for CM SIDR state structure list manipulation.
5397c478bd9Sstevel@tonic-gate  *	Finds an entry based on lid, gid and grh exists fields
5407c478bd9Sstevel@tonic-gate  *
5417c478bd9Sstevel@tonic-gate  * INPUTS:
5427c478bd9Sstevel@tonic-gate  *	lid:		LID of incoming SIDR REQ
5437c478bd9Sstevel@tonic-gate  *	gid:		GID of incoming SIDR REQ
5447c478bd9Sstevel@tonic-gate  *	grh_exists:	TRUE if GRH exists in the incoming SIDR REQ
5457c478bd9Sstevel@tonic-gate  *	req_id:		Request ID
5467c478bd9Sstevel@tonic-gate  *	hcap:		CM State table to search for SIDR state structure
5477c478bd9Sstevel@tonic-gate  *	statep:		Returns a valid state structure, if one exists based
5487c478bd9Sstevel@tonic-gate  *			on lid, gid and grh_exists fields
5497c478bd9Sstevel@tonic-gate  *	flag:		IBCM_FLAG_LOOKUP - just lookup
5507c478bd9Sstevel@tonic-gate  *			IBCM_FLAG_LOOKUP_AND_ADD - if lookup fails, add it.
5517c478bd9Sstevel@tonic-gate  * Return Values:
5527c478bd9Sstevel@tonic-gate  *	IBCM_LOOKUP_EXISTS	- found an existing entry
5537c478bd9Sstevel@tonic-gate  *	IBCM_LOOKUP_FAIL	- failed to find an entry
5547c478bd9Sstevel@tonic-gate  *	IBCM_LOOKUP_NEW		- created a new entry
5557c478bd9Sstevel@tonic-gate  */
5567c478bd9Sstevel@tonic-gate ibcm_status_t
ibcm_find_sidr_entry(ibcm_sidr_srch_t * srch_param,ibcm_hca_info_t * hcap,ibcm_ud_state_data_t ** ud_statep,ibcm_lookup_flag_t flag)5577c478bd9Sstevel@tonic-gate ibcm_find_sidr_entry(ibcm_sidr_srch_t *srch_param, ibcm_hca_info_t *hcap,
5587c478bd9Sstevel@tonic-gate     ibcm_ud_state_data_t **ud_statep, ibcm_lookup_flag_t flag)
5597c478bd9Sstevel@tonic-gate {
5607c478bd9Sstevel@tonic-gate 	ibcm_status_t		status;
5617c478bd9Sstevel@tonic-gate 	ibcm_ud_state_data_t	*usp;
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_find_sidr_entry: srch_params are:"
5647c478bd9Sstevel@tonic-gate 	    "lid=%x, (%llX, %llX), grh: %x, id: %x",
5657c478bd9Sstevel@tonic-gate 	    srch_param->srch_lid, srch_param->srch_gid.gid_prefix,
5667c478bd9Sstevel@tonic-gate 	    srch_param->srch_gid.gid_guid, srch_param->srch_grh_exists,
5677c478bd9Sstevel@tonic-gate 	    srch_param->srch_req_id);
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate 	if (flag == IBCM_FLAG_ADD) {
5707c478bd9Sstevel@tonic-gate 		*ud_statep = ibcm_add_sidr_entry(srch_param, hcap);
5717c478bd9Sstevel@tonic-gate 		return (IBCM_LOOKUP_NEW);
5727c478bd9Sstevel@tonic-gate 	}
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate 	usp = hcap->hca_sidr_list;	/* Point to the list */
5757c478bd9Sstevel@tonic-gate 
5767c478bd9Sstevel@tonic-gate 	/* traverse the list for a matching entry */
5777c478bd9Sstevel@tonic-gate 	while (usp != NULL) {
5787c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L5(cmlog, "ibcm_find_sidr_entry: "
5797c478bd9Sstevel@tonic-gate 		    "lid=%x, (%llX, %llX), grh: %x, id: %x",
5807c478bd9Sstevel@tonic-gate 		    usp->ud_sidr_req_lid, usp->ud_sidr_req_gid.gid_prefix,
5817c478bd9Sstevel@tonic-gate 		    usp->ud_sidr_req_gid.gid_guid, usp->ud_grh_exists,
5827c478bd9Sstevel@tonic-gate 		    usp->ud_req_id);
5837c478bd9Sstevel@tonic-gate 
5847c478bd9Sstevel@tonic-gate 		if ((usp->ud_sidr_req_lid == srch_param->srch_lid) &&
5857c478bd9Sstevel@tonic-gate 		    ((srch_param->srch_gid.gid_prefix == 0) ||
5867c478bd9Sstevel@tonic-gate 		    (srch_param->srch_gid.gid_prefix ==
587015f8fffShiremath 		    usp->ud_sidr_req_gid.gid_prefix)) &&
5887c478bd9Sstevel@tonic-gate 		    ((srch_param->srch_gid.gid_guid == 0) ||
5897c478bd9Sstevel@tonic-gate 		    (srch_param->srch_gid.gid_guid ==
590015f8fffShiremath 		    usp->ud_sidr_req_gid.gid_guid)) &&
5917c478bd9Sstevel@tonic-gate 		    (srch_param->srch_req_id == usp->ud_req_id) &&
5927c478bd9Sstevel@tonic-gate 		    (usp->ud_grh_exists == srch_param->srch_grh_exists) &&
5937c478bd9Sstevel@tonic-gate 		    (usp->ud_mode == srch_param->srch_mode)) { /* found match */
5947c478bd9Sstevel@tonic-gate 			*ud_statep = usp;
5957c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L5(cmlog, "ibcm_find_sidr_entry: "
5967c478bd9Sstevel@tonic-gate 			    "found usp = %p", usp);
5977c478bd9Sstevel@tonic-gate 			mutex_enter(&usp->ud_state_mutex);
5987c478bd9Sstevel@tonic-gate 			IBCM_UD_REF_CNT_INCR(usp);
5997c478bd9Sstevel@tonic-gate 			mutex_exit(&usp->ud_state_mutex);
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate 			return (IBCM_LOOKUP_EXISTS);
6027c478bd9Sstevel@tonic-gate 		}
6037c478bd9Sstevel@tonic-gate 		usp = usp->ud_nextp;
6047c478bd9Sstevel@tonic-gate 	}
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate 	/*
6077c478bd9Sstevel@tonic-gate 	 * If code came here --> it couldn't find a match.
6087c478bd9Sstevel@tonic-gate 	 *	OR
6097c478bd9Sstevel@tonic-gate 	 * the "hcap->hca_sidr_list" was NULL
6107c478bd9Sstevel@tonic-gate 	 */
6117c478bd9Sstevel@tonic-gate 	if (flag == IBCM_FLAG_LOOKUP) {
6127c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L3(cmlog, "ibcm_find_sidr_entry: no match found "
6137c478bd9Sstevel@tonic-gate 		    "lid=%x, (%llX, %llX), grh: %x, id: %x",
6147c478bd9Sstevel@tonic-gate 		    srch_param->srch_lid, srch_param->srch_gid.gid_prefix,
6157c478bd9Sstevel@tonic-gate 		    srch_param->srch_gid.gid_guid, srch_param->srch_grh_exists,
6167c478bd9Sstevel@tonic-gate 		    srch_param->srch_req_id);
6177c478bd9Sstevel@tonic-gate 		status = IBCM_LOOKUP_FAIL;
6187c478bd9Sstevel@tonic-gate 	} else {
6197c478bd9Sstevel@tonic-gate 		*ud_statep = ibcm_add_sidr_entry(srch_param, hcap);
6207c478bd9Sstevel@tonic-gate 		status = IBCM_LOOKUP_NEW;
6217c478bd9Sstevel@tonic-gate 	}
6227c478bd9Sstevel@tonic-gate 
6237c478bd9Sstevel@tonic-gate 	return (status);
6247c478bd9Sstevel@tonic-gate }
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate 
6277c478bd9Sstevel@tonic-gate /*
6287c478bd9Sstevel@tonic-gate  * ibcm_add_sidr_entry:
6297c478bd9Sstevel@tonic-gate  *	Adds a SIDR entry. Called *ONLY* from ibcm_find_sidr_entry()
6307c478bd9Sstevel@tonic-gate  *
6317c478bd9Sstevel@tonic-gate  * INPUTS:
6327c478bd9Sstevel@tonic-gate  *	lid:		LID of incoming SIDR REQ
6337c478bd9Sstevel@tonic-gate  *	gid:		GID of incoming SIDR REQ
6347c478bd9Sstevel@tonic-gate  *	grh_exists:	TRUE if GRH exists in the incoming SIDR REQ
6357c478bd9Sstevel@tonic-gate  *	req_id:		Request ID
6367c478bd9Sstevel@tonic-gate  *	hcap:		CM State table to search for SIDR state structure
6377c478bd9Sstevel@tonic-gate  * Return Values: NONE
6387c478bd9Sstevel@tonic-gate  */
6397c478bd9Sstevel@tonic-gate ibcm_ud_state_data_t *
ibcm_add_sidr_entry(ibcm_sidr_srch_t * srch_param,ibcm_hca_info_t * hcap)6407c478bd9Sstevel@tonic-gate ibcm_add_sidr_entry(ibcm_sidr_srch_t *srch_param, ibcm_hca_info_t *hcap)
6417c478bd9Sstevel@tonic-gate {
6427c478bd9Sstevel@tonic-gate 	ibcm_ud_state_data_t	*ud_statep;
6437c478bd9Sstevel@tonic-gate 
6447c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_add_sidr_entry: lid=%x, guid=%llX, "
6459d3d2ed0Shiremath 	    "grh = %x req_id = %x", srch_param->srch_lid,
6467c478bd9Sstevel@tonic-gate 	    srch_param->srch_gid.gid_guid, srch_param->srch_grh_exists,
6477c478bd9Sstevel@tonic-gate 	    srch_param->srch_req_id);
6487c478bd9Sstevel@tonic-gate 
6497c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ud_statep))
6507c478bd9Sstevel@tonic-gate 
6517c478bd9Sstevel@tonic-gate 	/* didn't find the entry - so create new */
6527c478bd9Sstevel@tonic-gate 	ud_statep = kmem_zalloc(sizeof (ibcm_ud_state_data_t), KM_SLEEP);
6537c478bd9Sstevel@tonic-gate 
6547c478bd9Sstevel@tonic-gate 	mutex_init(&ud_statep->ud_state_mutex, NULL, MUTEX_DEFAULT, NULL);
6557c478bd9Sstevel@tonic-gate 	cv_init(&ud_statep->ud_block_client_cv, NULL, CV_DRIVER, NULL);
6567c478bd9Sstevel@tonic-gate 
6577c478bd9Sstevel@tonic-gate 	/* Initialize some ud_statep fields */
6587c478bd9Sstevel@tonic-gate 	mutex_enter(&ud_statep->ud_state_mutex);
6597c478bd9Sstevel@tonic-gate 	ud_statep->ud_hcap		= hcap;
6607c478bd9Sstevel@tonic-gate 	ud_statep->ud_req_id		= srch_param->srch_req_id;
6617c478bd9Sstevel@tonic-gate 	ud_statep->ud_ref_cnt		= 1;
6627c478bd9Sstevel@tonic-gate 	ud_statep->ud_grh_exists	= srch_param->srch_grh_exists;
6637c478bd9Sstevel@tonic-gate 	ud_statep->ud_sidr_req_lid	= srch_param->srch_lid;
6647c478bd9Sstevel@tonic-gate 	ud_statep->ud_sidr_req_gid	= srch_param->srch_gid;
6657c478bd9Sstevel@tonic-gate 	ud_statep->ud_mode		= srch_param->srch_mode;
6667c478bd9Sstevel@tonic-gate 	ud_statep->ud_max_cm_retries	= ibcm_max_retries;
6677c478bd9Sstevel@tonic-gate 	mutex_exit(&ud_statep->ud_state_mutex);
6687c478bd9Sstevel@tonic-gate 
6697c478bd9Sstevel@tonic-gate 	/* Update the list */
6707c478bd9Sstevel@tonic-gate 	ud_statep->ud_nextp = hcap->hca_sidr_list;
6717c478bd9Sstevel@tonic-gate 	hcap->hca_sidr_list = ud_statep;
6727c478bd9Sstevel@tonic-gate 
6737c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ud_statep))
6747c478bd9Sstevel@tonic-gate 
6757c478bd9Sstevel@tonic-gate 	return (ud_statep);
6767c478bd9Sstevel@tonic-gate }
6777c478bd9Sstevel@tonic-gate 
6787c478bd9Sstevel@tonic-gate 
6797c478bd9Sstevel@tonic-gate /*
6807c478bd9Sstevel@tonic-gate  * ibcm_delete_ud_state_data:
6817c478bd9Sstevel@tonic-gate  *	Deletes a given state structure
6827c478bd9Sstevel@tonic-gate  *
6837c478bd9Sstevel@tonic-gate  * Arguments are:-
6847c478bd9Sstevel@tonic-gate  *	statep	- statep to be deleted
6857c478bd9Sstevel@tonic-gate  *
6867c478bd9Sstevel@tonic-gate  * Return Values:	NONE
6877c478bd9Sstevel@tonic-gate  */
6887c478bd9Sstevel@tonic-gate void
ibcm_delete_ud_state_data(ibcm_ud_state_data_t * ud_statep)6897c478bd9Sstevel@tonic-gate ibcm_delete_ud_state_data(ibcm_ud_state_data_t *ud_statep)
6907c478bd9Sstevel@tonic-gate {
6917c478bd9Sstevel@tonic-gate 	ibcm_ud_state_data_t	*prevp, *headp;
6927c478bd9Sstevel@tonic-gate 	ibcm_hca_info_t		*hcap;
6937c478bd9Sstevel@tonic-gate 
6947c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_delete_ud_state_data: ud_statep 0x%p",
6957c478bd9Sstevel@tonic-gate 	    ud_statep);
6967c478bd9Sstevel@tonic-gate 
6977c478bd9Sstevel@tonic-gate 	if (ud_statep == NULL || ud_statep->ud_hcap == NULL) {
6987c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_delete_ud_state_data: "
6997c478bd9Sstevel@tonic-gate 		    "ud_statep or hcap is NULL");
7007c478bd9Sstevel@tonic-gate 		return;
7017c478bd9Sstevel@tonic-gate 	}
7027c478bd9Sstevel@tonic-gate 
7037c478bd9Sstevel@tonic-gate 	hcap = ud_statep->ud_hcap;
7047c478bd9Sstevel@tonic-gate 
7057c478bd9Sstevel@tonic-gate 	rw_enter(&hcap->hca_sidr_list_lock, RW_WRITER);
7067c478bd9Sstevel@tonic-gate 
7077c478bd9Sstevel@tonic-gate 	/* Next, remove this from the HCA SIDR list */
7087c478bd9Sstevel@tonic-gate 	if (hcap->hca_sidr_list != NULL) {
7097c478bd9Sstevel@tonic-gate 		prevp = NULL;
7107c478bd9Sstevel@tonic-gate 		headp = hcap->hca_sidr_list;
7117c478bd9Sstevel@tonic-gate 
7127c478bd9Sstevel@tonic-gate 		while (headp != NULL) {
7137c478bd9Sstevel@tonic-gate 			/* delete the matching entry */
7147c478bd9Sstevel@tonic-gate 			if (headp == ud_statep) {
7157c478bd9Sstevel@tonic-gate 				if (prevp) {
7167c478bd9Sstevel@tonic-gate 					prevp->ud_nextp = headp->ud_nextp;
7177c478bd9Sstevel@tonic-gate 				} else {
7187c478bd9Sstevel@tonic-gate 					prevp = headp->ud_nextp;
7197c478bd9Sstevel@tonic-gate 					hcap->hca_sidr_list = prevp;
7207c478bd9Sstevel@tonic-gate 				}
7217c478bd9Sstevel@tonic-gate 				break;
7227c478bd9Sstevel@tonic-gate 			}
7237c478bd9Sstevel@tonic-gate 			prevp = headp;
7247c478bd9Sstevel@tonic-gate 			headp = headp->ud_nextp;
7257c478bd9Sstevel@tonic-gate 		}
7267c478bd9Sstevel@tonic-gate 	}
7277c478bd9Sstevel@tonic-gate 
7287c478bd9Sstevel@tonic-gate 	rw_exit(&hcap->hca_sidr_list_lock);
7297c478bd9Sstevel@tonic-gate 
7307c478bd9Sstevel@tonic-gate 	/*
7317c478bd9Sstevel@tonic-gate 	 * While ref_cnt >  0
7327c478bd9Sstevel@tonic-gate 	 * - implies someone else is accessing the statep (possibly in
7337c478bd9Sstevel@tonic-gate 	 * a timeout function handler etc.)
7347c478bd9Sstevel@tonic-gate 	 * - don't delete statep unless they are done otherwise potentially
7357c478bd9Sstevel@tonic-gate 	 * one could access released memory and panic.
7367c478bd9Sstevel@tonic-gate 	 */
7377c478bd9Sstevel@tonic-gate 	mutex_enter(&ud_statep->ud_state_mutex);
7387c478bd9Sstevel@tonic-gate 	if (ud_statep->ud_ref_cnt > 0) {
7397c478bd9Sstevel@tonic-gate 		ud_statep->ud_delete_state_data = B_TRUE;
7407c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_delete_ud_state_data: "
7417c478bd9Sstevel@tonic-gate 		    "ud_statep 0x%p ud_ref_cnt = %x", ud_statep,
7427c478bd9Sstevel@tonic-gate 		    ud_statep->ud_ref_cnt);
7437c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
7447c478bd9Sstevel@tonic-gate 		return;
7457c478bd9Sstevel@tonic-gate 	}
7467c478bd9Sstevel@tonic-gate 	mutex_exit(&ud_statep->ud_state_mutex);
7477c478bd9Sstevel@tonic-gate 
7487c478bd9Sstevel@tonic-gate 	ibcm_dealloc_ud_state_data(ud_statep);
7497c478bd9Sstevel@tonic-gate }
7507c478bd9Sstevel@tonic-gate 
7517c478bd9Sstevel@tonic-gate /*
7527c478bd9Sstevel@tonic-gate  * ibcm_ud_dealloc_state_data:
7537c478bd9Sstevel@tonic-gate  *	Deallocates a given ud state structure
7547c478bd9Sstevel@tonic-gate  *
7557c478bd9Sstevel@tonic-gate  * Arguments are:-
7567c478bd9Sstevel@tonic-gate  *	ud statep	- ud statep to be deleted
7577c478bd9Sstevel@tonic-gate  *
7587c478bd9Sstevel@tonic-gate  * Return Values:	NONE
7597c478bd9Sstevel@tonic-gate  */
7607c478bd9Sstevel@tonic-gate void
ibcm_dealloc_ud_state_data(ibcm_ud_state_data_t * ud_statep)7617c478bd9Sstevel@tonic-gate ibcm_dealloc_ud_state_data(ibcm_ud_state_data_t *ud_statep)
7627c478bd9Sstevel@tonic-gate {
7637c478bd9Sstevel@tonic-gate 	timeout_id_t		timer_val;
7647c478bd9Sstevel@tonic-gate 
7657c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_dealloc_ud_state_data: ud_statep 0x%p",
7667c478bd9Sstevel@tonic-gate 	    ud_statep);
7677c478bd9Sstevel@tonic-gate 
7687c478bd9Sstevel@tonic-gate 	/* If timer is running - expire it */
7697c478bd9Sstevel@tonic-gate 	mutex_enter(&ud_statep->ud_state_mutex);
7707c478bd9Sstevel@tonic-gate 	if (ud_statep->ud_timerid) {
7717c478bd9Sstevel@tonic-gate 		timer_val = ud_statep->ud_timerid;
7727c478bd9Sstevel@tonic-gate 		ud_statep->ud_timerid = 0;
7737c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
7747c478bd9Sstevel@tonic-gate 		(void) untimeout(timer_val);
7757c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_dealloc_ud_state_data: "
7767c478bd9Sstevel@tonic-gate 		    "Unexpected timer id 0x%p ud_statep 0x%p", timer_val,
7777c478bd9Sstevel@tonic-gate 		    ud_statep);
7787c478bd9Sstevel@tonic-gate 	} else
7797c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
7807c478bd9Sstevel@tonic-gate 
7817c478bd9Sstevel@tonic-gate 	if (ud_statep->ud_stored_msg != NULL) {
7827c478bd9Sstevel@tonic-gate 		(void) ibcm_free_out_msg(
7837c478bd9Sstevel@tonic-gate 		    ud_statep->ud_stored_reply_addr.ibmf_hdl,
7847c478bd9Sstevel@tonic-gate 		    &ud_statep->ud_stored_msg);
7857c478bd9Sstevel@tonic-gate 	}
7867c478bd9Sstevel@tonic-gate 
7877c478bd9Sstevel@tonic-gate 	/* release the ref cnt on the associated ibmf qp */
7887c478bd9Sstevel@tonic-gate 	ASSERT(ud_statep->ud_stored_reply_addr.cm_qp_entry != NULL);
7897c478bd9Sstevel@tonic-gate 	ibcm_release_qp(ud_statep->ud_stored_reply_addr.cm_qp_entry);
7907c478bd9Sstevel@tonic-gate 
7917c478bd9Sstevel@tonic-gate 	/* Ensure the thread doing ref cnt decr releases the mutex */
7927c478bd9Sstevel@tonic-gate 	mutex_enter(&ud_statep->ud_state_mutex);
7937c478bd9Sstevel@tonic-gate 	mutex_exit(&ud_statep->ud_state_mutex);
7947c478bd9Sstevel@tonic-gate 
7957c478bd9Sstevel@tonic-gate 	/* now do the mutex_destroy() and cv_destroy() */
7967c478bd9Sstevel@tonic-gate 	mutex_destroy(&ud_statep->ud_state_mutex);
7977c478bd9Sstevel@tonic-gate 
7987c478bd9Sstevel@tonic-gate 	cv_destroy(&ud_statep->ud_block_client_cv);
7997c478bd9Sstevel@tonic-gate 
8007c478bd9Sstevel@tonic-gate 	/* free the req id on SIDR REQ sender side */
8017c478bd9Sstevel@tonic-gate 	if (ud_statep->ud_mode == IBCM_ACTIVE_MODE)
8027c478bd9Sstevel@tonic-gate 		ibcm_free_reqid(ud_statep->ud_hcap, ud_statep->ud_req_id);
8037c478bd9Sstevel@tonic-gate 
8047c478bd9Sstevel@tonic-gate 	/* Decrement the resource on hcap */
8057c478bd9Sstevel@tonic-gate 	ibcm_dec_hca_res_cnt(ud_statep->ud_hcap);
8067c478bd9Sstevel@tonic-gate 
8077c478bd9Sstevel@tonic-gate 	/* free the statep */
8087c478bd9Sstevel@tonic-gate 	kmem_free(ud_statep, sizeof (ibcm_ud_state_data_t));
8097c478bd9Sstevel@tonic-gate }
8107c478bd9Sstevel@tonic-gate 
8117c478bd9Sstevel@tonic-gate 
8127c478bd9Sstevel@tonic-gate /*
8137c478bd9Sstevel@tonic-gate  * ibcm_init_ids:
8147c478bd9Sstevel@tonic-gate  *	Create the vmem arenas for the various global ids
8157c478bd9Sstevel@tonic-gate  *
8167c478bd9Sstevel@tonic-gate  * Arguments are:-
8177c478bd9Sstevel@tonic-gate  *	NONE
8187c478bd9Sstevel@tonic-gate  *
8197c478bd9Sstevel@tonic-gate  * Return Values:	ibcm_status_t
8207c478bd9Sstevel@tonic-gate  */
8217c478bd9Sstevel@tonic-gate 
8227c478bd9Sstevel@tonic-gate ibcm_status_t
ibcm_init_ids(void)8237c478bd9Sstevel@tonic-gate ibcm_init_ids(void)
8247c478bd9Sstevel@tonic-gate {
8257c478bd9Sstevel@tonic-gate 	timespec_t tv;
8267c478bd9Sstevel@tonic-gate 
8277c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_local_sid_arena))
828015f8fffShiremath 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_ip_sid_arena))
8297c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_local_sid_seed))
8307c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_local_cid_seed))
8317c478bd9Sstevel@tonic-gate 
8327c478bd9Sstevel@tonic-gate 	ibcm_local_sid_arena = vmem_create("ibcm_local_sid",
8337c478bd9Sstevel@tonic-gate 	    (void *)IBCM_INITIAL_SID, IBCM_MAX_LOCAL_SIDS, 1, NULL, NULL, NULL,
8347c478bd9Sstevel@tonic-gate 	    0, VM_SLEEP | VMC_IDENTIFIER);
8357c478bd9Sstevel@tonic-gate 
8367c478bd9Sstevel@tonic-gate 	if (!ibcm_local_sid_arena)
8377c478bd9Sstevel@tonic-gate 		return (IBCM_FAILURE);
8387c478bd9Sstevel@tonic-gate 
839015f8fffShiremath 	ibcm_ip_sid_arena = vmem_create("ibcm_ip_sid", (void *)IBCM_INITIAL_SID,
840015f8fffShiremath 	    IBCM_MAX_IP_SIDS, 1, NULL, NULL, NULL, 0,
841015f8fffShiremath 	    VM_SLEEP | VMC_IDENTIFIER);
842015f8fffShiremath 
843015f8fffShiremath 	if (!ibcm_ip_sid_arena)
844015f8fffShiremath 		return (IBCM_FAILURE);
845015f8fffShiremath 
8467c478bd9Sstevel@tonic-gate 	/* create a random starting value for local service ids */
8477c478bd9Sstevel@tonic-gate 	gethrestime(&tv);
8487c478bd9Sstevel@tonic-gate 	ibcm_local_sid_seed = ((uint64_t)tv.tv_sec << 20) & 0x007FFFFFFFF00000;
8497c478bd9Sstevel@tonic-gate 	ASSERT((ibcm_local_sid_seed & IB_SID_AGN_MASK) == 0);
8507c478bd9Sstevel@tonic-gate 	ibcm_local_sid_seed |= IB_SID_AGN_LOCAL;
851015f8fffShiremath 
8527c478bd9Sstevel@tonic-gate 	ibcm_local_cid_seed = (ib_com_id_t)tv.tv_sec;
8537c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_local_sid_arena))
8547c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_local_sid_seed))
855015f8fffShiremath 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_ip_sid_arena))
8567c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_local_cid_seed))
8577c478bd9Sstevel@tonic-gate 
8587c478bd9Sstevel@tonic-gate 	return (IBCM_SUCCESS);
8597c478bd9Sstevel@tonic-gate }
8607c478bd9Sstevel@tonic-gate 
8617c478bd9Sstevel@tonic-gate 
8627c478bd9Sstevel@tonic-gate /*
8637c478bd9Sstevel@tonic-gate  * ibcm_init_hca_ids:
8647c478bd9Sstevel@tonic-gate  *	Create the vmem arenas for the various hca level ids
8657c478bd9Sstevel@tonic-gate  *
8667c478bd9Sstevel@tonic-gate  * Arguments are:-
8677c478bd9Sstevel@tonic-gate  *	hcap		pointer to ibcm_hca_info_t
8687c478bd9Sstevel@tonic-gate  *
8697c478bd9Sstevel@tonic-gate  * Return Values:	ibcm_status_t
8707c478bd9Sstevel@tonic-gate  */
8717c478bd9Sstevel@tonic-gate ibcm_status_t
ibcm_init_hca_ids(ibcm_hca_info_t * hcap)8727c478bd9Sstevel@tonic-gate ibcm_init_hca_ids(ibcm_hca_info_t *hcap)
8737c478bd9Sstevel@tonic-gate {
8747c478bd9Sstevel@tonic-gate 	hcap->hca_comid_arena = vmem_create("ibcm_com_ids",
8757c478bd9Sstevel@tonic-gate 	    (void *)IBCM_INITIAL_COMID, IBCM_MAX_COMIDS,
8767c478bd9Sstevel@tonic-gate 	    1, NULL, NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER);
8777c478bd9Sstevel@tonic-gate 
8787c478bd9Sstevel@tonic-gate 	if (!hcap->hca_comid_arena)
8797c478bd9Sstevel@tonic-gate 		return (IBCM_FAILURE);
8807c478bd9Sstevel@tonic-gate 
8817c478bd9Sstevel@tonic-gate 	hcap->hca_reqid_arena = vmem_create("ibcm_req_ids",
8827c478bd9Sstevel@tonic-gate 	    (void *)IBCM_INITIAL_REQID, IBCM_MAX_REQIDS,
8837c478bd9Sstevel@tonic-gate 	    1, NULL, NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER);
8847c478bd9Sstevel@tonic-gate 
8857c478bd9Sstevel@tonic-gate 	if (!hcap->hca_reqid_arena) {
8867c478bd9Sstevel@tonic-gate 		vmem_destroy(hcap->hca_comid_arena);
8877c478bd9Sstevel@tonic-gate 		return (IBCM_FAILURE);
8887c478bd9Sstevel@tonic-gate 	}
8897c478bd9Sstevel@tonic-gate 
8907c478bd9Sstevel@tonic-gate 	return (IBCM_SUCCESS);
8917c478bd9Sstevel@tonic-gate }
8927c478bd9Sstevel@tonic-gate 
8937c478bd9Sstevel@tonic-gate /*
8947c478bd9Sstevel@tonic-gate  * ibcm_free_ids:
8957c478bd9Sstevel@tonic-gate  *	Destroy the vmem arenas for the various ids
8967c478bd9Sstevel@tonic-gate  *
8977c478bd9Sstevel@tonic-gate  * Arguments are:-
8987c478bd9Sstevel@tonic-gate  *	NONE
8997c478bd9Sstevel@tonic-gate  *
9007c478bd9Sstevel@tonic-gate  * Return Values:	NONE
9017c478bd9Sstevel@tonic-gate  */
9027c478bd9Sstevel@tonic-gate void
ibcm_fini_ids(void)9037c478bd9Sstevel@tonic-gate ibcm_fini_ids(void)
9047c478bd9Sstevel@tonic-gate {
9057c478bd9Sstevel@tonic-gate 	/* All arenas shall be valid */
9067c478bd9Sstevel@tonic-gate 	vmem_destroy(ibcm_local_sid_arena);
907015f8fffShiremath 	vmem_destroy(ibcm_ip_sid_arena);
9087c478bd9Sstevel@tonic-gate }
9097c478bd9Sstevel@tonic-gate 
9107c478bd9Sstevel@tonic-gate /*
9117c478bd9Sstevel@tonic-gate  * ibcm_free_hca_ids:
9127c478bd9Sstevel@tonic-gate  *	Destroy the vmem arenas for the various ids
9137c478bd9Sstevel@tonic-gate  *
9147c478bd9Sstevel@tonic-gate  * Arguments are:-
9157c478bd9Sstevel@tonic-gate  *	hcap		pointer to ibcm_hca_info_t
9167c478bd9Sstevel@tonic-gate  *
9177c478bd9Sstevel@tonic-gate  * Return Values:	NONE
9187c478bd9Sstevel@tonic-gate  */
9197c478bd9Sstevel@tonic-gate void
ibcm_fini_hca_ids(ibcm_hca_info_t * hcap)9207c478bd9Sstevel@tonic-gate ibcm_fini_hca_ids(ibcm_hca_info_t *hcap)
9217c478bd9Sstevel@tonic-gate {
9227c478bd9Sstevel@tonic-gate 	/* All arenas shall be valid */
9237c478bd9Sstevel@tonic-gate 	vmem_destroy(hcap->hca_comid_arena);
9247c478bd9Sstevel@tonic-gate 	vmem_destroy(hcap->hca_reqid_arena);
9257c478bd9Sstevel@tonic-gate }
9267c478bd9Sstevel@tonic-gate 
9277c478bd9Sstevel@tonic-gate /* Communication id management routines ie., allocate, free up comids */
9287c478bd9Sstevel@tonic-gate 
9297c478bd9Sstevel@tonic-gate /*
9307c478bd9Sstevel@tonic-gate  * ibcm_alloc_comid:
9317c478bd9Sstevel@tonic-gate  *	Allocate a new communication id
9327c478bd9Sstevel@tonic-gate  *
9337c478bd9Sstevel@tonic-gate  * Arguments are:-
9347c478bd9Sstevel@tonic-gate  *	hcap	:	pointer to ibcm_hca_info_t
9357c478bd9Sstevel@tonic-gate  *	comid:		pointer to the newly allocated communication id
9367c478bd9Sstevel@tonic-gate  *
9377c478bd9Sstevel@tonic-gate  * Return Values:	ibt_status_t
9387c478bd9Sstevel@tonic-gate  */
9397c478bd9Sstevel@tonic-gate ibcm_status_t
ibcm_alloc_comid(ibcm_hca_info_t * hcap,ib_com_id_t * comidp)9407c478bd9Sstevel@tonic-gate ibcm_alloc_comid(ibcm_hca_info_t *hcap, ib_com_id_t *comidp)
9417c478bd9Sstevel@tonic-gate {
9427c478bd9Sstevel@tonic-gate 	ib_com_id_t comid;
9437c478bd9Sstevel@tonic-gate 
9447c478bd9Sstevel@tonic-gate 	/* Use next fit, so least recently used com id is allocated */
9457c478bd9Sstevel@tonic-gate 	comid = (ib_com_id_t)(uintptr_t)vmem_alloc(hcap->hca_comid_arena, 1,
9467c478bd9Sstevel@tonic-gate 	    VM_SLEEP | VM_NEXTFIT);
9477c478bd9Sstevel@tonic-gate 
9487c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_alloc_comid: hcap 0x%p comid 0x%lX", hcap,
9497c478bd9Sstevel@tonic-gate 	    comid);
9507c478bd9Sstevel@tonic-gate 
9517c478bd9Sstevel@tonic-gate 	/*
9527c478bd9Sstevel@tonic-gate 	 * As comid is 32 bits, and maximum connections possible are 2^24
9537c478bd9Sstevel@tonic-gate 	 * per hca, comid allocation would never fail
9547c478bd9Sstevel@tonic-gate 	 */
9557c478bd9Sstevel@tonic-gate 	*comidp = comid + ibcm_local_cid_seed;
9567c478bd9Sstevel@tonic-gate 	if (comid == 0) {
9577c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_alloc_comid: hcap 0x%p"
9587c478bd9Sstevel@tonic-gate 		    "no more comids available", hcap);
9597c478bd9Sstevel@tonic-gate 		return (IBCM_FAILURE);
9607c478bd9Sstevel@tonic-gate 	}
9617c478bd9Sstevel@tonic-gate 
9627c478bd9Sstevel@tonic-gate 	return (IBCM_SUCCESS);
9637c478bd9Sstevel@tonic-gate }
9647c478bd9Sstevel@tonic-gate 
9657c478bd9Sstevel@tonic-gate /*
9667c478bd9Sstevel@tonic-gate  * ibcm_free_comid:
9677c478bd9Sstevel@tonic-gate  *	Releases the given Communication Id
9687c478bd9Sstevel@tonic-gate  *
9697c478bd9Sstevel@tonic-gate  * Arguments are:
9707c478bd9Sstevel@tonic-gate  *	hcap	:	pointer to ibcm_hca_info_t
9717c478bd9Sstevel@tonic-gate  *	comid	:	Communication id to be free'd
9727c478bd9Sstevel@tonic-gate  *
9737c478bd9Sstevel@tonic-gate  * Return Values:	NONE
9747c478bd9Sstevel@tonic-gate  */
9757c478bd9Sstevel@tonic-gate void
ibcm_free_comid(ibcm_hca_info_t * hcap,ib_com_id_t comid)9767c478bd9Sstevel@tonic-gate ibcm_free_comid(ibcm_hca_info_t *hcap, ib_com_id_t comid)
9777c478bd9Sstevel@tonic-gate {
9787c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_free_comid: hcap 0x%p"
9797c478bd9Sstevel@tonic-gate 	    "comid %x", hcap, comid);
9807c478bd9Sstevel@tonic-gate 	comid -= ibcm_local_cid_seed;
9817c478bd9Sstevel@tonic-gate 	vmem_free(hcap->hca_comid_arena, (void *)(uintptr_t)comid, 1);
9827c478bd9Sstevel@tonic-gate }
9837c478bd9Sstevel@tonic-gate 
9847c478bd9Sstevel@tonic-gate /* Allocate and Free local service ids */
9857c478bd9Sstevel@tonic-gate 
9867c478bd9Sstevel@tonic-gate /*
9877c478bd9Sstevel@tonic-gate  * ibcm_alloc_local_sids:
9887c478bd9Sstevel@tonic-gate  *	Create and destroy the vmem arenas for the service ids
9897c478bd9Sstevel@tonic-gate  *
9907c478bd9Sstevel@tonic-gate  * Arguments are:-
9917c478bd9Sstevel@tonic-gate  *	Number of contiguous SIDs needed
9927c478bd9Sstevel@tonic-gate  *
9937c478bd9Sstevel@tonic-gate  * Return Values:	starting SID
9947c478bd9Sstevel@tonic-gate  */
9957c478bd9Sstevel@tonic-gate ib_svc_id_t
ibcm_alloc_local_sids(int num_sids)9967c478bd9Sstevel@tonic-gate ibcm_alloc_local_sids(int num_sids)
9977c478bd9Sstevel@tonic-gate {
9987c478bd9Sstevel@tonic-gate 	ib_svc_id_t sid;
9997c478bd9Sstevel@tonic-gate 
10007c478bd9Sstevel@tonic-gate 	sid = (ib_svc_id_t)(uintptr_t)vmem_alloc(ibcm_local_sid_arena,
10017c478bd9Sstevel@tonic-gate 	    num_sids, VM_SLEEP | VM_NEXTFIT);
10027c478bd9Sstevel@tonic-gate 
10037c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_alloc_local_sids: ServiceID 0x%llX "
10047c478bd9Sstevel@tonic-gate 	    "num_sids %d", sid, num_sids);
10057c478bd9Sstevel@tonic-gate 	if (sid == 0) {
10067c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_alloc_local_sids: "
10077c478bd9Sstevel@tonic-gate 		    "no more local sids available");
10087c478bd9Sstevel@tonic-gate 	} else {
10097c478bd9Sstevel@tonic-gate 		ASSERT((ibcm_local_sid_seed & IB_SID_AGN_MASK) ==
10107c478bd9Sstevel@tonic-gate 		    IB_SID_AGN_LOCAL);
10117c478bd9Sstevel@tonic-gate 		sid += ibcm_local_sid_seed;
10127c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_alloc_local_sids: Success: "
10137c478bd9Sstevel@tonic-gate 		    "allocated 0x%llX:%d", sid, num_sids);
10147c478bd9Sstevel@tonic-gate 	}
10157c478bd9Sstevel@tonic-gate 	return (sid);
10167c478bd9Sstevel@tonic-gate }
10177c478bd9Sstevel@tonic-gate 
10187c478bd9Sstevel@tonic-gate /*
10197c478bd9Sstevel@tonic-gate  * ibcm_free_local_sids:
10207c478bd9Sstevel@tonic-gate  *	Releases the given Local service id
10217c478bd9Sstevel@tonic-gate  *
10227c478bd9Sstevel@tonic-gate  * Arguments are:
10237c478bd9Sstevel@tonic-gate  *	num_sids:	Number of local service id's to be free'd
10247c478bd9Sstevel@tonic-gate  *	service_id:	Starting local service id that needs to be free'd
10257c478bd9Sstevel@tonic-gate  *
10267c478bd9Sstevel@tonic-gate  * Return Values:	NONE
10277c478bd9Sstevel@tonic-gate  */
10287c478bd9Sstevel@tonic-gate void
ibcm_free_local_sids(ib_svc_id_t service_id,int num_sids)10297c478bd9Sstevel@tonic-gate ibcm_free_local_sids(ib_svc_id_t service_id, int num_sids)
10307c478bd9Sstevel@tonic-gate {
10317c478bd9Sstevel@tonic-gate 	service_id -= ibcm_local_sid_seed;
10327c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_free_local_sids: "
10337c478bd9Sstevel@tonic-gate 	    "service_id 0x%llX num_sids %d", service_id, num_sids);
10347c478bd9Sstevel@tonic-gate 	vmem_free(ibcm_local_sid_arena,
10357c478bd9Sstevel@tonic-gate 	    (void *)(uintptr_t)service_id, num_sids);
10367c478bd9Sstevel@tonic-gate }
10377c478bd9Sstevel@tonic-gate 
1038015f8fffShiremath /*
1039015f8fffShiremath  * ibcm_alloc_ip_sid:
1040015f8fffShiremath  *	Allocate a local IP SID.
1041015f8fffShiremath  */
1042015f8fffShiremath ib_svc_id_t
ibcm_alloc_ip_sid()1043015f8fffShiremath ibcm_alloc_ip_sid()
1044015f8fffShiremath {
1045015f8fffShiremath 	ib_svc_id_t sid;
1046015f8fffShiremath 
1047015f8fffShiremath 	sid = (ib_svc_id_t)(uintptr_t)vmem_alloc(ibcm_ip_sid_arena, 1,
1048015f8fffShiremath 	    VM_SLEEP | VM_NEXTFIT);
1049015f8fffShiremath 	if (sid == 0) {
1050015f8fffShiremath 		IBTF_DPRINTF_L2(cmlog, "ibcm_alloc_ip_sid: no more RDMA IP "
1051015f8fffShiremath 		    "SIDs available");
1052015f8fffShiremath 	} else {
1053015f8fffShiremath 		sid += IB_SID_IPADDR_PREFIX;
1054015f8fffShiremath 		IBTF_DPRINTF_L4(cmlog, "ibcm_alloc_ip_sid: Success: RDMA IP SID"
1055015f8fffShiremath 		    " allocated : 0x%016llX", sid);
1056015f8fffShiremath 	}
1057015f8fffShiremath 	return (sid);
1058015f8fffShiremath }
1059015f8fffShiremath 
1060015f8fffShiremath /*
1061015f8fffShiremath  * ibcm_free_ip_sid:
1062015f8fffShiremath  *	Releases the given IP Service ID
1063015f8fffShiremath  */
1064015f8fffShiremath void
ibcm_free_ip_sid(ib_svc_id_t sid)1065015f8fffShiremath ibcm_free_ip_sid(ib_svc_id_t sid)
1066015f8fffShiremath {
1067015f8fffShiremath 	sid -= IB_SID_IPADDR_PREFIX;
1068015f8fffShiremath 	vmem_free(ibcm_ip_sid_arena, (void *)(uintptr_t)sid, 1);
1069015f8fffShiremath }
1070015f8fffShiremath 
1071015f8fffShiremath 
10727c478bd9Sstevel@tonic-gate /* Allocate and free request id routines for SIDR */
10737c478bd9Sstevel@tonic-gate 
10747c478bd9Sstevel@tonic-gate /*
10757c478bd9Sstevel@tonic-gate  * ibcm_alloc_reqid:
10767c478bd9Sstevel@tonic-gate  *	Allocate a new SIDR REQ request id
10777c478bd9Sstevel@tonic-gate  *
10787c478bd9Sstevel@tonic-gate  * Arguments are:-
10797c478bd9Sstevel@tonic-gate  *	hcap	:	pointer to ibcm_hca_info_t
10807c478bd9Sstevel@tonic-gate  *	*reqid	:	pointer to the new request id returned
10817c478bd9Sstevel@tonic-gate  *
10827c478bd9Sstevel@tonic-gate  * Return Values:	ibcm_status_t
10837c478bd9Sstevel@tonic-gate  */
10847c478bd9Sstevel@tonic-gate ibcm_status_t
ibcm_alloc_reqid(ibcm_hca_info_t * hcap,uint32_t * reqid)10857c478bd9Sstevel@tonic-gate ibcm_alloc_reqid(ibcm_hca_info_t *hcap, uint32_t *reqid)
10867c478bd9Sstevel@tonic-gate {
10877c478bd9Sstevel@tonic-gate 	/* Use next fit, so least recently used com id is allocated */
10887c478bd9Sstevel@tonic-gate 	*reqid = (uint32_t)(uintptr_t)vmem_alloc(hcap->hca_reqid_arena, 1,
10897c478bd9Sstevel@tonic-gate 	    VM_SLEEP | VM_NEXTFIT);
10907c478bd9Sstevel@tonic-gate 
10917c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_alloc_reqid: hcap 0x%p reqid %x", hcap,
10927c478bd9Sstevel@tonic-gate 	    *reqid);
10937c478bd9Sstevel@tonic-gate 	if (!(*reqid)) {
10947c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_alloc_reqid: "
10957c478bd9Sstevel@tonic-gate 		    "no more req ids available");
10967c478bd9Sstevel@tonic-gate 		return (IBCM_FAILURE);
10977c478bd9Sstevel@tonic-gate 	}
10987c478bd9Sstevel@tonic-gate 	return (IBCM_SUCCESS);
10997c478bd9Sstevel@tonic-gate }
11007c478bd9Sstevel@tonic-gate 
11017c478bd9Sstevel@tonic-gate /*
11027c478bd9Sstevel@tonic-gate  * ibcm_free_reqid:
11037c478bd9Sstevel@tonic-gate  *	Releases the given SIDR REQ request id
11047c478bd9Sstevel@tonic-gate  *
11057c478bd9Sstevel@tonic-gate  * Arguments are:
11067c478bd9Sstevel@tonic-gate  *	hcap	:	pointer to ibcm_hca_info_t
11077c478bd9Sstevel@tonic-gate  *	reqid	:	Request id to be free'd
11087c478bd9Sstevel@tonic-gate  *
11097c478bd9Sstevel@tonic-gate  * Return Values:	NONE
11107c478bd9Sstevel@tonic-gate  */
11117c478bd9Sstevel@tonic-gate void
ibcm_free_reqid(ibcm_hca_info_t * hcap,uint32_t reqid)11127c478bd9Sstevel@tonic-gate ibcm_free_reqid(ibcm_hca_info_t *hcap, uint32_t reqid)
11137c478bd9Sstevel@tonic-gate {
11147c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_free_reqid: hcap 0x%p reqid %x", hcap,
11157c478bd9Sstevel@tonic-gate 	    reqid);
11167c478bd9Sstevel@tonic-gate 	vmem_free(hcap->hca_reqid_arena, (void *)(uintptr_t)reqid, 1);
11177c478bd9Sstevel@tonic-gate }
11187c478bd9Sstevel@tonic-gate 
11197c478bd9Sstevel@tonic-gate /*
11207c478bd9Sstevel@tonic-gate  * ibcm_generate_tranid:
11217c478bd9Sstevel@tonic-gate  *	Generate a new transaction id based on args
11227c478bd9Sstevel@tonic-gate  *
11237c478bd9Sstevel@tonic-gate  * Arguments are:-
11247c478bd9Sstevel@tonic-gate  *	event_type	CM Message REQ/DREQ/LAP
11257c478bd9Sstevel@tonic-gate  *	id		32 bit identifier
11267c478bd9Sstevel@tonic-gate  *	cm_tran_priv	CM private data to be filled in top 28 MSB bits of
11277c478bd9Sstevel@tonic-gate  *			tran id
11287c478bd9Sstevel@tonic-gate  *
11297c478bd9Sstevel@tonic-gate  *
11307c478bd9Sstevel@tonic-gate  * Return Value:	uint64_t
11317c478bd9Sstevel@tonic-gate  */
11327c478bd9Sstevel@tonic-gate uint64_t
ibcm_generate_tranid(uint8_t event,uint32_t id,uint32_t cm_tran_priv)11337c478bd9Sstevel@tonic-gate ibcm_generate_tranid(uint8_t event, uint32_t id, uint32_t cm_tran_priv)
11347c478bd9Sstevel@tonic-gate {
11357c478bd9Sstevel@tonic-gate 	/*
11367c478bd9Sstevel@tonic-gate 	 * copy comid to bits 31-0 of tran id,
11377c478bd9Sstevel@tonic-gate 	 * attr id to bits 35-32 of tran id,
11387c478bd9Sstevel@tonic-gate 	 * cm_priv to bits 63-36 of tran id
11397c478bd9Sstevel@tonic-gate 	 */
11407c478bd9Sstevel@tonic-gate 	if (cm_tran_priv == 0)
11417c478bd9Sstevel@tonic-gate 		/*
11427c478bd9Sstevel@tonic-gate 		 * The below ensures that no duplicate transaction id is
11437c478bd9Sstevel@tonic-gate 		 * generated atleast for next 6 months. Calculations:
11447c478bd9Sstevel@tonic-gate 		 * (2^28)/(1000 * 60 * 24 * 30) = 6 approx
11457c478bd9Sstevel@tonic-gate 		 */
11467c478bd9Sstevel@tonic-gate 		cm_tran_priv = gethrtime() >> 20;	/* ~time in ms */
11477c478bd9Sstevel@tonic-gate 
11487c478bd9Sstevel@tonic-gate 	return ((((uint64_t)cm_tran_priv << 36) | (uint64_t)event << 32) | id);
11497c478bd9Sstevel@tonic-gate }
11507c478bd9Sstevel@tonic-gate 
11517c478bd9Sstevel@tonic-gate #ifdef DEBUG
11527c478bd9Sstevel@tonic-gate 
11537c478bd9Sstevel@tonic-gate /*
11547c478bd9Sstevel@tonic-gate  * ibcm_decode_tranid:
11557c478bd9Sstevel@tonic-gate  *	Decodes a given transaction id, assuming certain format.
11567c478bd9Sstevel@tonic-gate  *
11577c478bd9Sstevel@tonic-gate  * Arguments are:-
11587c478bd9Sstevel@tonic-gate  *	tran_id		Transaction id to be decoded
11597c478bd9Sstevel@tonic-gate  *	cm_tran_priv	CM private data retrieved from transaction id
11607c478bd9Sstevel@tonic-gate  *
11617c478bd9Sstevel@tonic-gate  * Return Value:	None
11627c478bd9Sstevel@tonic-gate  */
11637c478bd9Sstevel@tonic-gate void
ibcm_decode_tranid(uint64_t tran_id,uint32_t * cm_tran_priv)11647c478bd9Sstevel@tonic-gate ibcm_decode_tranid(uint64_t tran_id, uint32_t *cm_tran_priv)
11657c478bd9Sstevel@tonic-gate {
11667c478bd9Sstevel@tonic-gate 	ib_com_id_t		id;
11677c478bd9Sstevel@tonic-gate 	ibcm_event_type_t	event;
11687c478bd9Sstevel@tonic-gate 
11697c478bd9Sstevel@tonic-gate 	id = tran_id & 0xFFFFFFFF;
11707c478bd9Sstevel@tonic-gate 	event = (tran_id >> 32) & 0xF;
11717c478bd9Sstevel@tonic-gate 
11729d3d2ed0Shiremath 	IBTF_DPRINTF_L5(cmlog, "ibcm_decode_tranid: id = 0x%x, event = %x",
11737c478bd9Sstevel@tonic-gate 	    id, event);
11747c478bd9Sstevel@tonic-gate 
11757c478bd9Sstevel@tonic-gate 	if (cm_tran_priv) {
11767c478bd9Sstevel@tonic-gate 		*cm_tran_priv = tran_id >> 36;
11777c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L5(cmlog, "ibcm_decode_tranid: "
11787c478bd9Sstevel@tonic-gate 		    "cm_tran_priv = %x", *cm_tran_priv);
11797c478bd9Sstevel@tonic-gate 	}
11807c478bd9Sstevel@tonic-gate }
11817c478bd9Sstevel@tonic-gate 
11827c478bd9Sstevel@tonic-gate #endif
11837c478bd9Sstevel@tonic-gate 
11847c478bd9Sstevel@tonic-gate /*
11857c478bd9Sstevel@tonic-gate  * Service ID entry create and lookup functions
11867c478bd9Sstevel@tonic-gate  */
11877c478bd9Sstevel@tonic-gate 
11887c478bd9Sstevel@tonic-gate /*
11897c478bd9Sstevel@tonic-gate  * ibcm_svc_compare:
11907c478bd9Sstevel@tonic-gate  * 	- AVL svc tree node compare
11917c478bd9Sstevel@tonic-gate  *
11927c478bd9Sstevel@tonic-gate  * Arguments:
11937c478bd9Sstevel@tonic-gate  *	p1	: pointer to local comid
11947c478bd9Sstevel@tonic-gate  *	p2	: pointer to passed ibcm_state_data_t
11957c478bd9Sstevel@tonic-gate  *
11967c478bd9Sstevel@tonic-gate  * Return values:
11977c478bd9Sstevel@tonic-gate  *	0	: match found
11987c478bd9Sstevel@tonic-gate  *	-1	: no match but insert to left side of the tree
11997c478bd9Sstevel@tonic-gate  *	+1	: no match but insert to right side of the tree
12007c478bd9Sstevel@tonic-gate  */
12017c478bd9Sstevel@tonic-gate int
ibcm_svc_compare(const void * p1,const void * p2)12027c478bd9Sstevel@tonic-gate ibcm_svc_compare(const void *p1, const void *p2)
12037c478bd9Sstevel@tonic-gate {
12047c478bd9Sstevel@tonic-gate 	ibcm_svc_lookup_t	*sidp = (ibcm_svc_lookup_t *)p1;
12057c478bd9Sstevel@tonic-gate 	ibcm_svc_info_t		*svcp = (ibcm_svc_info_t *)p2;
12067c478bd9Sstevel@tonic-gate 	ib_svc_id_t		start_sid = sidp->sid;
12077c478bd9Sstevel@tonic-gate 	ib_svc_id_t		end_sid = start_sid + sidp->num_sids - 1;
12087c478bd9Sstevel@tonic-gate 
12097c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_svc_compare: "
12107c478bd9Sstevel@tonic-gate 	    "sid: 0x%llx, numsids: %d, node_sid: 0x%llx node_num_sids: %d",
12117c478bd9Sstevel@tonic-gate 	    sidp->sid, sidp->num_sids, svcp->svc_id, svcp->svc_num_sids);
12127c478bd9Sstevel@tonic-gate 
12137c478bd9Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&ibcm_svc_info_lock));
12147c478bd9Sstevel@tonic-gate 
12157c478bd9Sstevel@tonic-gate 	if (svcp->svc_id > end_sid)
12167c478bd9Sstevel@tonic-gate 		return (-1);
12177c478bd9Sstevel@tonic-gate 	if (svcp->svc_id + svcp->svc_num_sids - 1 < start_sid)
12187c478bd9Sstevel@tonic-gate 		return (+1);
12197c478bd9Sstevel@tonic-gate 	return (0);	/* means there is some overlap of SIDs */
12207c478bd9Sstevel@tonic-gate }
12217c478bd9Sstevel@tonic-gate 
12227c478bd9Sstevel@tonic-gate 
12237c478bd9Sstevel@tonic-gate /*
12247c478bd9Sstevel@tonic-gate  * ibcm_create_svc_entry:
12257c478bd9Sstevel@tonic-gate  *	Make sure no conflicting entry exists, then allocate it.
12267c478bd9Sstevel@tonic-gate  *	Fill in the critical "look up" details that are provided
12277c478bd9Sstevel@tonic-gate  *	in the arguments before dropping the lock.
12287c478bd9Sstevel@tonic-gate  *
12297c478bd9Sstevel@tonic-gate  * Return values:
12307c478bd9Sstevel@tonic-gate  *	Pointer to ibcm_svc_info_t, if created, otherwise NULL.
12317c478bd9Sstevel@tonic-gate  */
12327c478bd9Sstevel@tonic-gate ibcm_svc_info_t *
ibcm_create_svc_entry(ib_svc_id_t sid,int num_sids)12337c478bd9Sstevel@tonic-gate ibcm_create_svc_entry(ib_svc_id_t sid, int num_sids)
12347c478bd9Sstevel@tonic-gate {
12357c478bd9Sstevel@tonic-gate 	ibcm_svc_info_t	*svcp;
12367c478bd9Sstevel@tonic-gate 	ibcm_svc_info_t	*svcinfop;
12377c478bd9Sstevel@tonic-gate 	ibcm_svc_lookup_t svc;
12387c478bd9Sstevel@tonic-gate 	avl_index_t where = 0;
12397c478bd9Sstevel@tonic-gate 
12407c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*svcinfop))
12417c478bd9Sstevel@tonic-gate 
12427c478bd9Sstevel@tonic-gate 	/* assume success, and avoid kmem while holding the writer lock */
12437c478bd9Sstevel@tonic-gate 	svcinfop = kmem_zalloc(sizeof (*svcinfop), KM_SLEEP);
12447c478bd9Sstevel@tonic-gate 	svcinfop->svc_id = sid;
12457c478bd9Sstevel@tonic-gate 	svcinfop->svc_num_sids = num_sids;
12467c478bd9Sstevel@tonic-gate 
12477c478bd9Sstevel@tonic-gate 	svc.sid = sid;
12487c478bd9Sstevel@tonic-gate 	svc.num_sids = num_sids;
12497c478bd9Sstevel@tonic-gate 
12507c478bd9Sstevel@tonic-gate 	mutex_enter(&ibcm_svc_info_lock);
12517c478bd9Sstevel@tonic-gate #ifdef __lock_lint
12527c478bd9Sstevel@tonic-gate 	ibcm_svc_compare(NULL, NULL);
12537c478bd9Sstevel@tonic-gate #endif
12547c478bd9Sstevel@tonic-gate 	svcp = avl_find(&ibcm_svc_avl_tree, &svc, &where);
12557c478bd9Sstevel@tonic-gate 	if (svcp != NULL) {	/* overlab exists */
12567c478bd9Sstevel@tonic-gate 		mutex_exit(&ibcm_svc_info_lock);
12577c478bd9Sstevel@tonic-gate 		kmem_free(svcinfop, sizeof (*svcinfop));
12587c478bd9Sstevel@tonic-gate 		return (NULL);
12597c478bd9Sstevel@tonic-gate 	}
12607c478bd9Sstevel@tonic-gate 	avl_insert(&ibcm_svc_avl_tree, (void *)svcinfop, where);
12617c478bd9Sstevel@tonic-gate 	mutex_exit(&ibcm_svc_info_lock);
12627c478bd9Sstevel@tonic-gate 
12637c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*svcinfop))
12647c478bd9Sstevel@tonic-gate 
12657c478bd9Sstevel@tonic-gate 	return (svcinfop);
12667c478bd9Sstevel@tonic-gate }
12677c478bd9Sstevel@tonic-gate 
12687c478bd9Sstevel@tonic-gate /*
12697c478bd9Sstevel@tonic-gate  * ibcm_find_svc_entry:
12707c478bd9Sstevel@tonic-gate  *	Finds a ibcm_svc_info_t entry into the CM's global table.
12717c478bd9Sstevel@tonic-gate  *	The search done here assumes the list is sorted by SID.
12727c478bd9Sstevel@tonic-gate  *
12737c478bd9Sstevel@tonic-gate  * Arguments are:
12747c478bd9Sstevel@tonic-gate  *	sid		- Service ID to look up
12757c478bd9Sstevel@tonic-gate  *
12767c478bd9Sstevel@tonic-gate  * Return values:
12777c478bd9Sstevel@tonic-gate  *	Pointer to ibcm_svc_info_t, if found, otherwise NULL.
12787c478bd9Sstevel@tonic-gate  */
12797c478bd9Sstevel@tonic-gate ibcm_svc_info_t *
ibcm_find_svc_entry(ib_svc_id_t sid)12807c478bd9Sstevel@tonic-gate ibcm_find_svc_entry(ib_svc_id_t sid)
12817c478bd9Sstevel@tonic-gate {
12827c478bd9Sstevel@tonic-gate 	ibcm_svc_info_t	*svcp;
12837c478bd9Sstevel@tonic-gate 	ibcm_svc_lookup_t svc;
12847c478bd9Sstevel@tonic-gate 
12857c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_find_svc_entry: finding SID 0x%llX", sid);
12867c478bd9Sstevel@tonic-gate 
12877c478bd9Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&ibcm_svc_info_lock));
12887c478bd9Sstevel@tonic-gate 
12897c478bd9Sstevel@tonic-gate 	svc.sid = sid;
12907c478bd9Sstevel@tonic-gate 	svc.num_sids = 1;
12917c478bd9Sstevel@tonic-gate #ifdef __lock_lint
12927c478bd9Sstevel@tonic-gate 	ibcm_svc_compare(NULL, NULL);
12937c478bd9Sstevel@tonic-gate #endif
12947c478bd9Sstevel@tonic-gate 	svcp = avl_find(&ibcm_svc_avl_tree, &svc, NULL);
12957c478bd9Sstevel@tonic-gate 	if (svcp != NULL) {
12967c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L3(cmlog, "ibcm_find_svc_entry: "
12977c478bd9Sstevel@tonic-gate 		    "found SID = 0x%llX", sid);
12987c478bd9Sstevel@tonic-gate 		return (svcp);	/* found it */
12997c478bd9Sstevel@tonic-gate 	}
13007c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_find_svc_entry: SID %llX not found", sid);
13017c478bd9Sstevel@tonic-gate 	return (NULL);
13027c478bd9Sstevel@tonic-gate }
13037c478bd9Sstevel@tonic-gate 
13047c478bd9Sstevel@tonic-gate /*
13057c478bd9Sstevel@tonic-gate  * ibcm_alloc_ibmf_msg:
13067c478bd9Sstevel@tonic-gate  * Allocate an ibmf message structure and the additional memory required for
13077c478bd9Sstevel@tonic-gate  * sending an outgoing CM mad.  The ibmf message structure contains two
13087c478bd9Sstevel@tonic-gate  * ibmf_msg_bufs_t fields, one for the incoming MAD and one for the outgoing
13097c478bd9Sstevel@tonic-gate  * MAD.  The CM must allocate the memory for the outgoing MAD.  The msg_buf
13107c478bd9Sstevel@tonic-gate  * field has three buffers: the mad header, the class header, and the class
13117c478bd9Sstevel@tonic-gate  * data.  To simplify the code and reduce the number of kmem_zalloc() calls,
13127c478bd9Sstevel@tonic-gate  * ibcm_alloc_ibmf_msg will allocate one buffer and set the pointers to the
13137c478bd9Sstevel@tonic-gate  * right offsets.  No class header is needed so only the mad header and class
13147c478bd9Sstevel@tonic-gate  * data fields are used.
13157c478bd9Sstevel@tonic-gate  */
13167c478bd9Sstevel@tonic-gate ibt_status_t
ibcm_alloc_out_msg(ibmf_handle_t ibmf_handle,ibmf_msg_t ** ibmf_msgpp,uint8_t method)13177c478bd9Sstevel@tonic-gate ibcm_alloc_out_msg(ibmf_handle_t ibmf_handle, ibmf_msg_t **ibmf_msgpp,
13187c478bd9Sstevel@tonic-gate     uint8_t method)
13197c478bd9Sstevel@tonic-gate {
13207c478bd9Sstevel@tonic-gate 	ib_mad_hdr_t	*output_mad_hdr;
13217c478bd9Sstevel@tonic-gate 	int		sa_retval;
13227c478bd9Sstevel@tonic-gate 
13237c478bd9Sstevel@tonic-gate 	if ((sa_retval =
13247c478bd9Sstevel@tonic-gate 	    ibmf_alloc_msg(ibmf_handle, IBMF_ALLOC_SLEEP, ibmf_msgpp)) !=
13257c478bd9Sstevel@tonic-gate 	    IBMF_SUCCESS) {
13267c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L1(cmlog, "ibcm_alloc_out_msg: "
13277c478bd9Sstevel@tonic-gate 		    "ibmf_alloc_msg failed with IBMF_ALLOC_SLEEP");
13287c478bd9Sstevel@tonic-gate 		return (ibcm_ibmf_analyze_error(sa_retval));
13297c478bd9Sstevel@tonic-gate 	}
13307c478bd9Sstevel@tonic-gate 
13317c478bd9Sstevel@tonic-gate 	(*ibmf_msgpp)->im_msgbufs_send.im_bufs_mad_hdr = kmem_zalloc(
13327c478bd9Sstevel@tonic-gate 	    IBCM_MAD_SIZE, KM_SLEEP);
13337c478bd9Sstevel@tonic-gate 
13347c478bd9Sstevel@tonic-gate 	(*ibmf_msgpp)->im_msgbufs_send.im_bufs_cl_data_len = IBCM_MSG_SIZE;
13357c478bd9Sstevel@tonic-gate 	(*ibmf_msgpp)->im_msgbufs_send.im_bufs_cl_data =
13367c478bd9Sstevel@tonic-gate 	    (uchar_t *)((*ibmf_msgpp)->im_msgbufs_send.im_bufs_mad_hdr) +
13377c478bd9Sstevel@tonic-gate 	    IBCM_MAD_HDR_SIZE;
13387c478bd9Sstevel@tonic-gate 
13397c478bd9Sstevel@tonic-gate 	/* initialize generic CM MAD header fields */
13407c478bd9Sstevel@tonic-gate 	output_mad_hdr = IBCM_OUT_HDRP((*ibmf_msgpp));
13417c478bd9Sstevel@tonic-gate 	output_mad_hdr->BaseVersion = IBCM_MAD_BASE_VERSION;
13427c478bd9Sstevel@tonic-gate 	output_mad_hdr->MgmtClass = MAD_MGMT_CLASS_COMM_MGT;
13437c478bd9Sstevel@tonic-gate 	output_mad_hdr->ClassVersion = IBCM_MAD_CLASS_VERSION;
13447c478bd9Sstevel@tonic-gate 	output_mad_hdr->R_Method = method;
13457c478bd9Sstevel@tonic-gate 
13467c478bd9Sstevel@tonic-gate 	return (IBT_SUCCESS);
13477c478bd9Sstevel@tonic-gate }
13487c478bd9Sstevel@tonic-gate 
13497c478bd9Sstevel@tonic-gate /*
13507c478bd9Sstevel@tonic-gate  * ibcm_free_ibmf_msg:
13517c478bd9Sstevel@tonic-gate  * Frees the buffer and ibmf message associated with an outgoing CM message.
13527c478bd9Sstevel@tonic-gate  * This function should only be used to free messages created by
13537c478bd9Sstevel@tonic-gate  * ibcm_alloc_out_msg.  Will return IBCM_FAILURE if the ibmf_free_msg() call
13547c478bd9Sstevel@tonic-gate  * fails and IBCM_SUCCESS otherwise.
13557c478bd9Sstevel@tonic-gate  */
13567c478bd9Sstevel@tonic-gate ibcm_status_t
ibcm_free_out_msg(ibmf_handle_t ibmf_handle,ibmf_msg_t ** ibmf_msgpp)13577c478bd9Sstevel@tonic-gate ibcm_free_out_msg(ibmf_handle_t ibmf_handle, ibmf_msg_t **ibmf_msgpp)
13587c478bd9Sstevel@tonic-gate {
13597c478bd9Sstevel@tonic-gate 	int ibmf_status;
13607c478bd9Sstevel@tonic-gate 
13617c478bd9Sstevel@tonic-gate 	kmem_free((*ibmf_msgpp)->im_msgbufs_send.im_bufs_mad_hdr,
13627c478bd9Sstevel@tonic-gate 	    IBCM_MAD_SIZE);
13637c478bd9Sstevel@tonic-gate 
13647c478bd9Sstevel@tonic-gate 	if ((ibmf_status = ibmf_free_msg(ibmf_handle, ibmf_msgpp)) !=
13657c478bd9Sstevel@tonic-gate 	    IBMF_SUCCESS) {
13667c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_free_out_msg: "
13677c478bd9Sstevel@tonic-gate 		    "ibmf_free_msg failed %d", ibmf_status);
13687c478bd9Sstevel@tonic-gate 		return (IBCM_FAILURE);
13697c478bd9Sstevel@tonic-gate 	} else
13707c478bd9Sstevel@tonic-gate 		return (IBCM_SUCCESS);
13717c478bd9Sstevel@tonic-gate }
13727c478bd9Sstevel@tonic-gate 
13737c478bd9Sstevel@tonic-gate ibcm_qp_list_t *
ibcm_find_qp(ibcm_hca_info_t * hcap,int port_no,ib_pkey_t pkey)13747c478bd9Sstevel@tonic-gate ibcm_find_qp(ibcm_hca_info_t *hcap, int port_no, ib_pkey_t pkey)
13757c478bd9Sstevel@tonic-gate {
13767c478bd9Sstevel@tonic-gate 	ibcm_qp_list_t		*entry;
13777c478bd9Sstevel@tonic-gate 	ibmf_qp_handle_t	ibmf_qp;
13787c478bd9Sstevel@tonic-gate 	int			ibmf_status;
13797c478bd9Sstevel@tonic-gate 
13807c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*entry))
13817c478bd9Sstevel@tonic-gate 
13827c478bd9Sstevel@tonic-gate 	mutex_enter(&ibcm_qp_list_lock);
13837c478bd9Sstevel@tonic-gate 
13847c478bd9Sstevel@tonic-gate 	/*
13857c478bd9Sstevel@tonic-gate 	 * CM currently does not track port up and down status. If tracking of
13867c478bd9Sstevel@tonic-gate 	 * " port status" is added in the future, then CM could be optimized to
13877c478bd9Sstevel@tonic-gate 	 * re-use other ports on hcap, if the port associated with the above
13887c478bd9Sstevel@tonic-gate 	 * port_no is down. But, the issue of "reachability" needs to be
13897c478bd9Sstevel@tonic-gate 	 * handled, before selecting an alternative port different from above.
13907c478bd9Sstevel@tonic-gate 	 */
13917c478bd9Sstevel@tonic-gate 	entry = hcap->hca_port_info[port_no-1].port_qplist;
13927c478bd9Sstevel@tonic-gate 	while (entry != NULL) {
13937c478bd9Sstevel@tonic-gate 		if (entry->qp_pkey == pkey) {
13947c478bd9Sstevel@tonic-gate 			++entry->qp_ref_cnt;
13957c478bd9Sstevel@tonic-gate 			mutex_exit(&ibcm_qp_list_lock);
13967c478bd9Sstevel@tonic-gate 			return (entry);
13977c478bd9Sstevel@tonic-gate 		}
13987c478bd9Sstevel@tonic-gate 		entry = entry->qp_next;
13997c478bd9Sstevel@tonic-gate 	}
14007c478bd9Sstevel@tonic-gate 
14017c478bd9Sstevel@tonic-gate 	/*
14027c478bd9Sstevel@tonic-gate 	 * entry not found, attempt to alloc a qp
14037c478bd9Sstevel@tonic-gate 	 * This may be optimized in the future, to allocate ibmf qp's
14047c478bd9Sstevel@tonic-gate 	 * once the "CM mgmt pkeys" are precisely known.
14057c478bd9Sstevel@tonic-gate 	 */
14067c478bd9Sstevel@tonic-gate 	ibmf_status = ibmf_alloc_qp(
14077c478bd9Sstevel@tonic-gate 	    hcap->hca_port_info[port_no-1].port_ibmf_hdl, pkey, IB_GSI_QKEY,
14087c478bd9Sstevel@tonic-gate 	    IBMF_ALT_QP_MAD_NO_RMPP, &ibmf_qp);
14097c478bd9Sstevel@tonic-gate 
14107c478bd9Sstevel@tonic-gate 	if (ibmf_status != IBMF_SUCCESS) {
14117c478bd9Sstevel@tonic-gate 		mutex_exit(&ibcm_qp_list_lock);
14127c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_find_qp: failed to alloc IBMF QP"
14137c478bd9Sstevel@tonic-gate 		    "for Pkey = %x port_no = %x status = %d hcaguid = %llXp",
14147c478bd9Sstevel@tonic-gate 		    pkey, port_no, ibmf_status, hcap->hca_guid);
14157c478bd9Sstevel@tonic-gate 		/*
14167c478bd9Sstevel@tonic-gate 		 * This may be optimized in the future, so as CM would attempt
14177c478bd9Sstevel@tonic-gate 		 * to re-use other QP's whose ref cnt is 0 in the respective
14187c478bd9Sstevel@tonic-gate 		 * port_qplist, by doing an ibmf_modify_qp with pkey above.
14197c478bd9Sstevel@tonic-gate 		 */
14207c478bd9Sstevel@tonic-gate 		return (NULL);
14217c478bd9Sstevel@tonic-gate 	}
14227c478bd9Sstevel@tonic-gate 
14237c478bd9Sstevel@tonic-gate 	entry = kmem_alloc(sizeof (ibcm_qp_list_t), KM_SLEEP);
14247c478bd9Sstevel@tonic-gate 	entry->qp_next = hcap->hca_port_info[port_no-1].port_qplist;
14257c478bd9Sstevel@tonic-gate 	hcap->hca_port_info[port_no-1].port_qplist = entry;
14267c478bd9Sstevel@tonic-gate 	entry->qp_cm = ibmf_qp;
14277c478bd9Sstevel@tonic-gate 	entry->qp_ref_cnt = 1;
14287c478bd9Sstevel@tonic-gate 	entry->qp_pkey = pkey;
14297c478bd9Sstevel@tonic-gate 	entry->qp_port = &(hcap->hca_port_info[port_no-1]);
14307c478bd9Sstevel@tonic-gate 
14317c478bd9Sstevel@tonic-gate 	mutex_exit(&ibcm_qp_list_lock);
14327c478bd9Sstevel@tonic-gate 
14337c478bd9Sstevel@tonic-gate 	/* set-up the handler */
14347c478bd9Sstevel@tonic-gate 	ibmf_status = ibmf_setup_async_cb(
14357c478bd9Sstevel@tonic-gate 	    hcap->hca_port_info[port_no-1].port_ibmf_hdl, ibmf_qp,
14367c478bd9Sstevel@tonic-gate 	    ibcm_recv_cb, entry, 0);
14377c478bd9Sstevel@tonic-gate 
14387c478bd9Sstevel@tonic-gate 	ASSERT(ibmf_status == IBMF_SUCCESS);
14397c478bd9Sstevel@tonic-gate 
14407c478bd9Sstevel@tonic-gate #ifdef	DEBUG
14417c478bd9Sstevel@tonic-gate 	ibcm_query_qp(hcap->hca_port_info[port_no-1].port_ibmf_hdl, ibmf_qp);
14427c478bd9Sstevel@tonic-gate #endif
14437c478bd9Sstevel@tonic-gate 
14447c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*entry))
14457c478bd9Sstevel@tonic-gate 
14467c478bd9Sstevel@tonic-gate 	return (entry);
14477c478bd9Sstevel@tonic-gate }
14487c478bd9Sstevel@tonic-gate 
14497c478bd9Sstevel@tonic-gate void
ibcm_release_qp(ibcm_qp_list_t * cm_qp_entry)14507c478bd9Sstevel@tonic-gate ibcm_release_qp(ibcm_qp_list_t *cm_qp_entry)
14517c478bd9Sstevel@tonic-gate {
14527c478bd9Sstevel@tonic-gate 	mutex_enter(&ibcm_qp_list_lock);
14537c478bd9Sstevel@tonic-gate 	--cm_qp_entry->qp_ref_cnt;
14547c478bd9Sstevel@tonic-gate 	ASSERT(cm_qp_entry->qp_ref_cnt >= 0);
14557c478bd9Sstevel@tonic-gate 	mutex_exit(&ibcm_qp_list_lock);
14567c478bd9Sstevel@tonic-gate }
14577c478bd9Sstevel@tonic-gate 
14587c478bd9Sstevel@tonic-gate 
14597c478bd9Sstevel@tonic-gate /* called holding the ibcm_qp_list_lock mutex */
14607c478bd9Sstevel@tonic-gate ibcm_status_t
ibcm_free_qp(ibcm_qp_list_t * cm_qp_entry)14617c478bd9Sstevel@tonic-gate ibcm_free_qp(ibcm_qp_list_t *cm_qp_entry)
14627c478bd9Sstevel@tonic-gate {
14637c478bd9Sstevel@tonic-gate 	int	ibmf_status;
14647c478bd9Sstevel@tonic-gate 
14657c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_free_qp: qp_hdl %p ref_cnt %d pkey %x",
14667c478bd9Sstevel@tonic-gate 	    cm_qp_entry->qp_cm, cm_qp_entry->qp_ref_cnt, cm_qp_entry->qp_pkey);
14677c478bd9Sstevel@tonic-gate 
14687c478bd9Sstevel@tonic-gate 	/* check, there are no users of this ibmf qp */
14697c478bd9Sstevel@tonic-gate 	if (cm_qp_entry->qp_ref_cnt != 0)
14707c478bd9Sstevel@tonic-gate 		return (IBCM_FAILURE);
14717c478bd9Sstevel@tonic-gate 
14727c478bd9Sstevel@tonic-gate 	/* Tear down the receive callback */
14737c478bd9Sstevel@tonic-gate 	ibmf_status = ibmf_tear_down_async_cb(
14747c478bd9Sstevel@tonic-gate 	    cm_qp_entry->qp_port->port_ibmf_hdl, cm_qp_entry->qp_cm, 0);
14757c478bd9Sstevel@tonic-gate 	if (ibmf_status != IBMF_SUCCESS) {
14767c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_free_qp: "
14777c478bd9Sstevel@tonic-gate 		    "ibmf_tear_down_async_cb failed %d port_num %d",
14787c478bd9Sstevel@tonic-gate 		    ibmf_status, cm_qp_entry->qp_port->port_num);
14797c478bd9Sstevel@tonic-gate 		return (IBCM_FAILURE);
14807c478bd9Sstevel@tonic-gate 	}
14817c478bd9Sstevel@tonic-gate 
14827c478bd9Sstevel@tonic-gate 	ibmf_status = ibmf_free_qp(cm_qp_entry->qp_port->port_ibmf_hdl,
14837c478bd9Sstevel@tonic-gate 	    &cm_qp_entry->qp_cm, 0);
14847c478bd9Sstevel@tonic-gate 	if (ibmf_status != IBMF_SUCCESS) {
14857c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_free_qp: ibmf_free_qp failed for"
14867c478bd9Sstevel@tonic-gate 		    " ibmf_status %d qp hdl %p port_no %x", ibmf_status,
14877c478bd9Sstevel@tonic-gate 		    cm_qp_entry->qp_cm, cm_qp_entry->qp_port->port_num);
14887c478bd9Sstevel@tonic-gate 		return (IBCM_FAILURE);
14897c478bd9Sstevel@tonic-gate 	}
14907c478bd9Sstevel@tonic-gate 
14917c478bd9Sstevel@tonic-gate 	return (IBCM_SUCCESS);
14927c478bd9Sstevel@tonic-gate }
14937c478bd9Sstevel@tonic-gate 
14947c478bd9Sstevel@tonic-gate ibcm_status_t
ibcm_free_allqps(ibcm_hca_info_t * hcap,int port_no)14957c478bd9Sstevel@tonic-gate ibcm_free_allqps(ibcm_hca_info_t *hcap, int port_no)
14967c478bd9Sstevel@tonic-gate {
14977c478bd9Sstevel@tonic-gate 	ibcm_qp_list_t		*entry, *freed;
14987c478bd9Sstevel@tonic-gate 	ibcm_status_t		ibcm_status = IBCM_SUCCESS;
14997c478bd9Sstevel@tonic-gate 
15007c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_free_allqps: hcap %p port_no %d", hcap,
15017c478bd9Sstevel@tonic-gate 	    port_no);
15027c478bd9Sstevel@tonic-gate 
15037c478bd9Sstevel@tonic-gate 	mutex_enter(&ibcm_qp_list_lock);
15047c478bd9Sstevel@tonic-gate 	entry = hcap->hca_port_info[port_no-1].port_qplist;
15057c478bd9Sstevel@tonic-gate 	while ((entry != NULL) &&
15067c478bd9Sstevel@tonic-gate 	    ((ibcm_status = ibcm_free_qp(entry)) == IBCM_SUCCESS)) {
15077c478bd9Sstevel@tonic-gate 		freed = entry;
15087c478bd9Sstevel@tonic-gate 		entry = entry->qp_next;
15097c478bd9Sstevel@tonic-gate 		kmem_free(freed, sizeof (ibcm_qp_list_t));
15107c478bd9Sstevel@tonic-gate 	}
15117c478bd9Sstevel@tonic-gate 
15127c478bd9Sstevel@tonic-gate 	if (ibcm_status != IBCM_SUCCESS)	/* sanity the linked list */
15137c478bd9Sstevel@tonic-gate 		hcap->hca_port_info[port_no-1].port_qplist = entry;
15147c478bd9Sstevel@tonic-gate 	else	/* all ibmf qp's of port must have been free'd successfully */
15157c478bd9Sstevel@tonic-gate 		hcap->hca_port_info[port_no-1].port_qplist = NULL;
15167c478bd9Sstevel@tonic-gate 
15177c478bd9Sstevel@tonic-gate 	mutex_exit(&ibcm_qp_list_lock);
15187c478bd9Sstevel@tonic-gate 	return (ibcm_status);
15197c478bd9Sstevel@tonic-gate }
15207c478bd9Sstevel@tonic-gate 
15217c478bd9Sstevel@tonic-gate /*
15227c478bd9Sstevel@tonic-gate  * ibt_bind_service() and ibt_get_paths() needs the following helper function
15237c478bd9Sstevel@tonic-gate  * to handle endianess in case of Service Data.
15247c478bd9Sstevel@tonic-gate  */
15257c478bd9Sstevel@tonic-gate void
ibcm_swizzle_from_srv(ibt_srv_data_t * sb_data,uint8_t * service_bytes)15267c478bd9Sstevel@tonic-gate ibcm_swizzle_from_srv(ibt_srv_data_t *sb_data, uint8_t *service_bytes)
15277c478bd9Sstevel@tonic-gate {
15287c478bd9Sstevel@tonic-gate 	uint8_t		*p8 = service_bytes;
15297c478bd9Sstevel@tonic-gate 	uint16_t	*p16;
15307c478bd9Sstevel@tonic-gate 	uint32_t	*p32;
15317c478bd9Sstevel@tonic-gate 	uint64_t	*p64;
15327c478bd9Sstevel@tonic-gate 	int		i;
15337c478bd9Sstevel@tonic-gate 
15347c478bd9Sstevel@tonic-gate 	for (i = 0; i < 16; i++)
15357c478bd9Sstevel@tonic-gate 		*p8++ = sb_data->s_data8[i];
15367c478bd9Sstevel@tonic-gate 
15377c478bd9Sstevel@tonic-gate 	p16 = (uint16_t *)p8;
15387c478bd9Sstevel@tonic-gate 	for (i = 0; i < 8; i++)
15397c478bd9Sstevel@tonic-gate 		*p16++ = h2b16(sb_data->s_data16[i]);
15407c478bd9Sstevel@tonic-gate 
15417c478bd9Sstevel@tonic-gate 	p32 = (uint32_t *)p16;
15427c478bd9Sstevel@tonic-gate 	for (i = 0; i < 4; i++)
15437c478bd9Sstevel@tonic-gate 		*p32++ = h2b32(sb_data->s_data32[i]);
15447c478bd9Sstevel@tonic-gate 
15457c478bd9Sstevel@tonic-gate 	p64 = (uint64_t *)p32;
15467c478bd9Sstevel@tonic-gate 	for (i = 0; i < 2; i++)
15477c478bd9Sstevel@tonic-gate 		*p64++ = h2b64(sb_data->s_data64[i]);
15487c478bd9Sstevel@tonic-gate }
15497c478bd9Sstevel@tonic-gate 
15507c478bd9Sstevel@tonic-gate void
ibcm_swizzle_to_srv(uint8_t * service_bytes,ibt_srv_data_t * sb_data)15517c478bd9Sstevel@tonic-gate ibcm_swizzle_to_srv(uint8_t *service_bytes, ibt_srv_data_t *sb_data)
15527c478bd9Sstevel@tonic-gate {
15537c478bd9Sstevel@tonic-gate 	uint8_t		*p8 = service_bytes;
15547c478bd9Sstevel@tonic-gate 	uint16_t	*p16;
15557c478bd9Sstevel@tonic-gate 	uint32_t	*p32;
15567c478bd9Sstevel@tonic-gate 	uint64_t	*p64;
15577c478bd9Sstevel@tonic-gate 	int		i;
15587c478bd9Sstevel@tonic-gate 
15597c478bd9Sstevel@tonic-gate 	for (i = 0; i < 16; i++)
15607c478bd9Sstevel@tonic-gate 		sb_data->s_data8[i] = *p8++;
15617c478bd9Sstevel@tonic-gate 
15627c478bd9Sstevel@tonic-gate 	p16 = (uint16_t *)p8;
15637c478bd9Sstevel@tonic-gate 	for (i = 0; i < 8; i++)
15647c478bd9Sstevel@tonic-gate 		sb_data->s_data16[i] = h2b16(*p16++);
15657c478bd9Sstevel@tonic-gate 
15667c478bd9Sstevel@tonic-gate 	p32 = (uint32_t *)p16;
15677c478bd9Sstevel@tonic-gate 	for (i = 0; i < 4; i++)
15687c478bd9Sstevel@tonic-gate 		sb_data->s_data32[i] = h2b32(*p32++);
15697c478bd9Sstevel@tonic-gate 	p64 = (uint64_t *)p32;
15707c478bd9Sstevel@tonic-gate 
15717c478bd9Sstevel@tonic-gate 	for (i = 0; i < 2; i++)
15727c478bd9Sstevel@tonic-gate 		sb_data->s_data64[i] = h2b64(*p64++);
15737c478bd9Sstevel@tonic-gate }
15747c478bd9Sstevel@tonic-gate 
15757c478bd9Sstevel@tonic-gate /* Trace related functions */
15767c478bd9Sstevel@tonic-gate 
15777c478bd9Sstevel@tonic-gate void
ibcm_init_conn_trace(ibcm_state_data_t * sp)15787c478bd9Sstevel@tonic-gate ibcm_init_conn_trace(ibcm_state_data_t *sp)
15797c478bd9Sstevel@tonic-gate {
15807c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_init_conn_trace: statep %p", sp);
15817c478bd9Sstevel@tonic-gate 
15827c478bd9Sstevel@tonic-gate 	/* Initialize trace related fields */
15837c478bd9Sstevel@tonic-gate 
15847c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sp->conn_trace))
15857c478bd9Sstevel@tonic-gate 	sp->conn_trace = kmem_zalloc(sizeof (ibcm_conn_trace_t), KM_SLEEP);
15867c478bd9Sstevel@tonic-gate 	if ((ibcm_enable_trace & 1) == 0)
15877c478bd9Sstevel@tonic-gate 		sp->conn_trace->conn_base_tm = gethrtime();
15887c478bd9Sstevel@tonic-gate 	sp->conn_trace->conn_allocated_trcnt = ibcm_conn_max_trcnt;
15897c478bd9Sstevel@tonic-gate 	sp->conn_trace->conn_trace_events =
15907c478bd9Sstevel@tonic-gate 	    kmem_zalloc(sp->conn_trace->conn_allocated_trcnt, KM_SLEEP);
15917c478bd9Sstevel@tonic-gate 	sp->conn_trace->conn_trace_event_times =
15927c478bd9Sstevel@tonic-gate 	    kmem_zalloc(sp->conn_trace->conn_allocated_trcnt *
15937c478bd9Sstevel@tonic-gate 	    sizeof (tm_diff_type), KM_SLEEP);
15947c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*sp->conn_trace))
15957c478bd9Sstevel@tonic-gate }
15967c478bd9Sstevel@tonic-gate 
15977c478bd9Sstevel@tonic-gate void
ibcm_fini_conn_trace(ibcm_state_data_t * statep)15987c478bd9Sstevel@tonic-gate ibcm_fini_conn_trace(ibcm_state_data_t *statep)
15997c478bd9Sstevel@tonic-gate {
16007c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_fini_conn_trace: statep %p tracep %p",
16017c478bd9Sstevel@tonic-gate 	    statep, statep->conn_trace);
16027c478bd9Sstevel@tonic-gate 
16037c478bd9Sstevel@tonic-gate 	/* free the trace data */
16047c478bd9Sstevel@tonic-gate 	if (statep->conn_trace) {
16057c478bd9Sstevel@tonic-gate 		if (statep->conn_trace->conn_trace_events)
16067c478bd9Sstevel@tonic-gate 			kmem_free(statep->conn_trace->conn_trace_events,
16077c478bd9Sstevel@tonic-gate 			    statep->conn_trace->conn_allocated_trcnt);
16087c478bd9Sstevel@tonic-gate 		if (statep->conn_trace->conn_trace_event_times)
16097c478bd9Sstevel@tonic-gate 			kmem_free(statep->conn_trace->conn_trace_event_times,
16107c478bd9Sstevel@tonic-gate 			    statep->conn_trace->conn_allocated_trcnt *
16117c478bd9Sstevel@tonic-gate 			    sizeof (tm_diff_type));
16127c478bd9Sstevel@tonic-gate 
16137c478bd9Sstevel@tonic-gate 		kmem_free(statep->conn_trace, sizeof (ibcm_conn_trace_t));
16147c478bd9Sstevel@tonic-gate 	}
16157c478bd9Sstevel@tonic-gate }
16167c478bd9Sstevel@tonic-gate 
16179d3d2ed0Shiremath /* mostly used to profile connection establishment times with dtrace */
16189d3d2ed0Shiremath void
ibcm_established(hrtime_t time_diff)16199d3d2ed0Shiremath ibcm_established(hrtime_t time_diff)
16209d3d2ed0Shiremath {
16219d3d2ed0Shiremath 	if (time_diff > 1000000000LL)	/* 1 second */
16229d3d2ed0Shiremath 		IBTF_DPRINTF_L2(cmlog, "slow connection time (%d seconds)",
16239d3d2ed0Shiremath 		    (uint_t)(time_diff >> 30));
16249d3d2ed0Shiremath }
16259d3d2ed0Shiremath 
16267c478bd9Sstevel@tonic-gate void
ibcm_insert_trace(void * statep,ibcm_state_rc_trace_qualifier_t event_qualifier)16277c478bd9Sstevel@tonic-gate ibcm_insert_trace(void *statep, ibcm_state_rc_trace_qualifier_t event_qualifier)
16287c478bd9Sstevel@tonic-gate {
16297c478bd9Sstevel@tonic-gate 	ibcm_conn_trace_t	*conn_trace;
16307c478bd9Sstevel@tonic-gate 	uint8_t			conn_trace_ind;
163124b28d04Shiremath 	hrtime_t		time_diff;
163224b28d04Shiremath 	hrtime_t		hrt;
16337c478bd9Sstevel@tonic-gate 
16347c478bd9Sstevel@tonic-gate 	if (!(((ibcm_state_data_t *)statep)->conn_trace))
16357c478bd9Sstevel@tonic-gate 		return;
16367c478bd9Sstevel@tonic-gate 
16377c478bd9Sstevel@tonic-gate 	conn_trace = ((ibcm_state_data_t *)statep)->conn_trace;
16387c478bd9Sstevel@tonic-gate 
16397c478bd9Sstevel@tonic-gate 	if (!conn_trace->conn_trace_events)
16407c478bd9Sstevel@tonic-gate 		return;
16417c478bd9Sstevel@tonic-gate 
16427c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_insert_trace: statep %p event %d",
16437c478bd9Sstevel@tonic-gate 	    statep, event_qualifier);
16447c478bd9Sstevel@tonic-gate 
16457c478bd9Sstevel@tonic-gate 	mutex_enter(&ibcm_trace_mutex);
16467c478bd9Sstevel@tonic-gate 
16477c478bd9Sstevel@tonic-gate 	/* No more trace memory available, hence return */
16487c478bd9Sstevel@tonic-gate 	if (conn_trace->conn_trace_ind == conn_trace->conn_allocated_trcnt) {
16497c478bd9Sstevel@tonic-gate 		mutex_exit(&ibcm_trace_mutex);
16507c478bd9Sstevel@tonic-gate 		return;
16517c478bd9Sstevel@tonic-gate 	} else
16527c478bd9Sstevel@tonic-gate 		++conn_trace->conn_trace_ind;
16537c478bd9Sstevel@tonic-gate 
16547c478bd9Sstevel@tonic-gate 	conn_trace_ind = conn_trace->conn_trace_ind - 1;
16557c478bd9Sstevel@tonic-gate 
16567c478bd9Sstevel@tonic-gate 	conn_trace->conn_trace_events[conn_trace_ind] = event_qualifier;
16577c478bd9Sstevel@tonic-gate 
16587c478bd9Sstevel@tonic-gate 	if ((ibcm_enable_trace & 1) == 0) {
165924b28d04Shiremath 		hrt = gethrtime();
16609d3d2ed0Shiremath 		time_diff = hrt - conn_trace->conn_base_tm;
16619d3d2ed0Shiremath 		if (event_qualifier == IBCM_TRACE_CALLED_CONN_EST_EVENT)
16629d3d2ed0Shiremath 			ibcm_established(time_diff);
16639d3d2ed0Shiremath 		time_diff >>= 10;
166424b28d04Shiremath 		if (time_diff >= TM_DIFF_MAX) {
166524b28d04Shiremath 			/* RESET, future times are relative to new base time. */
166624b28d04Shiremath 			conn_trace->conn_base_tm = hrt;
16677c478bd9Sstevel@tonic-gate 			time_diff = 0;
166824b28d04Shiremath 		}
16697c478bd9Sstevel@tonic-gate 		conn_trace->conn_trace_event_times[conn_trace_ind] = time_diff;
16707c478bd9Sstevel@tonic-gate 	}
16717c478bd9Sstevel@tonic-gate 
16727c478bd9Sstevel@tonic-gate 	mutex_exit(&ibcm_trace_mutex);
16737c478bd9Sstevel@tonic-gate 
16747c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_insert_trace: statep %p inserted event %d",
16757c478bd9Sstevel@tonic-gate 	    statep, event_qualifier);
16767c478bd9Sstevel@tonic-gate }
16777c478bd9Sstevel@tonic-gate 
16787c478bd9Sstevel@tonic-gate void
ibcm_dump_conn_trace(void * statep)16797c478bd9Sstevel@tonic-gate ibcm_dump_conn_trace(void *statep)
16807c478bd9Sstevel@tonic-gate {
16817c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_dump_conn_trace: statep %p",
16827c478bd9Sstevel@tonic-gate 	    statep);
16837c478bd9Sstevel@tonic-gate 
16847c478bd9Sstevel@tonic-gate 	mutex_enter(&ibcm_trace_print_mutex);
16857c478bd9Sstevel@tonic-gate 	ibcm_debug_buf[0] = '\0';
16867c478bd9Sstevel@tonic-gate 	ibcm_dump_conn_trbuf(statep, "ibcm: ", ibcm_debug_buf,
16877c478bd9Sstevel@tonic-gate 	    IBCM_DEBUG_BUF_SIZE);
16887c478bd9Sstevel@tonic-gate 	if (ibcm_debug_buf[0] != '\0')
16897c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "\n%s", ibcm_debug_buf);
16907c478bd9Sstevel@tonic-gate 
16917c478bd9Sstevel@tonic-gate #ifdef	DEBUG
16927c478bd9Sstevel@tonic-gate 
16937c478bd9Sstevel@tonic-gate 	if (ibcm_test_mode > 1)
16947c478bd9Sstevel@tonic-gate 		cmn_err(CE_CONT, "IBCM DEBUG TRACE:\n%s", ibcm_debug_buf);
16957c478bd9Sstevel@tonic-gate #endif
16967c478bd9Sstevel@tonic-gate 
16977c478bd9Sstevel@tonic-gate 	mutex_exit(&ibcm_trace_print_mutex);
16987c478bd9Sstevel@tonic-gate }
16997c478bd9Sstevel@tonic-gate 
17007c478bd9Sstevel@tonic-gate void
ibcm_dump_conn_trbuf(void * statep,char * line_prefix,char * buf,int buf_size)17017c478bd9Sstevel@tonic-gate ibcm_dump_conn_trbuf(void *statep, char *line_prefix, char *buf, int buf_size)
17027c478bd9Sstevel@tonic-gate {
17037c478bd9Sstevel@tonic-gate 	ibcm_conn_trace_t	*conn_trace;
17047c478bd9Sstevel@tonic-gate 	int			tr_ind;
17057c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*sp;
17067c478bd9Sstevel@tonic-gate 	int	cur_size = 0;	/* size of item copied */
17077c478bd9Sstevel@tonic-gate 	int	rem_size;	/* remaining size in trace buffer */
17087c478bd9Sstevel@tonic-gate 	int	next_data = 0;	/* location where next item copied */
17097c478bd9Sstevel@tonic-gate 
17107c478bd9Sstevel@tonic-gate 	if ((buf == NULL) || (buf_size <= 0))
17117c478bd9Sstevel@tonic-gate 		return;
17127c478bd9Sstevel@tonic-gate 
17137c478bd9Sstevel@tonic-gate 	sp = (ibcm_state_data_t *)statep;
17147c478bd9Sstevel@tonic-gate 
17157c478bd9Sstevel@tonic-gate 	if (!sp->conn_trace)
17167c478bd9Sstevel@tonic-gate 		return;
17177c478bd9Sstevel@tonic-gate 
17187c478bd9Sstevel@tonic-gate 	conn_trace = sp->conn_trace;
17197c478bd9Sstevel@tonic-gate 
17207c478bd9Sstevel@tonic-gate 	if (!conn_trace->conn_trace_events)
17217c478bd9Sstevel@tonic-gate 		return;
17227c478bd9Sstevel@tonic-gate 
17237c478bd9Sstevel@tonic-gate 	rem_size = buf_size;
17247c478bd9Sstevel@tonic-gate 
17257c478bd9Sstevel@tonic-gate 	/* Print connection level global data */
17267c478bd9Sstevel@tonic-gate 
17277c478bd9Sstevel@tonic-gate 	/* Print statep, local comid, local qpn */
17287c478bd9Sstevel@tonic-gate 	cur_size = snprintf(&buf[next_data], rem_size, "%s%s0x%p\n%s%s0x%p\n"
172924b28d04Shiremath 	    "%s%s0x%x/%llx/%d\n%s%s0x%x\n%s%s0x%x/%llx\n%s%s0x%x\n%s%s%llu\n",
17307c478bd9Sstevel@tonic-gate 	    line_prefix, event_str[IBCM_DISPLAY_SID], (void *)sp,
17317c478bd9Sstevel@tonic-gate 	    line_prefix, event_str[IBCM_DISPLAY_CHAN], (void *)sp->channel,
17327c478bd9Sstevel@tonic-gate 	    line_prefix, event_str[IBCM_DISPLAY_LCID], sp->local_comid,
17337c478bd9Sstevel@tonic-gate 	    (longlong_t)sp->local_hca_guid, sp->prim_port,
17347c478bd9Sstevel@tonic-gate 	    line_prefix, event_str[IBCM_DISPLAY_LQPN], sp->local_qpn,
17357c478bd9Sstevel@tonic-gate 	    line_prefix, event_str[IBCM_DISPLAY_RCID], sp->remote_comid,
17367c478bd9Sstevel@tonic-gate 	    (longlong_t)sp->remote_hca_guid,
17377c478bd9Sstevel@tonic-gate 	    line_prefix, event_str[IBCM_DISPLAY_RQPN], sp->remote_qpn,
17387c478bd9Sstevel@tonic-gate 	    line_prefix, event_str[IBCM_DISPLAY_TM], conn_trace->conn_base_tm);
17397c478bd9Sstevel@tonic-gate 
17407c478bd9Sstevel@tonic-gate 	rem_size = rem_size - cur_size;
17417c478bd9Sstevel@tonic-gate 	if (rem_size <= 0) {
17427c478bd9Sstevel@tonic-gate 		buf[buf_size-1] = '\n';
17437c478bd9Sstevel@tonic-gate 		return;
17447c478bd9Sstevel@tonic-gate 	}
17457c478bd9Sstevel@tonic-gate 
17467c478bd9Sstevel@tonic-gate 	next_data = next_data + cur_size;
17477c478bd9Sstevel@tonic-gate 
17487c478bd9Sstevel@tonic-gate 	for (tr_ind = 0; tr_ind < conn_trace->conn_trace_ind; tr_ind++) {
17497c478bd9Sstevel@tonic-gate 		cur_size = snprintf(&buf[next_data], rem_size,
17507c478bd9Sstevel@tonic-gate 		    "%s%sTM_DIFF %u\n", line_prefix,
17517c478bd9Sstevel@tonic-gate 		    event_str[conn_trace->conn_trace_events[tr_ind]],
17527c478bd9Sstevel@tonic-gate 		    conn_trace->conn_trace_event_times[tr_ind]);
17537c478bd9Sstevel@tonic-gate 		rem_size = rem_size - cur_size;
17547c478bd9Sstevel@tonic-gate 		if (rem_size <= 0) {
17557c478bd9Sstevel@tonic-gate 			buf[buf_size-1] = '\n';
17567c478bd9Sstevel@tonic-gate 			return;
17577c478bd9Sstevel@tonic-gate 		}
17587c478bd9Sstevel@tonic-gate 		next_data = next_data + cur_size;
17597c478bd9Sstevel@tonic-gate 	}
17607c478bd9Sstevel@tonic-gate 
17617c478bd9Sstevel@tonic-gate 	buf[next_data] = '\0';
17627c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_dump_conn_trbuf: statep %p "
17637c478bd9Sstevel@tonic-gate 	    "debug buf size %d bytes", statep, next_data);
17647c478bd9Sstevel@tonic-gate }
17657c478bd9Sstevel@tonic-gate 
17667c478bd9Sstevel@tonic-gate 
17677c478bd9Sstevel@tonic-gate #ifdef	DEBUG
17687c478bd9Sstevel@tonic-gate 
17697c478bd9Sstevel@tonic-gate void
ibcm_query_qp(ibmf_handle_t ibmf_hdl,ibmf_qp_handle_t ibmf_qp)17707c478bd9Sstevel@tonic-gate ibcm_query_qp(ibmf_handle_t ibmf_hdl, ibmf_qp_handle_t ibmf_qp)
17717c478bd9Sstevel@tonic-gate {
17727c478bd9Sstevel@tonic-gate 	uint8_t		qp_port_num;
17737c478bd9Sstevel@tonic-gate 	ib_qpn_t	qp_num;
17747c478bd9Sstevel@tonic-gate 	ib_pkey_t	qp_pkey;
17757c478bd9Sstevel@tonic-gate 	ib_qkey_t	qp_qkey;
17767c478bd9Sstevel@tonic-gate 	int		ibmf_status;
17777c478bd9Sstevel@tonic-gate 
17787c478bd9Sstevel@tonic-gate 	if (ibmf_qp == IBMF_QP_HANDLE_DEFAULT) {
17797c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_query_qp: QP1");
17807c478bd9Sstevel@tonic-gate 		return;
17817c478bd9Sstevel@tonic-gate 	}
17827c478bd9Sstevel@tonic-gate 
17837c478bd9Sstevel@tonic-gate 	ibmf_status =
17847c478bd9Sstevel@tonic-gate 	    ibmf_query_qp(ibmf_hdl, ibmf_qp, &qp_num, &qp_pkey, &qp_qkey,
17857c478bd9Sstevel@tonic-gate 	    &qp_port_num, 0);
17867c478bd9Sstevel@tonic-gate 
17877c478bd9Sstevel@tonic-gate 	ASSERT(ibmf_status == IBMF_SUCCESS);
17887c478bd9Sstevel@tonic-gate 
17899d3d2ed0Shiremath 	IBTF_DPRINTF_L5(cmlog, "ibcm_query_qp: qpn %x qkey %x pkey %x port %d",
17907c478bd9Sstevel@tonic-gate 	    qp_num, qp_qkey, qp_pkey, qp_port_num);
17917c478bd9Sstevel@tonic-gate }
17927c478bd9Sstevel@tonic-gate 
17937c478bd9Sstevel@tonic-gate /*
17947c478bd9Sstevel@tonic-gate  * ibcm_dump_raw_message:
17957c478bd9Sstevel@tonic-gate  *	dumps 256 bytes of data of a raw message (REP/REQ/DREQ ...)
17967c478bd9Sstevel@tonic-gate  *	(can be called from the kernel debugger w/ the message pointer)
17977c478bd9Sstevel@tonic-gate  *
17987c478bd9Sstevel@tonic-gate  * Arguments:
17997c478bd9Sstevel@tonic-gate  *	msgp	- the messages that needs to be dumped
18007c478bd9Sstevel@tonic-gate  *
18017c478bd9Sstevel@tonic-gate  * Return values: NONE
18027c478bd9Sstevel@tonic-gate  */
18037c478bd9Sstevel@tonic-gate void
ibcm_dump_raw_message(uchar_t * c)18047c478bd9Sstevel@tonic-gate ibcm_dump_raw_message(uchar_t *c)
18057c478bd9Sstevel@tonic-gate {
18067c478bd9Sstevel@tonic-gate 	int	i;
18077c478bd9Sstevel@tonic-gate 
18087c478bd9Sstevel@tonic-gate 	for (i = 0; i < IBCM_MAD_SIZE; i += 16) {
18097c478bd9Sstevel@tonic-gate 		/* print in batches of 16 chars at a time */
18107c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog,
18117c478bd9Sstevel@tonic-gate 		    "%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
18127c478bd9Sstevel@tonic-gate 		    c[i], c[i + 1], c[i + 2], c[i + 3], c[i + 4], c[i + 5],
18137c478bd9Sstevel@tonic-gate 		    c[i + 6], c[i + 7], c[i + 8], c[i + 9], c[i + 10],
18147c478bd9Sstevel@tonic-gate 		    c[i + 11], c[i + 12], c[i + 13], c[i + 14], c[i + 15]);
18157c478bd9Sstevel@tonic-gate 	}
18167c478bd9Sstevel@tonic-gate }
18177c478bd9Sstevel@tonic-gate 
18187c478bd9Sstevel@tonic-gate 
18197c478bd9Sstevel@tonic-gate /*
18207c478bd9Sstevel@tonic-gate  * ibcm_dump_srv_rec:
18217c478bd9Sstevel@tonic-gate  *	Dumps Service Records.
18227c478bd9Sstevel@tonic-gate  *
18237c478bd9Sstevel@tonic-gate  * Arguments:
18247c478bd9Sstevel@tonic-gate  *	srv_rec	- the pointer to sa_service_record_t struct.
18257c478bd9Sstevel@tonic-gate  *
18267c478bd9Sstevel@tonic-gate  * Return values: NONE
18277c478bd9Sstevel@tonic-gate  */
18287c478bd9Sstevel@tonic-gate void
ibcm_dump_srvrec(sa_service_record_t * srv_rec)18297c478bd9Sstevel@tonic-gate ibcm_dump_srvrec(sa_service_record_t *srv_rec)
18307c478bd9Sstevel@tonic-gate {
18317c478bd9Sstevel@tonic-gate 	uint8_t		i;
18327c478bd9Sstevel@tonic-gate 
18337c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_dump_srvrec: Service Records");
18347c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "SID       : 0x%016llX", srv_rec->ServiceID);
18357c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "Svc GID   : 0x%016llX:0x%016llX",
18367c478bd9Sstevel@tonic-gate 	    srv_rec->ServiceGID.gid_prefix, srv_rec->ServiceGID.gid_guid);
18377c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "Svc PKey  : 0x%X", srv_rec->ServiceP_Key);
18387c478bd9Sstevel@tonic-gate 
18397c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "Svc Lease : 0x%lX", srv_rec->ServiceLease);
18407c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "Svc Key-hi: 0x%016llX", srv_rec->ServiceKey_hi);
18417c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "Svc Key-lo: 0x%016llX", srv_rec->ServiceKey_lo);
18427c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "Svc Name  : %s", srv_rec->ServiceName);
18437c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "Svc Data  : ");
18447c478bd9Sstevel@tonic-gate 	for (i = 0; i < IB_SVC_DATA_LEN; i += 8) {
18457c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog,
18467c478bd9Sstevel@tonic-gate 		    "\t 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X",
18477c478bd9Sstevel@tonic-gate 		    srv_rec->ServiceData[i], srv_rec->ServiceData[i+1],
18487c478bd9Sstevel@tonic-gate 		    srv_rec->ServiceData[i+2], srv_rec->ServiceData[i+3],
18497c478bd9Sstevel@tonic-gate 		    srv_rec->ServiceData[i+4], srv_rec->ServiceData[i+5],
18507c478bd9Sstevel@tonic-gate 		    srv_rec->ServiceData[i+6], srv_rec->ServiceData[i+7]);
18517c478bd9Sstevel@tonic-gate 	}
18527c478bd9Sstevel@tonic-gate }
18537c478bd9Sstevel@tonic-gate 
18547c478bd9Sstevel@tonic-gate 
18557c478bd9Sstevel@tonic-gate /*
18567c478bd9Sstevel@tonic-gate  * ibcm_dump_pathrec:
18577c478bd9Sstevel@tonic-gate  *	Dumps Path Records.
18587c478bd9Sstevel@tonic-gate  *
18597c478bd9Sstevel@tonic-gate  * Arguments:
18607c478bd9Sstevel@tonic-gate  *	path_rec - the pointer to sa_path_record_t struct.
18617c478bd9Sstevel@tonic-gate  *
18627c478bd9Sstevel@tonic-gate  * Return values: NONE
18637c478bd9Sstevel@tonic-gate  */
18647c478bd9Sstevel@tonic-gate void
ibcm_dump_pathrec(sa_path_record_t * path_rec)18657c478bd9Sstevel@tonic-gate ibcm_dump_pathrec(sa_path_record_t *path_rec)
18667c478bd9Sstevel@tonic-gate {
18677c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Path Record:");
18687c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "SGID: (sn_prefix)  %016llX",
18697c478bd9Sstevel@tonic-gate 	    path_rec->SGID.gid_prefix);
18707c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "SGID: (GUID)       %016llX",
18717c478bd9Sstevel@tonic-gate 	    path_rec->SGID.gid_guid);
18727c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "DGID: (sn_prefix)  %016llX",
18737c478bd9Sstevel@tonic-gate 	    path_rec->DGID.gid_prefix);
18747c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "DGID: (GUID)       %016llX",
18757c478bd9Sstevel@tonic-gate 	    path_rec->DGID.gid_guid);
18767c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "SLID:              %04X", path_rec->SLID);
18777c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "DLID:              %04X", path_rec->DLID);
18787c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Raw Traffic:       %01X", path_rec->RawTraffic);
18797c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Flow Label:        %05X", path_rec->FlowLabel);
18807c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Hop Limit:         %02X", path_rec->HopLimit);
18817c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "TClass:            %02X", path_rec->TClass);
18827c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Reversible:	   %01X", path_rec->Reversible);
18837c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Numb Paths:        %02d", path_rec->NumbPath);
18847c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "P_Key:             %04X", path_rec->P_Key);
18857c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "SL:                %02X", path_rec->SL);
18867c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Path MTU Selector: %01X",
18877c478bd9Sstevel@tonic-gate 	    path_rec->MtuSelector);
18887c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Path MTU:          %02X", path_rec->Mtu);
18897c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Path Rate Selector:%01X",
18907c478bd9Sstevel@tonic-gate 	    path_rec->RateSelector);
18917c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Path Rate:         %02X", path_rec->Rate);
18927c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Packet LT Selector:%01X",
18937c478bd9Sstevel@tonic-gate 	    path_rec->PacketLifeTimeSelector);
18947c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Packet Life Time:  %d (dec)",
18957c478bd9Sstevel@tonic-gate 	    path_rec->PacketLifeTime);
18967c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Preference Bit:    %02X", path_rec->Preference);
18977c478bd9Sstevel@tonic-gate }
18987c478bd9Sstevel@tonic-gate 
18997c478bd9Sstevel@tonic-gate /*
19007c478bd9Sstevel@tonic-gate  * ibcm_dump_node_rec:
19017c478bd9Sstevel@tonic-gate  *	Dumps Node Records.
19027c478bd9Sstevel@tonic-gate  *
19037c478bd9Sstevel@tonic-gate  * Arguments:
19047c478bd9Sstevel@tonic-gate  *	nrec - the pointer to sa_node_record_t struct.
19057c478bd9Sstevel@tonic-gate  *
19067c478bd9Sstevel@tonic-gate  * Return values: NONE
19077c478bd9Sstevel@tonic-gate  */
19087c478bd9Sstevel@tonic-gate void
ibcm_dump_noderec(sa_node_record_t * nrec)19097c478bd9Sstevel@tonic-gate ibcm_dump_noderec(sa_node_record_t *nrec)
19107c478bd9Sstevel@tonic-gate {
19117c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_dump_noderec: Node Info Record");
19127c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "LID       : %04X", nrec->LID);
19137c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Base Ver  : %02X", nrec->NodeInfo.BaseVersion);
19147c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Class Ver : %02X", nrec->NodeInfo.ClassVersion);
19157c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Node Type : %02d", nrec->NodeInfo.NodeType);
19167c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Num Ports : %02X", nrec->NodeInfo.NumPorts);
19177c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "SysImgGUID: %016llX",
19187c478bd9Sstevel@tonic-gate 	    nrec->NodeInfo.SystemImageGUID);
19197c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "NODE GUID : %016llX", nrec->NodeInfo.NodeGUID);
19207c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Port GUID : %016llX", nrec->NodeInfo.PortGUID);
19217c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "PartionCap: %04X", nrec->NodeInfo.PartitionCap);
19227c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Device ID : %04X", nrec->NodeInfo.DeviceID);
19237c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Revision  : %06X", nrec->NodeInfo.Revision);
19247c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "LocalPort#: %02X", nrec->NodeInfo.LocalPortNum);
19257c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Vendor ID : %06X", nrec->NodeInfo.VendorID);
19267c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "Description: %s",
19277c478bd9Sstevel@tonic-gate 	    (char *)&nrec->NodeDescription);
19287c478bd9Sstevel@tonic-gate }
19297c478bd9Sstevel@tonic-gate #endif
19307c478bd9Sstevel@tonic-gate 
1931*76c04273SRajkumar Sivaprakasam /*
1932*76c04273SRajkumar Sivaprakasam  * ibcm_ibtl_node_info:
1933*76c04273SRajkumar Sivaprakasam  *	Get the node record of the destination specified by lid via the HCA
1934*76c04273SRajkumar Sivaprakasam  *	and port specified.
1935*76c04273SRajkumar Sivaprakasam  *
1936*76c04273SRajkumar Sivaprakasam  * Arguments:
1937*76c04273SRajkumar Sivaprakasam  *	hca_guid - GUID of the local HCA.
1938*76c04273SRajkumar Sivaprakasam  *	port     - port in the HCA to be used.
1939*76c04273SRajkumar Sivaprakasam  *	lid      - destination LID
1940*76c04273SRajkumar Sivaprakasam  *	node_info_p - pointer to the Node Info to be returned.
1941*76c04273SRajkumar Sivaprakasam  *
1942*76c04273SRajkumar Sivaprakasam  * Return values:
1943*76c04273SRajkumar Sivaprakasam  * 	IBT_SUCCESS : Got the node record sucessfully
1944*76c04273SRajkumar Sivaprakasam  * 	IBT_FILURE  : Failed to get the node record.
1945*76c04273SRajkumar Sivaprakasam  */
1946*76c04273SRajkumar Sivaprakasam ibt_status_t
ibcm_ibtl_node_info(ib_guid_t hca_guid,uint8_t port,ib_lid_t lid,ibt_node_info_t * node_info_p)1947*76c04273SRajkumar Sivaprakasam ibcm_ibtl_node_info(ib_guid_t hca_guid, uint8_t port, ib_lid_t lid,
1948*76c04273SRajkumar Sivaprakasam     ibt_node_info_t *node_info_p)
1949*76c04273SRajkumar Sivaprakasam {
1950*76c04273SRajkumar Sivaprakasam 	sa_node_record_t	nr_req, *nr_resp;
1951*76c04273SRajkumar Sivaprakasam 	void			*res_p;
1952*76c04273SRajkumar Sivaprakasam 	ibmf_saa_handle_t	saa_handle;
1953*76c04273SRajkumar Sivaprakasam 	ibt_status_t		ibt_status;
1954*76c04273SRajkumar Sivaprakasam 	ibcm_hca_info_t		*hcap;
1955*76c04273SRajkumar Sivaprakasam 	uint_t			num_rec;
1956*76c04273SRajkumar Sivaprakasam 	size_t			len;
1957*76c04273SRajkumar Sivaprakasam 
1958*76c04273SRajkumar Sivaprakasam 	IBTF_DPRINTF_L3(cmlog, "ibcm_ibtl_node_info: ENTER: port %x "
1959*76c04273SRajkumar Sivaprakasam 	    "guid %llx\n", port, hca_guid);
1960*76c04273SRajkumar Sivaprakasam 
1961*76c04273SRajkumar Sivaprakasam 	hcap = ibcm_find_hca_entry(hca_guid);
1962*76c04273SRajkumar Sivaprakasam 	if (hcap == NULL) {
1963*76c04273SRajkumar Sivaprakasam 		IBTF_DPRINTF_L2(cmlog, "ibcm_ibtl_node_info: "
1964*76c04273SRajkumar Sivaprakasam 		    "HCA(%llX) info not found", hca_guid);
1965*76c04273SRajkumar Sivaprakasam 		return (IBT_FAILURE);
1966*76c04273SRajkumar Sivaprakasam 	}
1967*76c04273SRajkumar Sivaprakasam 
1968*76c04273SRajkumar Sivaprakasam 	/* Get SA Access Handle. */
1969*76c04273SRajkumar Sivaprakasam 	saa_handle = ibcm_get_saa_handle(hcap, port);
1970*76c04273SRajkumar Sivaprakasam 	if (saa_handle == NULL) {
1971*76c04273SRajkumar Sivaprakasam 		IBTF_DPRINTF_L2(cmlog, "ibcm_ibtl_node_info: "
1972*76c04273SRajkumar Sivaprakasam 		    "Port %d of HCA (%llX) is NOT ACTIVE", port, hca_guid);
1973*76c04273SRajkumar Sivaprakasam 		ibcm_dec_hca_acc_cnt(hcap);
1974*76c04273SRajkumar Sivaprakasam 		return (IBT_FAILURE);
1975*76c04273SRajkumar Sivaprakasam 	}
1976*76c04273SRajkumar Sivaprakasam 
1977*76c04273SRajkumar Sivaprakasam 	/* Retrieve Node Records from SA Access. */
1978*76c04273SRajkumar Sivaprakasam 	bzero(&nr_req, sizeof (sa_node_record_t));
1979*76c04273SRajkumar Sivaprakasam 	nr_req.LID =  lid;
1980*76c04273SRajkumar Sivaprakasam 
1981*76c04273SRajkumar Sivaprakasam 	ibt_status = ibcm_get_node_rec(saa_handle, &nr_req,
1982*76c04273SRajkumar Sivaprakasam 	    SA_NODEINFO_COMPMASK_NODELID, &res_p, &len);
1983*76c04273SRajkumar Sivaprakasam 	if (ibt_status != IBT_SUCCESS) {
1984*76c04273SRajkumar Sivaprakasam 		IBTF_DPRINTF_L2(cmlog, "ibcm_ibtl_node_info: "
1985*76c04273SRajkumar Sivaprakasam 		    "failed (%d) to get Node records", ibt_status);
1986*76c04273SRajkumar Sivaprakasam 		ibcm_dec_hca_acc_cnt(hcap);
1987*76c04273SRajkumar Sivaprakasam 		return (IBT_FAILURE);
1988*76c04273SRajkumar Sivaprakasam 	}
1989*76c04273SRajkumar Sivaprakasam 
1990*76c04273SRajkumar Sivaprakasam 	num_rec = len/sizeof (sa_node_record_t);
1991*76c04273SRajkumar Sivaprakasam 	nr_resp = (sa_node_record_t *)(uchar_t *)res_p;
1992*76c04273SRajkumar Sivaprakasam 
1993*76c04273SRajkumar Sivaprakasam 	if ((nr_resp != NULL) && (num_rec > 0)) {
1994*76c04273SRajkumar Sivaprakasam 		IBCM_DUMP_NODE_REC(nr_resp);
1995*76c04273SRajkumar Sivaprakasam 
1996*76c04273SRajkumar Sivaprakasam 		_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(
1997*76c04273SRajkumar Sivaprakasam 		    *node_info_p))
1998*76c04273SRajkumar Sivaprakasam 
1999*76c04273SRajkumar Sivaprakasam 		node_info_p->n_sys_img_guid =
2000*76c04273SRajkumar Sivaprakasam 		    nr_resp->NodeInfo.SystemImageGUID;
2001*76c04273SRajkumar Sivaprakasam 		node_info_p->n_node_guid =
2002*76c04273SRajkumar Sivaprakasam 		    nr_resp->NodeInfo.NodeGUID;
2003*76c04273SRajkumar Sivaprakasam 		node_info_p->n_port_guid =
2004*76c04273SRajkumar Sivaprakasam 		    nr_resp->NodeInfo.PortGUID;
2005*76c04273SRajkumar Sivaprakasam 		node_info_p->n_dev_id =
2006*76c04273SRajkumar Sivaprakasam 		    nr_resp->NodeInfo.DeviceID;
2007*76c04273SRajkumar Sivaprakasam 		node_info_p->n_revision =
2008*76c04273SRajkumar Sivaprakasam 		    nr_resp->NodeInfo.Revision;
2009*76c04273SRajkumar Sivaprakasam 		node_info_p->n_vendor_id =
2010*76c04273SRajkumar Sivaprakasam 		    nr_resp->NodeInfo.VendorID;
2011*76c04273SRajkumar Sivaprakasam 		node_info_p->n_num_ports =
2012*76c04273SRajkumar Sivaprakasam 		    nr_resp->NodeInfo.NumPorts;
2013*76c04273SRajkumar Sivaprakasam 		node_info_p->n_port_num =
2014*76c04273SRajkumar Sivaprakasam 		    nr_resp->NodeInfo.LocalPortNum;
2015*76c04273SRajkumar Sivaprakasam 		node_info_p->n_node_type =
2016*76c04273SRajkumar Sivaprakasam 		    nr_resp->NodeInfo.NodeType;
2017*76c04273SRajkumar Sivaprakasam 		(void) strncpy(node_info_p->n_description,
2018*76c04273SRajkumar Sivaprakasam 		    (char *)&nr_resp->NodeDescription, 64);
2019*76c04273SRajkumar Sivaprakasam 		_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(
2020*76c04273SRajkumar Sivaprakasam 		    *node_info_p))
2021*76c04273SRajkumar Sivaprakasam 
2022*76c04273SRajkumar Sivaprakasam 
2023*76c04273SRajkumar Sivaprakasam 		kmem_free(nr_resp, len);
2024*76c04273SRajkumar Sivaprakasam 	}
2025*76c04273SRajkumar Sivaprakasam 	ibcm_dec_hca_acc_cnt(hcap);
2026*76c04273SRajkumar Sivaprakasam 	return (IBT_SUCCESS);
2027*76c04273SRajkumar Sivaprakasam }
20287c478bd9Sstevel@tonic-gate 
20297c478bd9Sstevel@tonic-gate /*
20307c478bd9Sstevel@tonic-gate  * ibcm_ibmf_analyze_error:
20317c478bd9Sstevel@tonic-gate  *	Checks IBMF status and determines appropriate ibt status.
20327c478bd9Sstevel@tonic-gate  *
20337c478bd9Sstevel@tonic-gate  * Arguments:
20347c478bd9Sstevel@tonic-gate  *	ibmf_status - IBMF Status
20357c478bd9Sstevel@tonic-gate  *
20367c478bd9Sstevel@tonic-gate  * Return values:
20377c478bd9Sstevel@tonic-gate  *	ibt_status_t
20387c478bd9Sstevel@tonic-gate  */
20397c478bd9Sstevel@tonic-gate ibt_status_t
ibcm_ibmf_analyze_error(int ibmf_status)20407c478bd9Sstevel@tonic-gate ibcm_ibmf_analyze_error(int ibmf_status)
20417c478bd9Sstevel@tonic-gate {
20427c478bd9Sstevel@tonic-gate 	if (ibt_check_failure(ibmf_status, NULL) != IBT_FAILURE_STANDARD) {
20437c478bd9Sstevel@tonic-gate 		/*
20447c478bd9Sstevel@tonic-gate 		 * IBMF specific failure, return special error code
20457c478bd9Sstevel@tonic-gate 		 * to the client so that it can retrieve any associated ENA.
20467c478bd9Sstevel@tonic-gate 		 */
20477c478bd9Sstevel@tonic-gate 		return (ibmf_status);
2048ae0581d1SShantkumar Hiremath 	} else if (ibmf_status == IBMF_TRANS_TIMEOUT) {
2049ae0581d1SShantkumar Hiremath 		return (IBT_IBMF_TIMEOUT);
20507c478bd9Sstevel@tonic-gate 	} else {
20517c478bd9Sstevel@tonic-gate 		/*
20527c478bd9Sstevel@tonic-gate 		 * IBMF failed for some other reason, invalid arguments etc.
20537c478bd9Sstevel@tonic-gate 		 * Analyze, log ENA with IBTF and obtain a special ibt_status_t
20547c478bd9Sstevel@tonic-gate 		 * that indicates IBMF failure.
20557c478bd9Sstevel@tonic-gate 		 */
20567c478bd9Sstevel@tonic-gate 		if ((ibmf_status == IBMF_BAD_CLASS) ||
20577c478bd9Sstevel@tonic-gate 		    (ibmf_status == IBMF_BAD_HANDLE) ||
20587c478bd9Sstevel@tonic-gate 		    (ibmf_status == IBMF_BAD_QP_HANDLE) ||
20597c478bd9Sstevel@tonic-gate 		    (ibmf_status == IBMF_BAD_NODE) ||
20607c478bd9Sstevel@tonic-gate 		    (ibmf_status == IBMF_BAD_PORT) ||
20617c478bd9Sstevel@tonic-gate 		    (ibmf_status == IBMF_BAD_VERSION) ||
20627c478bd9Sstevel@tonic-gate 		    (ibmf_status == IBMF_BAD_FLAGS) ||
20637c478bd9Sstevel@tonic-gate 		    (ibmf_status == IBMF_BAD_SIZE) ||
20647c478bd9Sstevel@tonic-gate 		    (ibmf_status == IBMF_INVALID_GID) ||
20657c478bd9Sstevel@tonic-gate 		    (ibmf_status == IBMF_INVALID_ARG) ||
20667c478bd9Sstevel@tonic-gate 		    (ibmf_status == IBMF_INVALID_FIELD) ||
20677c478bd9Sstevel@tonic-gate 		    (ibmf_status == IBMF_UNSUPP_METHOD) ||
20687c478bd9Sstevel@tonic-gate 		    (ibmf_status == IBMF_UNSUPP_METHOD_ATTR)) {
20697c478bd9Sstevel@tonic-gate 
20707c478bd9Sstevel@tonic-gate 			/*
20717c478bd9Sstevel@tonic-gate 			 * These errors, we should not see...
20727c478bd9Sstevel@tonic-gate 			 * something really bad happened!.
20737c478bd9Sstevel@tonic-gate 			 */
20747c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_ibmf_analyze_error: "
20757c478bd9Sstevel@tonic-gate 			    "Unexpected ERROR from IBMF - %d", ibmf_status);
20767c478bd9Sstevel@tonic-gate 		}
20777c478bd9Sstevel@tonic-gate 		return (ibt_get_module_failure(IBT_FAILURE_IBMF, 0));
20787c478bd9Sstevel@tonic-gate 	}
20797c478bd9Sstevel@tonic-gate }
2080