xref: /onnv-gate/usr/src/uts/common/io/ib/ibtl/ibtl_cm.c (revision 9349:af3421bbd991)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
52840Scarlsonj  * Common Development and Distribution License (the "License").
62840Scarlsonj  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*9349SShantkumar.Hiremath@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #include <sys/ib/ibtl/impl/ibtl.h>
270Sstevel@tonic-gate #include <sys/ib/ibtl/impl/ibtl_cm.h>
280Sstevel@tonic-gate 
290Sstevel@tonic-gate /*
300Sstevel@tonic-gate  * ibtl_cm.c
310Sstevel@tonic-gate  *    These routines tie the Communication Manager into IBTL.
320Sstevel@tonic-gate  */
330Sstevel@tonic-gate 
340Sstevel@tonic-gate /*
350Sstevel@tonic-gate  * Globals.
360Sstevel@tonic-gate  */
370Sstevel@tonic-gate static char 		ibtf_cm[] = "ibtl_cm";
380Sstevel@tonic-gate boolean_t		ibtl_fast_gid_cache_valid = B_FALSE;
390Sstevel@tonic-gate 
400Sstevel@tonic-gate /*
410Sstevel@tonic-gate  * Function:
420Sstevel@tonic-gate  *	ibtl_cm_set_chan_private
430Sstevel@tonic-gate  * Input:
440Sstevel@tonic-gate  *	chan		Channel Handle.
450Sstevel@tonic-gate  *	cm_private	CM private data.
460Sstevel@tonic-gate  * Output:
470Sstevel@tonic-gate  *	none.
480Sstevel@tonic-gate  * Returns:
490Sstevel@tonic-gate  *	none.
500Sstevel@tonic-gate  * Description:
510Sstevel@tonic-gate  *	A helper function to store CM's Private data in the specified channel.
520Sstevel@tonic-gate  */
530Sstevel@tonic-gate void
ibtl_cm_set_chan_private(ibt_channel_hdl_t chan,void * cm_private)540Sstevel@tonic-gate ibtl_cm_set_chan_private(ibt_channel_hdl_t chan, void *cm_private)
550Sstevel@tonic-gate {
560Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_set_chan_private(%p, %p)",
570Sstevel@tonic-gate 	    chan, cm_private);
580Sstevel@tonic-gate 
590Sstevel@tonic-gate 	mutex_enter(&chan->ch_cm_mutex);
600Sstevel@tonic-gate 	chan->ch_cm_private = cm_private;
610Sstevel@tonic-gate 	if (cm_private == NULL)
620Sstevel@tonic-gate 		cv_signal(&chan->ch_cm_cv);
630Sstevel@tonic-gate 	mutex_exit(&chan->ch_cm_mutex);
640Sstevel@tonic-gate }
650Sstevel@tonic-gate 
660Sstevel@tonic-gate 
670Sstevel@tonic-gate /*
680Sstevel@tonic-gate  * Function:
690Sstevel@tonic-gate  *	ibtl_cm_get_chan_private
700Sstevel@tonic-gate  * Input:
710Sstevel@tonic-gate  *	chan		Channel Handle.
720Sstevel@tonic-gate  * Output:
730Sstevel@tonic-gate  *	cm_private_p	The CM private data.
740Sstevel@tonic-gate  * Returns:
750Sstevel@tonic-gate  *	CM private data.
760Sstevel@tonic-gate  * Description:
770Sstevel@tonic-gate  *	A helper function to get CM's Private data for the specified channel.
780Sstevel@tonic-gate  */
790Sstevel@tonic-gate void *
ibtl_cm_get_chan_private(ibt_channel_hdl_t chan)800Sstevel@tonic-gate ibtl_cm_get_chan_private(ibt_channel_hdl_t chan)
810Sstevel@tonic-gate {
820Sstevel@tonic-gate 	void *cm_private;
830Sstevel@tonic-gate 
840Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_get_chan_private(%p)", chan);
850Sstevel@tonic-gate 	mutex_enter(&chan->ch_cm_mutex);
860Sstevel@tonic-gate 	cm_private = chan->ch_cm_private;
870Sstevel@tonic-gate #ifndef __lock_lint
880Sstevel@tonic-gate 	/* IBCM will call the release function if cm_private is non-NULL */
890Sstevel@tonic-gate 	if (cm_private == NULL)
900Sstevel@tonic-gate #endif
910Sstevel@tonic-gate 		mutex_exit(&chan->ch_cm_mutex);
920Sstevel@tonic-gate 	return (cm_private);
930Sstevel@tonic-gate }
940Sstevel@tonic-gate 
950Sstevel@tonic-gate void
ibtl_cm_release_chan_private(ibt_channel_hdl_t chan)960Sstevel@tonic-gate ibtl_cm_release_chan_private(ibt_channel_hdl_t chan)
970Sstevel@tonic-gate {
980Sstevel@tonic-gate #ifndef __lock_lint
990Sstevel@tonic-gate 	mutex_exit(&chan->ch_cm_mutex);
1000Sstevel@tonic-gate #endif
1010Sstevel@tonic-gate }
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate void
ibtl_cm_wait_chan_private(ibt_channel_hdl_t chan)1040Sstevel@tonic-gate ibtl_cm_wait_chan_private(ibt_channel_hdl_t chan)
1050Sstevel@tonic-gate {
1060Sstevel@tonic-gate 	mutex_enter(&chan->ch_cm_mutex);
1070Sstevel@tonic-gate 	if (chan->ch_cm_private != NULL)
1080Sstevel@tonic-gate 		cv_wait(&chan->ch_cm_cv, &chan->ch_cm_mutex);
1090Sstevel@tonic-gate 	mutex_exit(&chan->ch_cm_mutex);
1100Sstevel@tonic-gate 	delay(drv_usectohz(50000));
1110Sstevel@tonic-gate }
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate 
1140Sstevel@tonic-gate /*
1150Sstevel@tonic-gate  * Function:
1160Sstevel@tonic-gate  *	ibtl_cm_get_chan_type
1170Sstevel@tonic-gate  * Input:
1180Sstevel@tonic-gate  *	chan		Channel Handle.
1190Sstevel@tonic-gate  * Output:
1200Sstevel@tonic-gate  *	none.
1210Sstevel@tonic-gate  * Returns:
1220Sstevel@tonic-gate  *	Channel transport type.
1230Sstevel@tonic-gate  * Description:
1240Sstevel@tonic-gate  *	A helper function to get channel transport type.
1250Sstevel@tonic-gate  */
1260Sstevel@tonic-gate ibt_tran_srv_t
ibtl_cm_get_chan_type(ibt_channel_hdl_t chan)1270Sstevel@tonic-gate ibtl_cm_get_chan_type(ibt_channel_hdl_t chan)
1280Sstevel@tonic-gate {
1290Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_get_chan_type(%p)", chan);
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 	return (chan->ch_qp.qp_type);
1320Sstevel@tonic-gate }
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate /*
1350Sstevel@tonic-gate  * Function:
1360Sstevel@tonic-gate  *	ibtl_cm_change_service_cnt
1370Sstevel@tonic-gate  * Input:
1380Sstevel@tonic-gate  *	ibt_hdl		Client's IBT Handle.
1390Sstevel@tonic-gate  *	delta_num_sids	The change in the number of service ids
1400Sstevel@tonic-gate  *			(positive for ibt_register_service() and
1410Sstevel@tonic-gate  *			negative fo ibt_service_deregister()).
1420Sstevel@tonic-gate  */
1430Sstevel@tonic-gate void
ibtl_cm_change_service_cnt(ibt_clnt_hdl_t ibt_hdl,int delta_num_sids)1440Sstevel@tonic-gate ibtl_cm_change_service_cnt(ibt_clnt_hdl_t ibt_hdl, int delta_num_sids)
1450Sstevel@tonic-gate {
1460Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_change_service_cnt(%p. %d)",
1470Sstevel@tonic-gate 	    ibt_hdl, delta_num_sids);
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate 	mutex_enter(&ibtl_clnt_list_mutex);
1500Sstevel@tonic-gate 	if ((delta_num_sids < 0) && (-delta_num_sids > ibt_hdl->clnt_srv_cnt)) {
1510Sstevel@tonic-gate 		IBTF_DPRINTF_L2(ibtf_cm, "ibtl_cm_change_service_cnt: "
1520Sstevel@tonic-gate 		    "ERROR: service registration counter underflow\n"
1530Sstevel@tonic-gate 		    "current count = %d, requested delta = %d",
1540Sstevel@tonic-gate 		    ibt_hdl->clnt_srv_cnt, delta_num_sids);
1550Sstevel@tonic-gate 	}
1560Sstevel@tonic-gate 	ibt_hdl->clnt_srv_cnt += delta_num_sids;
1570Sstevel@tonic-gate 	mutex_exit(&ibtl_clnt_list_mutex);
1580Sstevel@tonic-gate }
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate /*
1620Sstevel@tonic-gate  * Function:
1630Sstevel@tonic-gate  *	ibtl_cm_get_hca_port
1640Sstevel@tonic-gate  * Input:
1650Sstevel@tonic-gate  *	gid		Source GID.
1660Sstevel@tonic-gate  *	hca_guid	Optional source HCA GUID on which SGID is available.
1670Sstevel@tonic-gate  *			Ignored if zero.
1680Sstevel@tonic-gate  * Output:
1690Sstevel@tonic-gate  *	hca_port	Pointer to ibtl_cm_hca_port_t struct.
1700Sstevel@tonic-gate  * Returns:
1710Sstevel@tonic-gate  *	IBT_SUCCESS.
1720Sstevel@tonic-gate  * Description:
1730Sstevel@tonic-gate  *	A helper function to get HCA node GUID, Base LID, SGID Index,
1740Sstevel@tonic-gate  *	port number, LMC and MTU for the specified SGID.
1750Sstevel@tonic-gate  *	Also filling default SGID, to be used in ibmf_sa_session_open.
1760Sstevel@tonic-gate  */
1770Sstevel@tonic-gate ibt_status_t
ibtl_cm_get_hca_port(ib_gid_t gid,ib_guid_t hca_guid,ibtl_cm_hca_port_t * hca_port)1780Sstevel@tonic-gate ibtl_cm_get_hca_port(ib_gid_t gid, ib_guid_t hca_guid,
1790Sstevel@tonic-gate     ibtl_cm_hca_port_t *hca_port)
1800Sstevel@tonic-gate {
1810Sstevel@tonic-gate 	ibtl_hca_devinfo_t	*hca_devp;	/* HCA Dev Info */
1820Sstevel@tonic-gate 	ibt_hca_portinfo_t	*portinfop;
1830Sstevel@tonic-gate 	uint_t			ports, port;
1840Sstevel@tonic-gate 	uint_t			i;
1850Sstevel@tonic-gate 	ib_gid_t		*sgid;
1860Sstevel@tonic-gate 	static ib_gid_t		fast_gid;	/* fast_gid_cache data */
1870Sstevel@tonic-gate 	static uint8_t		fast_sgid_ix;
1880Sstevel@tonic-gate 	static ibt_hca_portinfo_t *fast_portinfop;
1890Sstevel@tonic-gate 	static ib_guid_t	fast_node_guid;
1900Sstevel@tonic-gate 	static ib_guid_t	fast_port_guid;
1910Sstevel@tonic-gate 
1920Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_get_hca_port(%llX:%llX, %llX)",
1930Sstevel@tonic-gate 	    gid.gid_prefix, gid.gid_guid, hca_guid);
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate 	if ((gid.gid_prefix == 0) || (gid.gid_guid == 0)) {
1960Sstevel@tonic-gate 		IBTF_DPRINTF_L2(ibtf_cm, "ibtl_cm_get_hca_port: "
1970Sstevel@tonic-gate 		    "NULL SGID specified.");
1980Sstevel@tonic-gate 		return (IBT_INVALID_PARAM);
1990Sstevel@tonic-gate 	}
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 	mutex_enter(&ibtl_clnt_list_mutex);
2020Sstevel@tonic-gate 
2030Sstevel@tonic-gate 	if ((ibtl_fast_gid_cache_valid == B_TRUE) &&
2040Sstevel@tonic-gate 	    (gid.gid_guid == fast_gid.gid_guid) &&
2050Sstevel@tonic-gate 	    (gid.gid_prefix == fast_gid.gid_prefix)) {
2060Sstevel@tonic-gate 
2070Sstevel@tonic-gate 		if ((hca_guid != 0) && (hca_guid != fast_node_guid)) {
2080Sstevel@tonic-gate 			IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_get_hca_port: "
2090Sstevel@tonic-gate 			    "Mis-match hca_guid v/s sgid combination.");
2100Sstevel@tonic-gate 			mutex_exit(&ibtl_clnt_list_mutex);
2110Sstevel@tonic-gate 			return (IBT_INVALID_PARAM);
2120Sstevel@tonic-gate 		}
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate 		portinfop = fast_portinfop;
2150Sstevel@tonic-gate 		hca_port->hp_base_lid = portinfop->p_base_lid;
2160Sstevel@tonic-gate 		hca_port->hp_port = portinfop->p_port_num;
2170Sstevel@tonic-gate 		hca_port->hp_sgid_ix = fast_sgid_ix;
2180Sstevel@tonic-gate 		hca_port->hp_lmc = portinfop->p_lmc;
2190Sstevel@tonic-gate 		hca_port->hp_mtu = portinfop->p_mtu;
2200Sstevel@tonic-gate 		hca_port->hp_hca_guid = fast_node_guid;
2210Sstevel@tonic-gate 		hca_port->hp_port_guid = fast_port_guid;
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate 		mutex_exit(&ibtl_clnt_list_mutex);
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate 		return (IBT_SUCCESS);
2260Sstevel@tonic-gate 	}
2270Sstevel@tonic-gate 
2280Sstevel@tonic-gate 	/* If HCA GUID is specified, then lookup in that device only. */
2290Sstevel@tonic-gate 	if (hca_guid) {
2300Sstevel@tonic-gate 		hca_devp = ibtl_get_hcadevinfo(hca_guid);
2310Sstevel@tonic-gate 	} else {
2320Sstevel@tonic-gate 		hca_devp = ibtl_hca_list;
2330Sstevel@tonic-gate 	}
2340Sstevel@tonic-gate 
2350Sstevel@tonic-gate 	while (hca_devp != NULL) {
2360Sstevel@tonic-gate 
2370Sstevel@tonic-gate 		ports = hca_devp->hd_hca_attr->hca_nports;
2380Sstevel@tonic-gate 		portinfop = hca_devp->hd_portinfop;
2390Sstevel@tonic-gate 
2400Sstevel@tonic-gate 		for (port = 0; port < ports; port++, portinfop++) {
2410Sstevel@tonic-gate 			if (portinfop->p_linkstate != IBT_PORT_ACTIVE)
2420Sstevel@tonic-gate 				continue;
2430Sstevel@tonic-gate 			sgid = &portinfop->p_sgid_tbl[0];
2440Sstevel@tonic-gate 			for (i = 0; i < portinfop->p_sgid_tbl_sz; i++, sgid++) {
2450Sstevel@tonic-gate 				if ((gid.gid_guid != sgid->gid_guid) ||
2460Sstevel@tonic-gate 				    (gid.gid_prefix != sgid->gid_prefix))
2470Sstevel@tonic-gate 					continue;
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate 				/*
2500Sstevel@tonic-gate 				 * Found the matching GID.
2510Sstevel@tonic-gate 				 */
2520Sstevel@tonic-gate 				ibtl_fast_gid_cache_valid = B_TRUE;
2530Sstevel@tonic-gate 				fast_gid = gid;
2540Sstevel@tonic-gate 				fast_portinfop = portinfop;
2550Sstevel@tonic-gate 				fast_node_guid = hca_port->hp_hca_guid =
2560Sstevel@tonic-gate 				    hca_devp->hd_hca_attr->hca_node_guid;
2570Sstevel@tonic-gate 				fast_sgid_ix = hca_port->hp_sgid_ix = i;
2580Sstevel@tonic-gate 				fast_port_guid =
2590Sstevel@tonic-gate 				    portinfop->p_sgid_tbl[0].gid_guid;
2600Sstevel@tonic-gate 				hca_port->hp_port_guid = fast_port_guid;
2610Sstevel@tonic-gate 				hca_port->hp_base_lid = portinfop->p_base_lid;
2620Sstevel@tonic-gate 				hca_port->hp_port = portinfop->p_port_num;
2630Sstevel@tonic-gate 				hca_port->hp_lmc = portinfop->p_lmc;
2640Sstevel@tonic-gate 				hca_port->hp_mtu = portinfop->p_mtu;
2650Sstevel@tonic-gate 
2660Sstevel@tonic-gate 				mutex_exit(&ibtl_clnt_list_mutex);
2670Sstevel@tonic-gate 
2680Sstevel@tonic-gate 				return (IBT_SUCCESS);
2690Sstevel@tonic-gate 			}
2700Sstevel@tonic-gate 		}
2710Sstevel@tonic-gate 
2720Sstevel@tonic-gate 		/* Asked to look in the specified HCA device only?. */
2730Sstevel@tonic-gate 		if (hca_guid)
2740Sstevel@tonic-gate 			break;
2750Sstevel@tonic-gate 
2760Sstevel@tonic-gate 		/* Get next in the list */
2770Sstevel@tonic-gate 		hca_devp = hca_devp->hd_hca_dev_link;
2780Sstevel@tonic-gate 	}
2790Sstevel@tonic-gate 
2800Sstevel@tonic-gate 	mutex_exit(&ibtl_clnt_list_mutex);
2810Sstevel@tonic-gate 
2820Sstevel@tonic-gate 	/* If we are here, then we failed to get a match, so return error. */
2830Sstevel@tonic-gate 	return (IBT_INVALID_PARAM);
2840Sstevel@tonic-gate }
2850Sstevel@tonic-gate 
2860Sstevel@tonic-gate 
2870Sstevel@tonic-gate static ibt_status_t
ibtl_cm_get_cnt(ibt_path_attr_t * attr,ibt_path_flags_t flags,ibtl_cm_port_list_t * plistp,uint_t * count)2880Sstevel@tonic-gate ibtl_cm_get_cnt(ibt_path_attr_t *attr, ibt_path_flags_t flags,
2890Sstevel@tonic-gate     ibtl_cm_port_list_t *plistp, uint_t *count)
2900Sstevel@tonic-gate {
2910Sstevel@tonic-gate 	ibtl_hca_devinfo_t	*hdevp;
2920Sstevel@tonic-gate 	ibt_hca_portinfo_t	*pinfop;
2930Sstevel@tonic-gate 	ib_guid_t		hca_guid, tmp_hca_guid = 0;
2940Sstevel@tonic-gate 	ib_gid_t		gid;
2951093Shiremath 	uint_t			pcount = 0, tmp_pcount = 0;
2960Sstevel@tonic-gate 	uint_t			cnt = *count;
2970Sstevel@tonic-gate 	ibt_status_t		retval = IBT_SUCCESS;
2980Sstevel@tonic-gate 	uint_t			i, j;
2990Sstevel@tonic-gate 
3000Sstevel@tonic-gate 	*count = 0;
3010Sstevel@tonic-gate 
3020Sstevel@tonic-gate 	/* If HCA GUID is specified, then lookup in that device only. */
3030Sstevel@tonic-gate 	if (attr->pa_hca_guid) {
3040Sstevel@tonic-gate 		hdevp = ibtl_get_hcadevinfo(attr->pa_hca_guid);
3050Sstevel@tonic-gate 	} else {
3060Sstevel@tonic-gate 		hdevp = ibtl_hca_list;
3070Sstevel@tonic-gate 	}
3080Sstevel@tonic-gate 
3090Sstevel@tonic-gate 	while (hdevp != NULL) {
3100Sstevel@tonic-gate 		hca_guid = hdevp->hd_hca_attr->hca_node_guid;
3110Sstevel@tonic-gate 
3120Sstevel@tonic-gate 		if ((flags & IBT_PATH_APM) &&
3130Sstevel@tonic-gate 		    (!(hdevp->hd_hca_attr->hca_flags &
3140Sstevel@tonic-gate 		    IBT_HCA_AUTO_PATH_MIG))) {
3150Sstevel@tonic-gate 
3160Sstevel@tonic-gate 			IBTF_DPRINTF_L2(ibtf_cm, "ibtl_cm_get_cnt: "
3170Sstevel@tonic-gate 			    "HCA (%llX) - APM NOT SUPPORTED ", hca_guid);
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate 			retval = IBT_APM_NOT_SUPPORTED;
3200Sstevel@tonic-gate 
3210Sstevel@tonic-gate 			if (attr->pa_hca_guid)
3220Sstevel@tonic-gate 				break;
3237354SGiri.Adari@Sun.COM 			goto search_next;
3240Sstevel@tonic-gate 		}
3250Sstevel@tonic-gate 
3260Sstevel@tonic-gate 		for (i = 0; i < hdevp->hd_hca_attr->hca_nports; i++) {
3270Sstevel@tonic-gate 
3280Sstevel@tonic-gate 			if ((attr->pa_hca_port_num) &&
3290Sstevel@tonic-gate 			    (attr->pa_hca_port_num != (i + 1))) {
3300Sstevel@tonic-gate 				IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_get_cnt: "
3310Sstevel@tonic-gate 				    "Asked only on Port# %d, so skip this "
3320Sstevel@tonic-gate 				    "port(%d)", attr->pa_hca_port_num, (i + 1));
3330Sstevel@tonic-gate 				continue;
3340Sstevel@tonic-gate 			}
3350Sstevel@tonic-gate 			pinfop = hdevp->hd_portinfop + i;
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate 			if (pinfop->p_linkstate != IBT_PORT_ACTIVE) {
3380Sstevel@tonic-gate 				retval = IBT_HCA_PORT_NOT_ACTIVE;
3390Sstevel@tonic-gate 				continue;
3400Sstevel@tonic-gate 			}
3410Sstevel@tonic-gate 			if (attr->pa_mtu.r_mtu) {
3420Sstevel@tonic-gate 				if ((attr->pa_mtu.r_selector == IBT_GT) &&
3430Sstevel@tonic-gate 				    (attr->pa_mtu.r_mtu >= pinfop->p_mtu))
3440Sstevel@tonic-gate 					continue;
3450Sstevel@tonic-gate 				else if ((attr->pa_mtu.r_selector == IBT_EQU) &&
3460Sstevel@tonic-gate 				    (attr->pa_mtu.r_mtu > pinfop->p_mtu))
3470Sstevel@tonic-gate 					continue;
3480Sstevel@tonic-gate 			}
3490Sstevel@tonic-gate 
3507354SGiri.Adari@Sun.COM 			if ((flags & IBT_PATH_APM) && (!attr->pa_hca_guid) &&
3517354SGiri.Adari@Sun.COM 			    attr->pa_sgid.gid_prefix &&
3527354SGiri.Adari@Sun.COM 			    attr->pa_sgid.gid_guid) {
3537354SGiri.Adari@Sun.COM 				for (j = 0; j < pinfop->p_sgid_tbl_sz; j++) {
3547354SGiri.Adari@Sun.COM 					gid = pinfop->p_sgid_tbl[j];
3557354SGiri.Adari@Sun.COM 					if (gid.gid_prefix && gid.gid_guid) {
3567354SGiri.Adari@Sun.COM 						if ((attr->pa_sgid.gid_prefix !=
3577354SGiri.Adari@Sun.COM 						    gid.gid_prefix) ||
3587354SGiri.Adari@Sun.COM 						    (attr->pa_sgid.gid_guid !=
3597354SGiri.Adari@Sun.COM 						    gid.gid_guid)) {
3607354SGiri.Adari@Sun.COM 							continue;
3617354SGiri.Adari@Sun.COM 						} else {
3627354SGiri.Adari@Sun.COM 							attr->pa_hca_guid =
3637354SGiri.Adari@Sun.COM 							    hca_guid;
3647354SGiri.Adari@Sun.COM 							goto got_apm_hca_info;
3657354SGiri.Adari@Sun.COM 						}
3667354SGiri.Adari@Sun.COM 					}
3677354SGiri.Adari@Sun.COM 				}
3687703SPavan.Chandrashekar@Sun.COM 				continue;
3697354SGiri.Adari@Sun.COM 			}
3707354SGiri.Adari@Sun.COM got_apm_hca_info:
3710Sstevel@tonic-gate 			for (j = 0; j < pinfop->p_sgid_tbl_sz; j++) {
3720Sstevel@tonic-gate 				gid = pinfop->p_sgid_tbl[j];
3730Sstevel@tonic-gate 				if (gid.gid_prefix && gid.gid_guid) {
3744703Shiremath 					if (!(flags & IBT_PATH_APM) &&
3754703Shiremath 					    attr->pa_sgid.gid_prefix &&
3764703Shiremath 					    attr->pa_sgid.gid_guid) {
3774703Shiremath 						if ((attr->pa_sgid.gid_prefix !=
3784703Shiremath 						    gid.gid_prefix) ||
3794703Shiremath 						    (attr->pa_sgid.gid_guid !=
3804703Shiremath 						    gid.gid_guid))
3814703Shiremath 							continue;
3824703Shiremath 					}
3830Sstevel@tonic-gate 					pcount++;
3840Sstevel@tonic-gate 					if (plistp) {
3850Sstevel@tonic-gate 						plistp->p_hca_guid = hca_guid;
3860Sstevel@tonic-gate 						plistp->p_mtu = pinfop->p_mtu;
3870Sstevel@tonic-gate 						plistp->p_base_lid =
3880Sstevel@tonic-gate 						    pinfop->p_base_lid;
3890Sstevel@tonic-gate 						plistp->p_port_num =
3900Sstevel@tonic-gate 						    pinfop->p_port_num;
3910Sstevel@tonic-gate 						plistp->p_sgid_ix = j;
3920Sstevel@tonic-gate 						plistp->p_sgid = gid;
3930Sstevel@tonic-gate 						plistp->p_count = cnt;
394401Shiremath 						if (hdevp->hd_multism)
395401Shiremath 							plistp->p_multi |=
396401Shiremath 							    IBTL_CM_MULTI_SM;
3970Sstevel@tonic-gate 
3980Sstevel@tonic-gate 						IBTF_DPRINTF_L3(ibtf_cm,
3990Sstevel@tonic-gate 						    "ibtl_cm_get_cnt: HCA"
4000Sstevel@tonic-gate 						    "(%llX,%d) SGID(%llX:%llX)",
4010Sstevel@tonic-gate 						    plistp->p_hca_guid,
4020Sstevel@tonic-gate 						    plistp->p_port_num,
4030Sstevel@tonic-gate 						    plistp->p_sgid.gid_prefix,
4040Sstevel@tonic-gate 						    plistp->p_sgid.gid_guid);
4050Sstevel@tonic-gate 
4060Sstevel@tonic-gate 						plistp++;
4070Sstevel@tonic-gate 					}
4080Sstevel@tonic-gate 				}
4090Sstevel@tonic-gate 			}
4100Sstevel@tonic-gate 		}
4110Sstevel@tonic-gate 		/* Asked to look in the specified HCA device only?. */
4120Sstevel@tonic-gate 		if (attr->pa_hca_guid)
4130Sstevel@tonic-gate 			break;
4140Sstevel@tonic-gate 
4150Sstevel@tonic-gate 		if (flags & IBT_PATH_APM) {
4160Sstevel@tonic-gate 			if (pcount == 2) {
4170Sstevel@tonic-gate 				attr->pa_hca_guid = hca_guid;
4180Sstevel@tonic-gate 				break;
4190Sstevel@tonic-gate 			} else if (pcount == 1) {
4200Sstevel@tonic-gate 				if (hdevp->hd_hca_dev_link) {
4210Sstevel@tonic-gate 					tmp_hca_guid = hca_guid;
4221093Shiremath 					tmp_pcount = pcount;
4230Sstevel@tonic-gate 					pcount = 0;
4240Sstevel@tonic-gate 				} else if (tmp_hca_guid) {
4250Sstevel@tonic-gate 					attr->pa_hca_guid = tmp_hca_guid;
4260Sstevel@tonic-gate 				} else {
4270Sstevel@tonic-gate 					attr->pa_hca_guid = hca_guid;
4280Sstevel@tonic-gate 				}
4291093Shiremath 			} else if ((pcount == 0) && (tmp_hca_guid)) {
430401Shiremath 				attr->pa_hca_guid = tmp_hca_guid;
4311093Shiremath 				pcount = tmp_pcount;
4320Sstevel@tonic-gate 			}
4330Sstevel@tonic-gate 		}
4347354SGiri.Adari@Sun.COM search_next:
4350Sstevel@tonic-gate 		hdevp = hdevp->hd_hca_dev_link;
4360Sstevel@tonic-gate 	}
4370Sstevel@tonic-gate 
4380Sstevel@tonic-gate 	*count = pcount;
4390Sstevel@tonic-gate 
4400Sstevel@tonic-gate 	if (pcount) {
4410Sstevel@tonic-gate 		retval = IBT_SUCCESS;
4420Sstevel@tonic-gate 	} else {
4430Sstevel@tonic-gate 		IBTF_DPRINTF_L2(ibtf_cm, "ibtl_cm_get_cnt: "
4440Sstevel@tonic-gate 		    "Appropriate Source Points NOT found");
4450Sstevel@tonic-gate 		if (retval == IBT_SUCCESS)
4460Sstevel@tonic-gate 			retval = IBT_NO_HCAS_AVAILABLE;
4470Sstevel@tonic-gate 	}
4480Sstevel@tonic-gate 
4490Sstevel@tonic-gate 	return (retval);
4500Sstevel@tonic-gate }
4510Sstevel@tonic-gate 
4520Sstevel@tonic-gate 
4530Sstevel@tonic-gate ibt_status_t
ibtl_cm_get_active_plist(ibt_path_attr_t * attr,ibt_path_flags_t flags,ibtl_cm_port_list_t ** port_list_p)4540Sstevel@tonic-gate ibtl_cm_get_active_plist(ibt_path_attr_t *attr, ibt_path_flags_t flags,
4550Sstevel@tonic-gate     ibtl_cm_port_list_t **port_list_p)
4560Sstevel@tonic-gate {
4570Sstevel@tonic-gate 	ibtl_cm_port_list_t	*p_listp, tmp;
4580Sstevel@tonic-gate 	uint_t			i, j;
4590Sstevel@tonic-gate 	uint_t			count, rcount;
460401Shiremath 	boolean_t		multi_hca = B_FALSE;
4610Sstevel@tonic-gate 	ibt_status_t		retval = IBT_SUCCESS;
4620Sstevel@tonic-gate 
4630Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_get_active_plist(%p, %X)",
4640Sstevel@tonic-gate 	    attr, flags);
4650Sstevel@tonic-gate 
4660Sstevel@tonic-gate get_plist_start:
4670Sstevel@tonic-gate 	*port_list_p = NULL;
4680Sstevel@tonic-gate 
4690Sstevel@tonic-gate 	/* Get "number of active src points" so that we can allocate memory. */
4700Sstevel@tonic-gate 	mutex_enter(&ibtl_clnt_list_mutex);
4710Sstevel@tonic-gate 	retval = ibtl_cm_get_cnt(attr, flags, NULL, &count);
4720Sstevel@tonic-gate 	mutex_exit(&ibtl_clnt_list_mutex);
4730Sstevel@tonic-gate 
4740Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_get_active_plist: Found %d SrcPoint",
4750Sstevel@tonic-gate 	    count);
4760Sstevel@tonic-gate 	if (retval != IBT_SUCCESS)
4770Sstevel@tonic-gate 		return (retval);
4780Sstevel@tonic-gate 
4790Sstevel@tonic-gate 	/* Allocate Memory to hold Src Point information. */
4800Sstevel@tonic-gate 	p_listp = kmem_zalloc(count * sizeof (ibtl_cm_port_list_t), KM_SLEEP);
4810Sstevel@tonic-gate 
4820Sstevel@tonic-gate 	/*
4830Sstevel@tonic-gate 	 * Verify that the count we got previously is still valid, as we had
4840Sstevel@tonic-gate 	 * dropped mutex to allocate memory. If not, restart the process.
4850Sstevel@tonic-gate 	 */
4860Sstevel@tonic-gate 	mutex_enter(&ibtl_clnt_list_mutex);
4870Sstevel@tonic-gate 	retval = ibtl_cm_get_cnt(attr, flags, NULL, &rcount);
4880Sstevel@tonic-gate 	if (retval != IBT_SUCCESS) {
4890Sstevel@tonic-gate 		mutex_exit(&ibtl_clnt_list_mutex);
4900Sstevel@tonic-gate 		kmem_free(p_listp, count * sizeof (ibtl_cm_port_list_t));
4910Sstevel@tonic-gate 		return (retval);
4920Sstevel@tonic-gate 	} else if (rcount != count) {
4930Sstevel@tonic-gate 		mutex_exit(&ibtl_clnt_list_mutex);
4940Sstevel@tonic-gate 		kmem_free(p_listp, count * sizeof (ibtl_cm_port_list_t));
4950Sstevel@tonic-gate 		goto get_plist_start;
4960Sstevel@tonic-gate 	}
4970Sstevel@tonic-gate 
4980Sstevel@tonic-gate 	*port_list_p = p_listp;
4990Sstevel@tonic-gate 	/*
5000Sstevel@tonic-gate 	 * Src count hasn't changed, still holding the lock fill-in the
5010Sstevel@tonic-gate 	 * required source point information.
5020Sstevel@tonic-gate 	 */
5030Sstevel@tonic-gate 	retval = ibtl_cm_get_cnt(attr, flags, p_listp, &rcount);
5040Sstevel@tonic-gate 	mutex_exit(&ibtl_clnt_list_mutex);
5050Sstevel@tonic-gate 	if (retval != IBT_SUCCESS) {
5060Sstevel@tonic-gate 		kmem_free(p_listp, count * sizeof (ibtl_cm_port_list_t));
5070Sstevel@tonic-gate 		*port_list_p = NULL;
5080Sstevel@tonic-gate 		return (retval);
5090Sstevel@tonic-gate 	}
5100Sstevel@tonic-gate 
5110Sstevel@tonic-gate 	p_listp = *port_list_p;
5120Sstevel@tonic-gate 
5130Sstevel@tonic-gate 	_NOTE(NO_COMPETING_THREADS_NOW)
5140Sstevel@tonic-gate 
515401Shiremath 	for (i = 0; i < count - 1; i++) {
516401Shiremath 		for (j = 0; j < count - 1 - i; j++) {
517401Shiremath 			if (p_listp[j].p_hca_guid != p_listp[j+1].p_hca_guid) {
518401Shiremath 				multi_hca = B_TRUE;
519401Shiremath 				break;
520401Shiremath 			}
521401Shiremath 		}
522401Shiremath 		if (multi_hca == B_TRUE)
523401Shiremath 			break;
524401Shiremath 	}
525401Shiremath 
526401Shiremath 	if (multi_hca == B_TRUE)
527401Shiremath 		for (i = 0; i < count; i++)
528401Shiremath 			p_listp[i].p_multi |= IBTL_CM_MULTI_HCA;
529401Shiremath 
5300Sstevel@tonic-gate 	/*
5310Sstevel@tonic-gate 	 * Sort (bubble sort) the list based on MTU quality (higher on top).
5320Sstevel@tonic-gate 	 * Sorting is only performed, if IBT_PATH_AVAIL is set.
5330Sstevel@tonic-gate 	 */
5340Sstevel@tonic-gate 	if (((attr->pa_mtu.r_selector == IBT_GT) || (flags & IBT_PATH_AVAIL)) &&
5350Sstevel@tonic-gate 	    (!(flags & IBT_PATH_APM))) {
5360Sstevel@tonic-gate 		for (i = 0; i < count - 1; i++) {
5370Sstevel@tonic-gate 			for (j = 0; j < count - 1 - i; j++) {
5380Sstevel@tonic-gate 				if (p_listp[j].p_mtu < p_listp[j+1].p_mtu) {
5390Sstevel@tonic-gate 					tmp = p_listp[j];
5400Sstevel@tonic-gate 					p_listp[j] = p_listp[j+1];
5410Sstevel@tonic-gate 					p_listp[j+1] = tmp;
5420Sstevel@tonic-gate 				}
5430Sstevel@tonic-gate 			}
5440Sstevel@tonic-gate 		}
5450Sstevel@tonic-gate 	}
5460Sstevel@tonic-gate 
547401Shiremath 	if ((p_listp->p_multi & IBTL_CM_MULTI_HCA) &&
548401Shiremath 	    (flags & IBT_PATH_AVAIL) && (!(flags & IBT_PATH_APM))) {
5490Sstevel@tonic-gate 		/* Avoid having same HCA next to each other in the list. */
5500Sstevel@tonic-gate 		for (i = 0; i < count - 1; i++) {
5510Sstevel@tonic-gate 			for (j = 0; j < (count - 1 - i); j++) {
5520Sstevel@tonic-gate 				if ((p_listp[j].p_hca_guid ==
5530Sstevel@tonic-gate 				    p_listp[j+1].p_hca_guid) &&
5540Sstevel@tonic-gate 				    (j+2 < count)) {
5550Sstevel@tonic-gate 					tmp = p_listp[j+1];
5560Sstevel@tonic-gate 					p_listp[j+1] = p_listp[j+2];
5570Sstevel@tonic-gate 					p_listp[j+2] = tmp;
5580Sstevel@tonic-gate 				}
5590Sstevel@tonic-gate 			}
5600Sstevel@tonic-gate 		}
5610Sstevel@tonic-gate 	}
5620Sstevel@tonic-gate 
5630Sstevel@tonic-gate 	/*
5640Sstevel@tonic-gate 	 * If SGID is specified, then make sure that SGID info is first
5650Sstevel@tonic-gate 	 * in the array.
5660Sstevel@tonic-gate 	 */
5670Sstevel@tonic-gate 	if (attr->pa_sgid.gid_guid && (p_listp->p_count > 1) &&
5680Sstevel@tonic-gate 	    (p_listp[0].p_sgid.gid_guid != attr->pa_sgid.gid_guid)) {
5690Sstevel@tonic-gate 		for (i = 1; i < count; i++) {
5700Sstevel@tonic-gate 			if (p_listp[i].p_sgid.gid_guid ==
5710Sstevel@tonic-gate 			    attr->pa_sgid.gid_guid) {
5720Sstevel@tonic-gate 				tmp = p_listp[i];
5730Sstevel@tonic-gate 				p_listp[i] = p_listp[0];
5740Sstevel@tonic-gate 				p_listp[0] = tmp;
5750Sstevel@tonic-gate 			}
5760Sstevel@tonic-gate 		}
5770Sstevel@tonic-gate 	}
5780Sstevel@tonic-gate 
5792840Scarlsonj #ifndef lint
5800Sstevel@tonic-gate 	_NOTE(COMPETING_THREADS_NOW)
5812840Scarlsonj #endif
5820Sstevel@tonic-gate 
5830Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_get_active_plist: "
5840Sstevel@tonic-gate 	    "Returned <%d> entries @0x%p", count, *port_list_p);
5850Sstevel@tonic-gate 
5860Sstevel@tonic-gate 	return (retval);
5870Sstevel@tonic-gate }
5880Sstevel@tonic-gate 
5890Sstevel@tonic-gate 
5900Sstevel@tonic-gate void
ibtl_cm_free_active_plist(ibtl_cm_port_list_t * plist)5910Sstevel@tonic-gate ibtl_cm_free_active_plist(ibtl_cm_port_list_t *plist)
5920Sstevel@tonic-gate {
5930Sstevel@tonic-gate 	int count;
5940Sstevel@tonic-gate 
5950Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_free_active_plist(%p)", plist);
5960Sstevel@tonic-gate 
5970Sstevel@tonic-gate 	if (plist != NULL) {
5980Sstevel@tonic-gate 		_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*plist))
5990Sstevel@tonic-gate 		count = plist->p_count;
6000Sstevel@tonic-gate 		_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*plist))
6010Sstevel@tonic-gate 
6020Sstevel@tonic-gate 		kmem_free(plist, count * sizeof (ibtl_cm_port_list_t));
6030Sstevel@tonic-gate 	}
6040Sstevel@tonic-gate }
6050Sstevel@tonic-gate 
6060Sstevel@tonic-gate /*
6070Sstevel@tonic-gate  * Function:
6080Sstevel@tonic-gate  *	ibtl_cm_get_1st_full_pkey_ix
6090Sstevel@tonic-gate  * Input:
6100Sstevel@tonic-gate  *	hca_guid	HCA GUID.
6110Sstevel@tonic-gate  *	port		Port Number.
6120Sstevel@tonic-gate  * Output:
6130Sstevel@tonic-gate  *	None.
6140Sstevel@tonic-gate  * Returns:
6150Sstevel@tonic-gate  *	P_Key Index of the first full member available from the P_Key table
6160Sstevel@tonic-gate  *	of the specified HCA<->Port.
6170Sstevel@tonic-gate  * Description:
6180Sstevel@tonic-gate  *	A helper function to get P_Key Index of the first full member P_Key
6190Sstevel@tonic-gate  *	available on the specified HCA and Port combination.
6200Sstevel@tonic-gate  */
6210Sstevel@tonic-gate uint16_t
ibtl_cm_get_1st_full_pkey_ix(ib_guid_t hca_guid,uint8_t port)6220Sstevel@tonic-gate ibtl_cm_get_1st_full_pkey_ix(ib_guid_t hca_guid, uint8_t port)
6230Sstevel@tonic-gate {
6240Sstevel@tonic-gate 	ibtl_hca_devinfo_t	*hca_devp;	/* HCA Dev Info */
6250Sstevel@tonic-gate 	uint16_t		pkey_ix = 0;
6260Sstevel@tonic-gate 
6270Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_get_1st_full_pkey_ix(%llX, %d)",
6280Sstevel@tonic-gate 	    hca_guid, port);
6290Sstevel@tonic-gate 
6300Sstevel@tonic-gate 	mutex_enter(&ibtl_clnt_list_mutex);
6310Sstevel@tonic-gate 	hca_devp = ibtl_get_hcadevinfo(hca_guid);
6320Sstevel@tonic-gate 
6330Sstevel@tonic-gate 	if ((hca_devp != NULL) && (port <= hca_devp->hd_hca_attr->hca_nports) &&
6340Sstevel@tonic-gate 	    (port != 0)) {
6350Sstevel@tonic-gate 		pkey_ix = hca_devp->hd_portinfop[port - 1].p_def_pkey_ix;
6360Sstevel@tonic-gate 	} else {
6370Sstevel@tonic-gate 		IBTF_DPRINTF_L2(ibtf_cm, "ibtl_cm_get_1st_full_pkey_ix: "
6380Sstevel@tonic-gate 		    "Invalid HCA (%llX), Port (%d) specified.", hca_guid, port);
6390Sstevel@tonic-gate 	}
6400Sstevel@tonic-gate 	mutex_exit(&ibtl_clnt_list_mutex);
6410Sstevel@tonic-gate 
6420Sstevel@tonic-gate 	return (pkey_ix);
6430Sstevel@tonic-gate }
6440Sstevel@tonic-gate 
6450Sstevel@tonic-gate 
6460Sstevel@tonic-gate ibt_status_t
ibtl_cm_get_local_comp_gids(ib_guid_t hca_guid,ib_gid_t gid,ib_gid_t ** gids_p,uint_t * num_gids_p)6470Sstevel@tonic-gate ibtl_cm_get_local_comp_gids(ib_guid_t hca_guid, ib_gid_t gid, ib_gid_t **gids_p,
6480Sstevel@tonic-gate     uint_t *num_gids_p)
6490Sstevel@tonic-gate {
6500Sstevel@tonic-gate 	ibtl_hca_devinfo_t	*hdevp;	/* HCA Dev Info */
6510Sstevel@tonic-gate 	ibt_hca_portinfo_t	*pinfop;
6520Sstevel@tonic-gate 	ib_gid_t		sgid;
6530Sstevel@tonic-gate 	ib_gid_t		*gidp = NULL;
6540Sstevel@tonic-gate 	int			i, j, k;
6550Sstevel@tonic-gate 	int			count = 0;
6560Sstevel@tonic-gate 	int			gid_specified;
6570Sstevel@tonic-gate 
6580Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_get_local_comp_gids(%llX, %llX:%llX)",
6590Sstevel@tonic-gate 	    hca_guid, gid.gid_prefix, gid.gid_guid);
6600Sstevel@tonic-gate 
6610Sstevel@tonic-gate 	mutex_enter(&ibtl_clnt_list_mutex);
6620Sstevel@tonic-gate 	hdevp = ibtl_get_hcadevinfo(hca_guid);
6630Sstevel@tonic-gate 
6640Sstevel@tonic-gate 	if (hdevp == NULL) {
6650Sstevel@tonic-gate 		IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_get_local_comp_gids: ",
6660Sstevel@tonic-gate 		    "NO HCA (%llX) availble", hca_guid);
6670Sstevel@tonic-gate 		mutex_exit(&ibtl_clnt_list_mutex);
6680Sstevel@tonic-gate 		return (IBT_NO_HCAS_AVAILABLE);
6690Sstevel@tonic-gate 	}
6700Sstevel@tonic-gate 
6710Sstevel@tonic-gate 	if (gid.gid_prefix && gid.gid_guid)
6720Sstevel@tonic-gate 		gid_specified = 1;
6730Sstevel@tonic-gate 	else
6740Sstevel@tonic-gate 		gid_specified = 0;
6750Sstevel@tonic-gate 
6760Sstevel@tonic-gate 	for (i = 0; i < hdevp->hd_hca_attr->hca_nports; i++) {
6770Sstevel@tonic-gate 		pinfop = hdevp->hd_portinfop + i;
6780Sstevel@tonic-gate 
6790Sstevel@tonic-gate 		if (pinfop->p_linkstate != IBT_PORT_ACTIVE)
6800Sstevel@tonic-gate 			continue;
6810Sstevel@tonic-gate 
6820Sstevel@tonic-gate 		for (j = 0; j < pinfop->p_sgid_tbl_sz; j++) {
6830Sstevel@tonic-gate 			sgid = pinfop->p_sgid_tbl[j];
6840Sstevel@tonic-gate 			if (sgid.gid_prefix && sgid.gid_guid) {
6850Sstevel@tonic-gate 				if (gid_specified &&
6860Sstevel@tonic-gate 				    ((gid.gid_prefix == sgid.gid_prefix) &&
6870Sstevel@tonic-gate 				    (gid.gid_guid == sgid.gid_guid))) {
6880Sstevel@tonic-gate 					/*
6890Sstevel@tonic-gate 					 * Don't return the input specified
6900Sstevel@tonic-gate 					 * GID
6910Sstevel@tonic-gate 					 */
6920Sstevel@tonic-gate 					continue;
6930Sstevel@tonic-gate 				}
6940Sstevel@tonic-gate 				count++;
6950Sstevel@tonic-gate 			}
6960Sstevel@tonic-gate 		}
6970Sstevel@tonic-gate 	}
6980Sstevel@tonic-gate 
6990Sstevel@tonic-gate 	if (count == 0) {
7000Sstevel@tonic-gate 		IBTF_DPRINTF_L2(ibtf_cm, "ibtl_cm_get_local_comp_gids: "
7010Sstevel@tonic-gate 		    "Companion GIDs not available");
7020Sstevel@tonic-gate 		mutex_exit(&ibtl_clnt_list_mutex);
7030Sstevel@tonic-gate 		return (IBT_GIDS_NOT_FOUND);
7040Sstevel@tonic-gate 	}
7050Sstevel@tonic-gate 
7060Sstevel@tonic-gate 	gidp = kmem_zalloc(count * sizeof (ib_gid_t), KM_SLEEP);
7070Sstevel@tonic-gate 	*num_gids_p = count;
7080Sstevel@tonic-gate 	*gids_p = gidp;
7090Sstevel@tonic-gate 	k = 0;
7100Sstevel@tonic-gate 
7110Sstevel@tonic-gate 	for (i = 0; i < hdevp->hd_hca_attr->hca_nports; i++) {
7120Sstevel@tonic-gate 		pinfop = hdevp->hd_portinfop + i;
7130Sstevel@tonic-gate 
7140Sstevel@tonic-gate 		if (pinfop->p_linkstate != IBT_PORT_ACTIVE)
7150Sstevel@tonic-gate 			continue;
7160Sstevel@tonic-gate 
7170Sstevel@tonic-gate 		for (j = 0; j < pinfop->p_sgid_tbl_sz; j++) {
7180Sstevel@tonic-gate 			sgid = pinfop->p_sgid_tbl[j];
7190Sstevel@tonic-gate 			if (sgid.gid_prefix && sgid.gid_guid) {
7200Sstevel@tonic-gate 				if (gid_specified &&
7210Sstevel@tonic-gate 				    ((gid.gid_prefix == sgid.gid_prefix) &&
7220Sstevel@tonic-gate 				    (gid.gid_guid == sgid.gid_guid)))
7230Sstevel@tonic-gate 					continue;
7240Sstevel@tonic-gate 
7250Sstevel@tonic-gate 				gidp[k].gid_prefix = sgid.gid_prefix;
7260Sstevel@tonic-gate 				gidp[k].gid_guid = sgid.gid_guid;
7270Sstevel@tonic-gate 
7280Sstevel@tonic-gate 				IBTF_DPRINTF_L3(ibtf_cm,
7290Sstevel@tonic-gate 				    "ibtl_cm_get_local_comp_gids: GID[%d]="
7300Sstevel@tonic-gate 				    "%llX:%llX", k, gidp[k].gid_prefix,
7310Sstevel@tonic-gate 				    gidp[k].gid_guid);
7320Sstevel@tonic-gate 				k++;
7330Sstevel@tonic-gate 				if (k == count)
7340Sstevel@tonic-gate 					break;
7350Sstevel@tonic-gate 			}
7360Sstevel@tonic-gate 		}
7370Sstevel@tonic-gate 		if (k == count)
7380Sstevel@tonic-gate 			break;
7390Sstevel@tonic-gate 	}
7400Sstevel@tonic-gate 	mutex_exit(&ibtl_clnt_list_mutex);
7410Sstevel@tonic-gate 
7420Sstevel@tonic-gate 	return (IBT_SUCCESS);
7430Sstevel@tonic-gate }
7440Sstevel@tonic-gate 
7450Sstevel@tonic-gate 
7460Sstevel@tonic-gate int
ibtl_cm_is_multi_sm(ib_guid_t hca_guid)7470Sstevel@tonic-gate ibtl_cm_is_multi_sm(ib_guid_t hca_guid)
7480Sstevel@tonic-gate {
7490Sstevel@tonic-gate 	ibtl_hca_devinfo_t	*hdevp;	/* HCA Dev Info */
7500Sstevel@tonic-gate 	uint_t			multi_sm;
7510Sstevel@tonic-gate 
7520Sstevel@tonic-gate 	mutex_enter(&ibtl_clnt_list_mutex);
7530Sstevel@tonic-gate 	hdevp = ibtl_get_hcadevinfo(hca_guid);
7540Sstevel@tonic-gate 	if (hdevp == NULL) {
7550Sstevel@tonic-gate 		IBTF_DPRINTF_L2(ibtf_cm, "ibtl_cm_is_multi_sm: NO HCA (%llX) "
7560Sstevel@tonic-gate 		    "availble", hca_guid);
7570Sstevel@tonic-gate 		mutex_exit(&ibtl_clnt_list_mutex);
7580Sstevel@tonic-gate 		return (-1);
7590Sstevel@tonic-gate 	}
7600Sstevel@tonic-gate 	multi_sm = hdevp->hd_multism;
7610Sstevel@tonic-gate 	mutex_exit(&ibtl_clnt_list_mutex);
7620Sstevel@tonic-gate 
7630Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_is_multi_sm(%llX): %d", hca_guid,
7640Sstevel@tonic-gate 	    multi_sm);
7650Sstevel@tonic-gate 
7660Sstevel@tonic-gate 	return (multi_sm);
7670Sstevel@tonic-gate }
768*9349SShantkumar.Hiremath@Sun.COM 
769*9349SShantkumar.Hiremath@Sun.COM char *
ibtl_cm_get_clnt_name(ibt_clnt_hdl_t ibt_hdl)770*9349SShantkumar.Hiremath@Sun.COM ibtl_cm_get_clnt_name(ibt_clnt_hdl_t ibt_hdl)
771*9349SShantkumar.Hiremath@Sun.COM {
772*9349SShantkumar.Hiremath@Sun.COM 	if (ibt_hdl)
773*9349SShantkumar.Hiremath@Sun.COM 		return (ibt_hdl->clnt_name);
774*9349SShantkumar.Hiremath@Sun.COM 	else
775*9349SShantkumar.Hiremath@Sun.COM 		return (NULL);
776*9349SShantkumar.Hiremath@Sun.COM }
777