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
54703Shiremath * Common Development and Distribution License (the "License").
64703Shiremath * 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 /*
229335SShantkumar.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 /*
270Sstevel@tonic-gate * ibcm_utils.c
280Sstevel@tonic-gate *
290Sstevel@tonic-gate * contains internal lookup functions of IB CM module
300Sstevel@tonic-gate * along with some other miscellaneous stuff
310Sstevel@tonic-gate *
320Sstevel@tonic-gate * TBD:
330Sstevel@tonic-gate * 1. Code needed to ensure that if any clients are using a service then
340Sstevel@tonic-gate * don't de-register it.
350Sstevel@tonic-gate */
360Sstevel@tonic-gate
370Sstevel@tonic-gate #include <sys/ib/mgt/ibcm/ibcm_impl.h>
380Sstevel@tonic-gate #include <sys/ddi.h>
390Sstevel@tonic-gate
400Sstevel@tonic-gate
410Sstevel@tonic-gate /* statics */
420Sstevel@tonic-gate static vmem_t *ibcm_local_sid_arena;
434703Shiremath static vmem_t *ibcm_ip_sid_arena;
440Sstevel@tonic-gate static ib_svc_id_t ibcm_local_sid_seed;
450Sstevel@tonic-gate static ib_com_id_t ibcm_local_cid_seed;
460Sstevel@tonic-gate _NOTE(READ_ONLY_DATA({ibcm_local_sid_arena ibcm_local_sid_seed
474703Shiremath ibcm_ip_sid_arena ibcm_local_cid_seed}))
480Sstevel@tonic-gate static void ibcm_delete_state_from_avl(ibcm_state_data_t *statep);
490Sstevel@tonic-gate static void ibcm_init_conn_trace(ibcm_state_data_t *statep);
500Sstevel@tonic-gate static void ibcm_fini_conn_trace(ibcm_state_data_t *statep);
510Sstevel@tonic-gate static void ibcm_dump_conn_trbuf(void *statep, char *line_prefix,
520Sstevel@tonic-gate char *buf, int buf_size);
53*9891SRajkumar.Sivaprakasam@Sun.COM extern ibt_status_t ibcm_get_node_rec(ibmf_saa_handle_t, sa_node_record_t *,
54*9891SRajkumar.Sivaprakasam@Sun.COM uint64_t c_mask, void *, size_t *);
550Sstevel@tonic-gate
560Sstevel@tonic-gate /*
570Sstevel@tonic-gate * ibcm_lookup_msg:
580Sstevel@tonic-gate *
590Sstevel@tonic-gate * Retrieves an existing state structure or creates a new one if none found.
600Sstevel@tonic-gate * This function is used during
610Sstevel@tonic-gate * Passive connection side for INCOMING REQ/REJ/RTU/MRA/DREQ/DREP/LAP msgs
620Sstevel@tonic-gate * Active connection side for INCOMING REP/REJ/MRA/DREQ/DREP/APR msgs
630Sstevel@tonic-gate * Active side CM for outgoing REQ message.
640Sstevel@tonic-gate *
650Sstevel@tonic-gate * NOTE: Only return IBCM_LOOKUP_FAIL if lookup failed to find a match.
660Sstevel@tonic-gate *
670Sstevel@tonic-gate * Arguments are:-
680Sstevel@tonic-gate * event_type - type of message
690Sstevel@tonic-gate * incoming REQ, REP, REJ, MRA, RTU
700Sstevel@tonic-gate * remote_qpn - Remote QP number
710Sstevel@tonic-gate * comid - local/remote comid
720Sstevel@tonic-gate * remote_hca_guid - Remote HCA GUID
730Sstevel@tonic-gate * hcap - HCA entry ptr
740Sstevel@tonic-gate * rstatep - return statep pointer
750Sstevel@tonic-gate *
760Sstevel@tonic-gate * Return Values:
770Sstevel@tonic-gate * IBCM_LOOKUP_NEW - new statep allocated
780Sstevel@tonic-gate * IBCM_LOOKUP_EXISTS - found an existing entry
790Sstevel@tonic-gate * IBCM_LOOKUP_FAIL - No lookup entry found
800Sstevel@tonic-gate * IBCM_MEMORY_FAILURE - Memory allocs failed
810Sstevel@tonic-gate */
820Sstevel@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)830Sstevel@tonic-gate ibcm_lookup_msg(ibcm_event_type_t event_type, ib_com_id_t comid,
840Sstevel@tonic-gate ib_qpn_t remote_qpn, ib_guid_t remote_hca_guid, ibcm_hca_info_t *hcap,
850Sstevel@tonic-gate ibcm_state_data_t **rstatep)
860Sstevel@tonic-gate {
870Sstevel@tonic-gate avl_index_t where;
880Sstevel@tonic-gate ibcm_state_data_t *sp;
890Sstevel@tonic-gate
901093Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_lookup_msg: event = 0x%x, comid = 0x%x",
910Sstevel@tonic-gate event_type, comid);
920Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_lookup_msg: rem_qpn = 0x%lX, "
930Sstevel@tonic-gate "rem_hca_guid = 0x%llX", remote_qpn, remote_hca_guid);
940Sstevel@tonic-gate
950Sstevel@tonic-gate ASSERT(rw_lock_held(&hcap->hca_state_rwlock));
960Sstevel@tonic-gate
970Sstevel@tonic-gate /*
980Sstevel@tonic-gate * Lookup in "hca_passive_tree" for IBCM_INCOMING_REQ and
990Sstevel@tonic-gate * IBCM_INCOMING_REP_STALE;
1000Sstevel@tonic-gate *
1010Sstevel@tonic-gate * Lookup in "hca_passive_comid_tree" for IBCM_INCOMING_REQ_STALE
1020Sstevel@tonic-gate *
1030Sstevel@tonic-gate * All other lookups in "hca_active_tree".
1040Sstevel@tonic-gate *
1050Sstevel@tonic-gate * NOTE: "hca_active_tree" lookups are based on the local comid.
1060Sstevel@tonic-gate * "hca_passive_state_tree" lookups are based on remote QPN
1070Sstevel@tonic-gate * and remote hca GUID.
1080Sstevel@tonic-gate *
1090Sstevel@tonic-gate * Call avl_find to lookup in the respective tree and save result in
1100Sstevel@tonic-gate * "sp". If "sp" is null it implies that no match was found. If so,
1110Sstevel@tonic-gate * allocate a new ibcm_state_data_t and insert it into the AVL tree(s).
1120Sstevel@tonic-gate */
1130Sstevel@tonic-gate if ((event_type == IBCM_INCOMING_REQ) ||
1140Sstevel@tonic-gate (event_type == IBCM_INCOMING_REP_STALE)) {
1150Sstevel@tonic-gate ibcm_passive_node_info_t info;
1160Sstevel@tonic-gate
1170Sstevel@tonic-gate info.info_qpn = remote_qpn;
1180Sstevel@tonic-gate info.info_hca_guid = remote_hca_guid;
1190Sstevel@tonic-gate
1200Sstevel@tonic-gate /* Lookup based on Remote QPN and Remote GUID in Passive Tree */
1210Sstevel@tonic-gate sp = avl_find(&hcap->hca_passive_tree, &info, &where);
1220Sstevel@tonic-gate } else if ((event_type == IBCM_INCOMING_REQ_STALE) ||
1230Sstevel@tonic-gate (event_type == IBCM_INCOMING_REJ_RCOMID)) {
1240Sstevel@tonic-gate ibcm_passive_comid_node_info_t info;
1250Sstevel@tonic-gate
1260Sstevel@tonic-gate info.info_comid = comid;
1270Sstevel@tonic-gate info.info_hca_guid = remote_hca_guid;
1280Sstevel@tonic-gate
1290Sstevel@tonic-gate /* Lookup based on Remote COMID in Passive Tree */
1300Sstevel@tonic-gate sp = avl_find(&hcap->hca_passive_comid_tree, &info, &where);
1310Sstevel@tonic-gate } else { /* any other event including IBCM_OUTGOING_REQ */
1320Sstevel@tonic-gate /* Lookup based on Local comid in Active Tree */
1330Sstevel@tonic-gate sp = avl_find(&hcap->hca_active_tree, &comid, &where);
1340Sstevel@tonic-gate }
1350Sstevel@tonic-gate
1360Sstevel@tonic-gate /* matching entry found !! */
1370Sstevel@tonic-gate if (sp != NULL) {
1380Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_lookup_msg: match found "
1390Sstevel@tonic-gate "statep = %p", sp);
1400Sstevel@tonic-gate if (event_type == IBCM_INCOMING_REQ)
1410Sstevel@tonic-gate kmem_free(*rstatep, sizeof (ibcm_state_data_t));
1420Sstevel@tonic-gate *rstatep = sp; /* return the matched statep */
1430Sstevel@tonic-gate
1440Sstevel@tonic-gate mutex_enter(&(sp->state_mutex));
1450Sstevel@tonic-gate IBCM_REF_CNT_INCR(sp); /* increment the ref count */
1460Sstevel@tonic-gate mutex_exit(&(sp->state_mutex));
1470Sstevel@tonic-gate
1480Sstevel@tonic-gate return (IBCM_LOOKUP_EXISTS);
1490Sstevel@tonic-gate }
1500Sstevel@tonic-gate
1510Sstevel@tonic-gate /*
1520Sstevel@tonic-gate * If we came here then it implies that CM didn't
1530Sstevel@tonic-gate * find a matching entry. We will create a new entry in avl tree,
1540Sstevel@tonic-gate * if event_type is INCOMING/OUTGOING REQ, REQ_STALE/REP_STALE.
1550Sstevel@tonic-gate * statep is created for INCOMING/OUTGOING REQ.
1560Sstevel@tonic-gate * For all other event_types we return lookup failure
1570Sstevel@tonic-gate */
1580Sstevel@tonic-gate if (!((event_type == IBCM_INCOMING_REQ) ||
1590Sstevel@tonic-gate (event_type == IBCM_INCOMING_REQ_STALE) ||
1600Sstevel@tonic-gate (event_type == IBCM_INCOMING_REP_STALE) ||
1610Sstevel@tonic-gate (event_type == IBCM_OUTGOING_REQ))) {
1620Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_lookup_msg: failed for "
1631093Shiremath "event type %x remote_comid = 0x%x",
1641093Shiremath event_type, comid);
1650Sstevel@tonic-gate
1660Sstevel@tonic-gate return (IBCM_LOOKUP_FAIL);
1670Sstevel@tonic-gate }
1680Sstevel@tonic-gate
1690Sstevel@tonic-gate if ((event_type == IBCM_INCOMING_REQ) ||
1700Sstevel@tonic-gate (event_type == IBCM_OUTGOING_REQ)) {
1710Sstevel@tonic-gate
1720Sstevel@tonic-gate /* fill in the new ibcm_state_data */
1730Sstevel@tonic-gate sp = *rstatep;
1740Sstevel@tonic-gate
1750Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sp))
1760Sstevel@tonic-gate
1770Sstevel@tonic-gate /* initialize statep */
1780Sstevel@tonic-gate mutex_init(&sp->state_mutex, NULL, MUTEX_DEFAULT, NULL);
1790Sstevel@tonic-gate cv_init(&sp->block_client_cv, NULL, CV_DRIVER, NULL);
1800Sstevel@tonic-gate cv_init(&sp->block_mad_cv, NULL, CV_DRIVER, NULL);
1810Sstevel@tonic-gate
1820Sstevel@tonic-gate sp->hcap = hcap;
1830Sstevel@tonic-gate IBCM_REF_CNT_INCR(sp);
1840Sstevel@tonic-gate sp->local_comid = comid;
1850Sstevel@tonic-gate
1860Sstevel@tonic-gate if (ibcm_enable_trace != 0)
1870Sstevel@tonic-gate ibcm_init_conn_trace(sp);
1880Sstevel@tonic-gate
1890Sstevel@tonic-gate if (event_type == IBCM_INCOMING_REQ) { /* Passive side */
1900Sstevel@tonic-gate sp->state = IBCM_STATE_REQ_RCVD;
1910Sstevel@tonic-gate sp->clnt_proceed = IBCM_BLOCK;
1920Sstevel@tonic-gate sp->close_nocb_state = IBCM_UNBLOCK;
1930Sstevel@tonic-gate sp->remote_hca_guid = remote_hca_guid;
1940Sstevel@tonic-gate sp->remote_qpn = remote_qpn;
1950Sstevel@tonic-gate
1960Sstevel@tonic-gate } else if (event_type == IBCM_OUTGOING_REQ) { /* Active side */
1970Sstevel@tonic-gate sp->close_nocb_state = IBCM_UNBLOCK;
1980Sstevel@tonic-gate sp->state = IBCM_STATE_IDLE;
1990Sstevel@tonic-gate }
2000Sstevel@tonic-gate
2010Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*sp))
2020Sstevel@tonic-gate
2030Sstevel@tonic-gate } else {
2040Sstevel@tonic-gate sp = *rstatep; /* for incoming REQ/REP STALE only */
2050Sstevel@tonic-gate }
2060Sstevel@tonic-gate
2070Sstevel@tonic-gate if ((event_type == IBCM_INCOMING_REQ) ||
2080Sstevel@tonic-gate (event_type == IBCM_INCOMING_REP_STALE)) {
2090Sstevel@tonic-gate
2100Sstevel@tonic-gate /* First, insert a new "sp" into "hca_passive_tree" @ "where" */
2110Sstevel@tonic-gate avl_insert(&(hcap->hca_passive_tree), (void *)sp, where);
2120Sstevel@tonic-gate
2130Sstevel@tonic-gate if (event_type == IBCM_INCOMING_REQ) { /* Only INCOMING_REQ */
2140Sstevel@tonic-gate /*
2150Sstevel@tonic-gate * We have to do an avl_find() to figure out
2160Sstevel@tonic-gate * "where" to insert the statep into the active tree.
2170Sstevel@tonic-gate *
2180Sstevel@tonic-gate * CM doesn't care for avl_find's retval.
2190Sstevel@tonic-gate */
2200Sstevel@tonic-gate (void) avl_find(&hcap->hca_active_tree,
2210Sstevel@tonic-gate &sp->local_comid, &where);
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate /* Next, insert the "sp" into "hca_active_tree" */
2240Sstevel@tonic-gate avl_insert(&hcap->hca_active_tree, (void *)sp, where);
2250Sstevel@tonic-gate }
2260Sstevel@tonic-gate } else if (event_type == IBCM_INCOMING_REQ_STALE) {
2270Sstevel@tonic-gate avl_insert(&(hcap->hca_passive_comid_tree), (void *)sp, where);
2280Sstevel@tonic-gate } else { /* IBCM_OUTGOING_REQ */
2290Sstevel@tonic-gate /* Insert the new sp only into "hca_active_tree", @ "where" */
2300Sstevel@tonic-gate avl_insert(&(hcap->hca_active_tree), (void *)sp, where);
2310Sstevel@tonic-gate }
2320Sstevel@tonic-gate
2330Sstevel@tonic-gate return (IBCM_LOOKUP_NEW); /* return new lookup */
2340Sstevel@tonic-gate }
2350Sstevel@tonic-gate
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate /*
2380Sstevel@tonic-gate * ibcm_active_node_compare:
2390Sstevel@tonic-gate * - AVL active tree node compare
2400Sstevel@tonic-gate *
2410Sstevel@tonic-gate * Arguments:
2420Sstevel@tonic-gate * p1 : pointer to local comid
2430Sstevel@tonic-gate * p2 : pointer to passed ibcm_state_data_t
2440Sstevel@tonic-gate *
2450Sstevel@tonic-gate * Return values:
2460Sstevel@tonic-gate * 0 : match found
2470Sstevel@tonic-gate * -1 : no match but insert to left side of the tree
2480Sstevel@tonic-gate * +1 : no match but insert to right side of the tree
2490Sstevel@tonic-gate */
2500Sstevel@tonic-gate int
ibcm_active_node_compare(const void * p1,const void * p2)2510Sstevel@tonic-gate ibcm_active_node_compare(const void *p1, const void *p2)
2520Sstevel@tonic-gate {
2530Sstevel@tonic-gate ib_com_id_t *local_comid = (ib_com_id_t *)p1;
2540Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)p2;
2550Sstevel@tonic-gate
2560Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_active_node_compare: "
2570Sstevel@tonic-gate "comid: 0x%x, statep: 0x%p", *local_comid, statep);
2580Sstevel@tonic-gate
2590Sstevel@tonic-gate if (*local_comid > statep->local_comid) {
2600Sstevel@tonic-gate return (+1);
2610Sstevel@tonic-gate } else if (*local_comid < statep->local_comid) {
2620Sstevel@tonic-gate return (-1);
2630Sstevel@tonic-gate } else {
2640Sstevel@tonic-gate return (0);
2650Sstevel@tonic-gate }
2660Sstevel@tonic-gate }
2670Sstevel@tonic-gate
2680Sstevel@tonic-gate
2690Sstevel@tonic-gate /*
2700Sstevel@tonic-gate * ibcm_passive_node_compare:
2710Sstevel@tonic-gate * - AVL passive tree node compare (passive side)
2720Sstevel@tonic-gate *
2730Sstevel@tonic-gate * Arguments:
2740Sstevel@tonic-gate * p1 : pointer to ibcm_passive_node_info (remote qpn and remote guid)
2750Sstevel@tonic-gate * p2 : pointer to passed ibcm_state_data_t
2760Sstevel@tonic-gate *
2770Sstevel@tonic-gate * Return values:
2780Sstevel@tonic-gate * 0 : match found
2790Sstevel@tonic-gate * -1 : no match but insert to left side of the tree
2800Sstevel@tonic-gate * +1 : no match but insert to right side of the tree
2810Sstevel@tonic-gate */
2820Sstevel@tonic-gate int
ibcm_passive_node_compare(const void * p1,const void * p2)2830Sstevel@tonic-gate ibcm_passive_node_compare(const void *p1, const void *p2)
2840Sstevel@tonic-gate {
2850Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)p2;
2860Sstevel@tonic-gate ibcm_passive_node_info_t *infop = (ibcm_passive_node_info_t *)p1;
2870Sstevel@tonic-gate
2880Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_passive_node_compare: "
2890Sstevel@tonic-gate "statep: 0x%p, p1: 0x%p", statep, p1);
2900Sstevel@tonic-gate
2910Sstevel@tonic-gate /*
2920Sstevel@tonic-gate * PASSIVE SIDE: (REQ, REP, MRA, REJ)
2930Sstevel@tonic-gate * always search by active COMID
2940Sstevel@tonic-gate */
2950Sstevel@tonic-gate if (infop->info_qpn > statep->remote_qpn) {
2960Sstevel@tonic-gate return (+1);
2970Sstevel@tonic-gate } else if (infop->info_qpn < statep->remote_qpn) {
2980Sstevel@tonic-gate return (-1);
2990Sstevel@tonic-gate } else {
3000Sstevel@tonic-gate if (infop->info_hca_guid < statep->remote_hca_guid) {
3010Sstevel@tonic-gate return (-1);
3020Sstevel@tonic-gate } else if (infop->info_hca_guid > statep->remote_hca_guid) {
3030Sstevel@tonic-gate return (+1);
3040Sstevel@tonic-gate } else {
3050Sstevel@tonic-gate return (0);
3060Sstevel@tonic-gate }
3070Sstevel@tonic-gate }
3080Sstevel@tonic-gate }
3090Sstevel@tonic-gate
3100Sstevel@tonic-gate /*
3110Sstevel@tonic-gate * ibcm_passive_comid_node_compare:
3120Sstevel@tonic-gate * - AVL passive comid tree node compare (passive side)
3130Sstevel@tonic-gate *
3140Sstevel@tonic-gate * Arguments:
3150Sstevel@tonic-gate * p1 : pointer to ibcm_passive_comid_node_info
3160Sstevel@tonic-gate * (remote comid and remote guid)
3170Sstevel@tonic-gate * p2 : pointer to passed ibcm_state_data_t
3180Sstevel@tonic-gate *
3190Sstevel@tonic-gate * Return values:
3200Sstevel@tonic-gate * 0 : match found
3210Sstevel@tonic-gate * -1 : no match but insert to left side of the tree
3220Sstevel@tonic-gate * +1 : no match but insert to right side of the tree
3230Sstevel@tonic-gate */
3240Sstevel@tonic-gate int
ibcm_passive_comid_node_compare(const void * p1,const void * p2)3250Sstevel@tonic-gate ibcm_passive_comid_node_compare(const void *p1, const void *p2)
3260Sstevel@tonic-gate {
3270Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)p2;
3280Sstevel@tonic-gate ibcm_passive_comid_node_info_t *infop =
3290Sstevel@tonic-gate (ibcm_passive_comid_node_info_t *)p1;
3300Sstevel@tonic-gate
3310Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_passive_comid_node_compare: "
3320Sstevel@tonic-gate "statep: 0x%p, p1: 0x%p", statep, p1);
3330Sstevel@tonic-gate
3340Sstevel@tonic-gate if (infop->info_comid > statep->remote_comid) {
3350Sstevel@tonic-gate return (+1);
3360Sstevel@tonic-gate } else if (infop->info_comid < statep->remote_comid) {
3370Sstevel@tonic-gate return (-1);
3380Sstevel@tonic-gate } else {
3390Sstevel@tonic-gate if (infop->info_hca_guid < statep->remote_hca_guid) {
3400Sstevel@tonic-gate return (-1);
3410Sstevel@tonic-gate } else if (infop->info_hca_guid > statep->remote_hca_guid) {
3420Sstevel@tonic-gate return (+1);
3430Sstevel@tonic-gate } else {
3440Sstevel@tonic-gate return (0);
3450Sstevel@tonic-gate }
3460Sstevel@tonic-gate }
3470Sstevel@tonic-gate }
3480Sstevel@tonic-gate
3490Sstevel@tonic-gate
3500Sstevel@tonic-gate void
ibcm_delete_state_from_avl(ibcm_state_data_t * statep)3510Sstevel@tonic-gate ibcm_delete_state_from_avl(ibcm_state_data_t *statep)
3520Sstevel@tonic-gate {
3530Sstevel@tonic-gate avl_index_t a_where = 0;
3540Sstevel@tonic-gate avl_index_t p_where = 0;
3550Sstevel@tonic-gate avl_index_t pcomid_where = 0;
3560Sstevel@tonic-gate ibcm_hca_info_t *hcap;
3574703Shiremath ibcm_state_data_t *active_nodep, *passive_nodep;
3584703Shiremath ibcm_state_data_t *passive_comid_nodep;
3590Sstevel@tonic-gate ibcm_passive_node_info_t info;
3600Sstevel@tonic-gate ibcm_passive_comid_node_info_t info_comid;
3610Sstevel@tonic-gate
3620Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_delete_state_from_avl: statep 0x%p",
3630Sstevel@tonic-gate statep);
3640Sstevel@tonic-gate
3650Sstevel@tonic-gate if (statep == NULL) {
3660Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_delete_state_from_avl: statep"
3670Sstevel@tonic-gate " NULL");
3680Sstevel@tonic-gate return;
3690Sstevel@tonic-gate }
3700Sstevel@tonic-gate
3710Sstevel@tonic-gate hcap = statep->hcap;
3720Sstevel@tonic-gate
3730Sstevel@tonic-gate /*
3740Sstevel@tonic-gate * Once the avl tree lock is acquired, no other thread can increment
3750Sstevel@tonic-gate * ref cnt, until tree lock is exit'ed. Since the statep is removed
3760Sstevel@tonic-gate * from the avl's after acquiring lock below, no other thread can
3770Sstevel@tonic-gate * increment the ref cnt after acquiring the lock below
3780Sstevel@tonic-gate */
3790Sstevel@tonic-gate
3800Sstevel@tonic-gate rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
3810Sstevel@tonic-gate
3820Sstevel@tonic-gate /* Lookup based on Local comid in the active tree */
3830Sstevel@tonic-gate active_nodep = avl_find(&hcap->hca_active_tree, &(statep->local_comid),
3840Sstevel@tonic-gate &a_where);
3850Sstevel@tonic-gate
3860Sstevel@tonic-gate /* Lookup based on Remote QPN and Remote GUID in the passive tree */
3870Sstevel@tonic-gate info.info_qpn = statep->remote_qpn;
3880Sstevel@tonic-gate info.info_hca_guid = statep->remote_hca_guid;
3890Sstevel@tonic-gate passive_nodep = avl_find(&hcap->hca_passive_tree, &info, &p_where);
3900Sstevel@tonic-gate
3910Sstevel@tonic-gate /* Lookup based on Remote Comid and Remote GUID in the passive tree */
3920Sstevel@tonic-gate info_comid.info_comid = statep->remote_comid;
3930Sstevel@tonic-gate info_comid.info_hca_guid = statep->remote_hca_guid;
3940Sstevel@tonic-gate passive_comid_nodep = avl_find(&hcap->hca_passive_comid_tree,
3950Sstevel@tonic-gate &info_comid, &pcomid_where);
3960Sstevel@tonic-gate
3970Sstevel@tonic-gate /* remove it from the tree, destroy record and the nodep */
3980Sstevel@tonic-gate if (active_nodep == statep) {
3990Sstevel@tonic-gate avl_remove(&hcap->hca_active_tree, active_nodep);
4000Sstevel@tonic-gate }
4010Sstevel@tonic-gate
4020Sstevel@tonic-gate if (passive_nodep == statep) {
4030Sstevel@tonic-gate avl_remove(&hcap->hca_passive_tree, passive_nodep);
4040Sstevel@tonic-gate }
4050Sstevel@tonic-gate
4060Sstevel@tonic-gate if (passive_comid_nodep == statep) {
4070Sstevel@tonic-gate avl_remove(&hcap->hca_passive_comid_tree, passive_comid_nodep);
4080Sstevel@tonic-gate }
4090Sstevel@tonic-gate
4100Sstevel@tonic-gate rw_exit(&hcap->hca_state_rwlock);
4110Sstevel@tonic-gate }
4120Sstevel@tonic-gate
4130Sstevel@tonic-gate /*
4140Sstevel@tonic-gate * ibcm_dealloc_state_data:
4150Sstevel@tonic-gate * Deallocates all buffers and the memory of state structure
4160Sstevel@tonic-gate * This routine can be called on statep that has ref_cnt of 0, and that is
4170Sstevel@tonic-gate * already deleted from the avl tree's
4180Sstevel@tonic-gate *
4190Sstevel@tonic-gate * Arguments are:-
4200Sstevel@tonic-gate * statep - statep to be deleted
4210Sstevel@tonic-gate *
4220Sstevel@tonic-gate * Return Values: NONE
4230Sstevel@tonic-gate */
4240Sstevel@tonic-gate void
ibcm_dealloc_state_data(ibcm_state_data_t * statep)4250Sstevel@tonic-gate ibcm_dealloc_state_data(ibcm_state_data_t *statep)
4260Sstevel@tonic-gate {
4270Sstevel@tonic-gate timeout_id_t timer_val;
4281093Shiremath int dump_trace;
4290Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_dealloc_state_data: statep 0x%p", statep);
4300Sstevel@tonic-gate
4310Sstevel@tonic-gate if (statep == NULL) {
4320Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_dealloc_state_data: statep NULL");
4330Sstevel@tonic-gate return;
4340Sstevel@tonic-gate }
4350Sstevel@tonic-gate
4360Sstevel@tonic-gate /* ref_cnt is 0 */
4370Sstevel@tonic-gate /* If timer is running - expire it */
4380Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
4390Sstevel@tonic-gate timer_val = statep->timerid;
4400Sstevel@tonic-gate if (timer_val != 0) {
4410Sstevel@tonic-gate statep->timerid = 0;
4420Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
4430Sstevel@tonic-gate (void) untimeout(timer_val);
4440Sstevel@tonic-gate } else
4450Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
4460Sstevel@tonic-gate
4470Sstevel@tonic-gate /* release the ref cnt on the associated ibmf qp */
4480Sstevel@tonic-gate if (statep->stored_reply_addr.cm_qp_entry != NULL)
4490Sstevel@tonic-gate ibcm_release_qp(statep->stored_reply_addr.cm_qp_entry);
4500Sstevel@tonic-gate
4510Sstevel@tonic-gate if (statep->stored_msg != NULL)
4520Sstevel@tonic-gate (void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
4530Sstevel@tonic-gate &statep->stored_msg);
4540Sstevel@tonic-gate
4550Sstevel@tonic-gate if (statep->dreq_msg != NULL)
4560Sstevel@tonic-gate (void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
4570Sstevel@tonic-gate &statep->dreq_msg);
4580Sstevel@tonic-gate
4590Sstevel@tonic-gate if (statep->drep_msg != NULL)
4600Sstevel@tonic-gate (void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
4610Sstevel@tonic-gate &statep->drep_msg);
4620Sstevel@tonic-gate
4630Sstevel@tonic-gate if (statep->mra_msg != NULL)
4640Sstevel@tonic-gate (void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
4650Sstevel@tonic-gate &statep->mra_msg);
4660Sstevel@tonic-gate
4670Sstevel@tonic-gate if (statep->lapr_msg != NULL)
4680Sstevel@tonic-gate (void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
4690Sstevel@tonic-gate &statep->lapr_msg);
4700Sstevel@tonic-gate
4710Sstevel@tonic-gate if (statep->defer_cm_msg != NULL)
4720Sstevel@tonic-gate kmem_free(statep->defer_cm_msg, IBCM_MSG_SIZE);
4730Sstevel@tonic-gate
4740Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_dealloc_state_data: done for sp = 0x%p",
4750Sstevel@tonic-gate statep);
4760Sstevel@tonic-gate
4770Sstevel@tonic-gate /* Ensure the thread doing ref cnt decr releases the mutex */
4780Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
4791093Shiremath dump_trace = statep->cm_retries > 0;
4800Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
4810Sstevel@tonic-gate
4820Sstevel@tonic-gate /*
4830Sstevel@tonic-gate * now call the mutex_destroy() and cv_destroy()
4840Sstevel@tonic-gate */
4850Sstevel@tonic-gate mutex_destroy(&statep->state_mutex);
4860Sstevel@tonic-gate
4870Sstevel@tonic-gate cv_destroy(&statep->block_client_cv);
4880Sstevel@tonic-gate cv_destroy(&statep->block_mad_cv);
4890Sstevel@tonic-gate
4900Sstevel@tonic-gate /* free the comid */
4910Sstevel@tonic-gate ibcm_free_comid(statep->hcap, statep->local_comid);
4920Sstevel@tonic-gate
4930Sstevel@tonic-gate /* Decrement the resource on hcap */
4940Sstevel@tonic-gate ibcm_dec_hca_res_cnt(statep->hcap);
4950Sstevel@tonic-gate
4960Sstevel@tonic-gate /* dump the trace data into ibtf_debug_buf */
4971093Shiremath if ((ibcm_enable_trace & 4) || dump_trace)
4980Sstevel@tonic-gate ibcm_dump_conn_trace(statep);
4990Sstevel@tonic-gate
5000Sstevel@tonic-gate ibcm_fini_conn_trace(statep);
5010Sstevel@tonic-gate
5020Sstevel@tonic-gate /* free the statep */
5030Sstevel@tonic-gate kmem_free(statep, sizeof (ibcm_state_data_t));
5040Sstevel@tonic-gate }
5050Sstevel@tonic-gate
5060Sstevel@tonic-gate /*
5070Sstevel@tonic-gate * ibcm_delete_state_data:
5080Sstevel@tonic-gate * Deletes the state from avl trees, and tries to deallocate state
5090Sstevel@tonic-gate *
5100Sstevel@tonic-gate * Arguments are:-
5110Sstevel@tonic-gate * statep - statep to be deleted
5120Sstevel@tonic-gate *
5130Sstevel@tonic-gate * Return Values: NONE
5140Sstevel@tonic-gate */
5150Sstevel@tonic-gate void
ibcm_delete_state_data(ibcm_state_data_t * statep)5160Sstevel@tonic-gate ibcm_delete_state_data(ibcm_state_data_t *statep)
5170Sstevel@tonic-gate {
5180Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_delete_state_data:");
5190Sstevel@tonic-gate
5200Sstevel@tonic-gate ibcm_delete_state_from_avl(statep);
5210Sstevel@tonic-gate
5220Sstevel@tonic-gate /* Must acquire the state mutex to set delete_state_data */
5230Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
5240Sstevel@tonic-gate if (statep->ref_cnt > 0) {
5250Sstevel@tonic-gate statep->delete_state_data = B_TRUE;
5260Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_delete_state_data: statep 0x%p "
5270Sstevel@tonic-gate "ref_cnt = %x", statep, statep->ref_cnt);
5280Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
5290Sstevel@tonic-gate return;
5300Sstevel@tonic-gate }
5310Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
5320Sstevel@tonic-gate
5330Sstevel@tonic-gate ibcm_dealloc_state_data(statep);
5340Sstevel@tonic-gate }
5350Sstevel@tonic-gate
5360Sstevel@tonic-gate /*
5370Sstevel@tonic-gate * ibcm_find_sidr_entry:
5380Sstevel@tonic-gate * Routines for CM SIDR state structure list manipulation.
5390Sstevel@tonic-gate * Finds an entry based on lid, gid and grh exists fields
5400Sstevel@tonic-gate *
5410Sstevel@tonic-gate * INPUTS:
5420Sstevel@tonic-gate * lid: LID of incoming SIDR REQ
5430Sstevel@tonic-gate * gid: GID of incoming SIDR REQ
5440Sstevel@tonic-gate * grh_exists: TRUE if GRH exists in the incoming SIDR REQ
5450Sstevel@tonic-gate * req_id: Request ID
5460Sstevel@tonic-gate * hcap: CM State table to search for SIDR state structure
5470Sstevel@tonic-gate * statep: Returns a valid state structure, if one exists based
5480Sstevel@tonic-gate * on lid, gid and grh_exists fields
5490Sstevel@tonic-gate * flag: IBCM_FLAG_LOOKUP - just lookup
5500Sstevel@tonic-gate * IBCM_FLAG_LOOKUP_AND_ADD - if lookup fails, add it.
5510Sstevel@tonic-gate * Return Values:
5520Sstevel@tonic-gate * IBCM_LOOKUP_EXISTS - found an existing entry
5530Sstevel@tonic-gate * IBCM_LOOKUP_FAIL - failed to find an entry
5540Sstevel@tonic-gate * IBCM_LOOKUP_NEW - created a new entry
5550Sstevel@tonic-gate */
5560Sstevel@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)5570Sstevel@tonic-gate ibcm_find_sidr_entry(ibcm_sidr_srch_t *srch_param, ibcm_hca_info_t *hcap,
5580Sstevel@tonic-gate ibcm_ud_state_data_t **ud_statep, ibcm_lookup_flag_t flag)
5590Sstevel@tonic-gate {
5600Sstevel@tonic-gate ibcm_status_t status;
5610Sstevel@tonic-gate ibcm_ud_state_data_t *usp;
5620Sstevel@tonic-gate
5630Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_find_sidr_entry: srch_params are:"
5640Sstevel@tonic-gate "lid=%x, (%llX, %llX), grh: %x, id: %x",
5650Sstevel@tonic-gate srch_param->srch_lid, srch_param->srch_gid.gid_prefix,
5660Sstevel@tonic-gate srch_param->srch_gid.gid_guid, srch_param->srch_grh_exists,
5670Sstevel@tonic-gate srch_param->srch_req_id);
5680Sstevel@tonic-gate
5690Sstevel@tonic-gate if (flag == IBCM_FLAG_ADD) {
5700Sstevel@tonic-gate *ud_statep = ibcm_add_sidr_entry(srch_param, hcap);
5710Sstevel@tonic-gate return (IBCM_LOOKUP_NEW);
5720Sstevel@tonic-gate }
5730Sstevel@tonic-gate
5740Sstevel@tonic-gate usp = hcap->hca_sidr_list; /* Point to the list */
5750Sstevel@tonic-gate
5760Sstevel@tonic-gate /* traverse the list for a matching entry */
5770Sstevel@tonic-gate while (usp != NULL) {
5780Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_find_sidr_entry: "
5790Sstevel@tonic-gate "lid=%x, (%llX, %llX), grh: %x, id: %x",
5800Sstevel@tonic-gate usp->ud_sidr_req_lid, usp->ud_sidr_req_gid.gid_prefix,
5810Sstevel@tonic-gate usp->ud_sidr_req_gid.gid_guid, usp->ud_grh_exists,
5820Sstevel@tonic-gate usp->ud_req_id);
5830Sstevel@tonic-gate
5840Sstevel@tonic-gate if ((usp->ud_sidr_req_lid == srch_param->srch_lid) &&
5850Sstevel@tonic-gate ((srch_param->srch_gid.gid_prefix == 0) ||
5860Sstevel@tonic-gate (srch_param->srch_gid.gid_prefix ==
5874703Shiremath usp->ud_sidr_req_gid.gid_prefix)) &&
5880Sstevel@tonic-gate ((srch_param->srch_gid.gid_guid == 0) ||
5890Sstevel@tonic-gate (srch_param->srch_gid.gid_guid ==
5904703Shiremath usp->ud_sidr_req_gid.gid_guid)) &&
5910Sstevel@tonic-gate (srch_param->srch_req_id == usp->ud_req_id) &&
5920Sstevel@tonic-gate (usp->ud_grh_exists == srch_param->srch_grh_exists) &&
5930Sstevel@tonic-gate (usp->ud_mode == srch_param->srch_mode)) { /* found match */
5940Sstevel@tonic-gate *ud_statep = usp;
5950Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_find_sidr_entry: "
5960Sstevel@tonic-gate "found usp = %p", usp);
5970Sstevel@tonic-gate mutex_enter(&usp->ud_state_mutex);
5980Sstevel@tonic-gate IBCM_UD_REF_CNT_INCR(usp);
5990Sstevel@tonic-gate mutex_exit(&usp->ud_state_mutex);
6000Sstevel@tonic-gate
6010Sstevel@tonic-gate return (IBCM_LOOKUP_EXISTS);
6020Sstevel@tonic-gate }
6030Sstevel@tonic-gate usp = usp->ud_nextp;
6040Sstevel@tonic-gate }
6050Sstevel@tonic-gate
6060Sstevel@tonic-gate /*
6070Sstevel@tonic-gate * If code came here --> it couldn't find a match.
6080Sstevel@tonic-gate * OR
6090Sstevel@tonic-gate * the "hcap->hca_sidr_list" was NULL
6100Sstevel@tonic-gate */
6110Sstevel@tonic-gate if (flag == IBCM_FLAG_LOOKUP) {
6120Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_find_sidr_entry: no match found "
6130Sstevel@tonic-gate "lid=%x, (%llX, %llX), grh: %x, id: %x",
6140Sstevel@tonic-gate srch_param->srch_lid, srch_param->srch_gid.gid_prefix,
6150Sstevel@tonic-gate srch_param->srch_gid.gid_guid, srch_param->srch_grh_exists,
6160Sstevel@tonic-gate srch_param->srch_req_id);
6170Sstevel@tonic-gate status = IBCM_LOOKUP_FAIL;
6180Sstevel@tonic-gate } else {
6190Sstevel@tonic-gate *ud_statep = ibcm_add_sidr_entry(srch_param, hcap);
6200Sstevel@tonic-gate status = IBCM_LOOKUP_NEW;
6210Sstevel@tonic-gate }
6220Sstevel@tonic-gate
6230Sstevel@tonic-gate return (status);
6240Sstevel@tonic-gate }
6250Sstevel@tonic-gate
6260Sstevel@tonic-gate
6270Sstevel@tonic-gate /*
6280Sstevel@tonic-gate * ibcm_add_sidr_entry:
6290Sstevel@tonic-gate * Adds a SIDR entry. Called *ONLY* from ibcm_find_sidr_entry()
6300Sstevel@tonic-gate *
6310Sstevel@tonic-gate * INPUTS:
6320Sstevel@tonic-gate * lid: LID of incoming SIDR REQ
6330Sstevel@tonic-gate * gid: GID of incoming SIDR REQ
6340Sstevel@tonic-gate * grh_exists: TRUE if GRH exists in the incoming SIDR REQ
6350Sstevel@tonic-gate * req_id: Request ID
6360Sstevel@tonic-gate * hcap: CM State table to search for SIDR state structure
6370Sstevel@tonic-gate * Return Values: NONE
6380Sstevel@tonic-gate */
6390Sstevel@tonic-gate ibcm_ud_state_data_t *
ibcm_add_sidr_entry(ibcm_sidr_srch_t * srch_param,ibcm_hca_info_t * hcap)6400Sstevel@tonic-gate ibcm_add_sidr_entry(ibcm_sidr_srch_t *srch_param, ibcm_hca_info_t *hcap)
6410Sstevel@tonic-gate {
6420Sstevel@tonic-gate ibcm_ud_state_data_t *ud_statep;
6430Sstevel@tonic-gate
6440Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_add_sidr_entry: lid=%x, guid=%llX, "
6451093Shiremath "grh = %x req_id = %x", srch_param->srch_lid,
6460Sstevel@tonic-gate srch_param->srch_gid.gid_guid, srch_param->srch_grh_exists,
6470Sstevel@tonic-gate srch_param->srch_req_id);
6480Sstevel@tonic-gate
6490Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ud_statep))
6500Sstevel@tonic-gate
6510Sstevel@tonic-gate /* didn't find the entry - so create new */
6520Sstevel@tonic-gate ud_statep = kmem_zalloc(sizeof (ibcm_ud_state_data_t), KM_SLEEP);
6530Sstevel@tonic-gate
6540Sstevel@tonic-gate mutex_init(&ud_statep->ud_state_mutex, NULL, MUTEX_DEFAULT, NULL);
6550Sstevel@tonic-gate cv_init(&ud_statep->ud_block_client_cv, NULL, CV_DRIVER, NULL);
6560Sstevel@tonic-gate
6570Sstevel@tonic-gate /* Initialize some ud_statep fields */
6580Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
6590Sstevel@tonic-gate ud_statep->ud_hcap = hcap;
6600Sstevel@tonic-gate ud_statep->ud_req_id = srch_param->srch_req_id;
6610Sstevel@tonic-gate ud_statep->ud_ref_cnt = 1;
6620Sstevel@tonic-gate ud_statep->ud_grh_exists = srch_param->srch_grh_exists;
6630Sstevel@tonic-gate ud_statep->ud_sidr_req_lid = srch_param->srch_lid;
6640Sstevel@tonic-gate ud_statep->ud_sidr_req_gid = srch_param->srch_gid;
6650Sstevel@tonic-gate ud_statep->ud_mode = srch_param->srch_mode;
6660Sstevel@tonic-gate ud_statep->ud_max_cm_retries = ibcm_max_retries;
6670Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
6680Sstevel@tonic-gate
6690Sstevel@tonic-gate /* Update the list */
6700Sstevel@tonic-gate ud_statep->ud_nextp = hcap->hca_sidr_list;
6710Sstevel@tonic-gate hcap->hca_sidr_list = ud_statep;
6720Sstevel@tonic-gate
6730Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ud_statep))
6740Sstevel@tonic-gate
6750Sstevel@tonic-gate return (ud_statep);
6760Sstevel@tonic-gate }
6770Sstevel@tonic-gate
6780Sstevel@tonic-gate
6790Sstevel@tonic-gate /*
6800Sstevel@tonic-gate * ibcm_delete_ud_state_data:
6810Sstevel@tonic-gate * Deletes a given state structure
6820Sstevel@tonic-gate *
6830Sstevel@tonic-gate * Arguments are:-
6840Sstevel@tonic-gate * statep - statep to be deleted
6850Sstevel@tonic-gate *
6860Sstevel@tonic-gate * Return Values: NONE
6870Sstevel@tonic-gate */
6880Sstevel@tonic-gate void
ibcm_delete_ud_state_data(ibcm_ud_state_data_t * ud_statep)6890Sstevel@tonic-gate ibcm_delete_ud_state_data(ibcm_ud_state_data_t *ud_statep)
6900Sstevel@tonic-gate {
6910Sstevel@tonic-gate ibcm_ud_state_data_t *prevp, *headp;
6920Sstevel@tonic-gate ibcm_hca_info_t *hcap;
6930Sstevel@tonic-gate
6940Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_delete_ud_state_data: ud_statep 0x%p",
6950Sstevel@tonic-gate ud_statep);
6960Sstevel@tonic-gate
6970Sstevel@tonic-gate if (ud_statep == NULL || ud_statep->ud_hcap == NULL) {
6980Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_delete_ud_state_data: "
6990Sstevel@tonic-gate "ud_statep or hcap is NULL");
7000Sstevel@tonic-gate return;
7010Sstevel@tonic-gate }
7020Sstevel@tonic-gate
7030Sstevel@tonic-gate hcap = ud_statep->ud_hcap;
7040Sstevel@tonic-gate
7050Sstevel@tonic-gate rw_enter(&hcap->hca_sidr_list_lock, RW_WRITER);
7060Sstevel@tonic-gate
7070Sstevel@tonic-gate /* Next, remove this from the HCA SIDR list */
7080Sstevel@tonic-gate if (hcap->hca_sidr_list != NULL) {
7090Sstevel@tonic-gate prevp = NULL;
7100Sstevel@tonic-gate headp = hcap->hca_sidr_list;
7110Sstevel@tonic-gate
7120Sstevel@tonic-gate while (headp != NULL) {
7130Sstevel@tonic-gate /* delete the matching entry */
7140Sstevel@tonic-gate if (headp == ud_statep) {
7150Sstevel@tonic-gate if (prevp) {
7160Sstevel@tonic-gate prevp->ud_nextp = headp->ud_nextp;
7170Sstevel@tonic-gate } else {
7180Sstevel@tonic-gate prevp = headp->ud_nextp;
7190Sstevel@tonic-gate hcap->hca_sidr_list = prevp;
7200Sstevel@tonic-gate }
7210Sstevel@tonic-gate break;
7220Sstevel@tonic-gate }
7230Sstevel@tonic-gate prevp = headp;
7240Sstevel@tonic-gate headp = headp->ud_nextp;
7250Sstevel@tonic-gate }
7260Sstevel@tonic-gate }
7270Sstevel@tonic-gate
7280Sstevel@tonic-gate rw_exit(&hcap->hca_sidr_list_lock);
7290Sstevel@tonic-gate
7300Sstevel@tonic-gate /*
7310Sstevel@tonic-gate * While ref_cnt > 0
7320Sstevel@tonic-gate * - implies someone else is accessing the statep (possibly in
7330Sstevel@tonic-gate * a timeout function handler etc.)
7340Sstevel@tonic-gate * - don't delete statep unless they are done otherwise potentially
7350Sstevel@tonic-gate * one could access released memory and panic.
7360Sstevel@tonic-gate */
7370Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
7380Sstevel@tonic-gate if (ud_statep->ud_ref_cnt > 0) {
7390Sstevel@tonic-gate ud_statep->ud_delete_state_data = B_TRUE;
7400Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_delete_ud_state_data: "
7410Sstevel@tonic-gate "ud_statep 0x%p ud_ref_cnt = %x", ud_statep,
7420Sstevel@tonic-gate ud_statep->ud_ref_cnt);
7430Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
7440Sstevel@tonic-gate return;
7450Sstevel@tonic-gate }
7460Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
7470Sstevel@tonic-gate
7480Sstevel@tonic-gate ibcm_dealloc_ud_state_data(ud_statep);
7490Sstevel@tonic-gate }
7500Sstevel@tonic-gate
7510Sstevel@tonic-gate /*
7520Sstevel@tonic-gate * ibcm_ud_dealloc_state_data:
7530Sstevel@tonic-gate * Deallocates a given ud state structure
7540Sstevel@tonic-gate *
7550Sstevel@tonic-gate * Arguments are:-
7560Sstevel@tonic-gate * ud statep - ud statep to be deleted
7570Sstevel@tonic-gate *
7580Sstevel@tonic-gate * Return Values: NONE
7590Sstevel@tonic-gate */
7600Sstevel@tonic-gate void
ibcm_dealloc_ud_state_data(ibcm_ud_state_data_t * ud_statep)7610Sstevel@tonic-gate ibcm_dealloc_ud_state_data(ibcm_ud_state_data_t *ud_statep)
7620Sstevel@tonic-gate {
7630Sstevel@tonic-gate timeout_id_t timer_val;
7640Sstevel@tonic-gate
7650Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_dealloc_ud_state_data: ud_statep 0x%p",
7660Sstevel@tonic-gate ud_statep);
7670Sstevel@tonic-gate
7680Sstevel@tonic-gate /* If timer is running - expire it */
7690Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
7700Sstevel@tonic-gate if (ud_statep->ud_timerid) {
7710Sstevel@tonic-gate timer_val = ud_statep->ud_timerid;
7720Sstevel@tonic-gate ud_statep->ud_timerid = 0;
7730Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
7740Sstevel@tonic-gate (void) untimeout(timer_val);
7750Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_dealloc_ud_state_data: "
7760Sstevel@tonic-gate "Unexpected timer id 0x%p ud_statep 0x%p", timer_val,
7770Sstevel@tonic-gate ud_statep);
7780Sstevel@tonic-gate } else
7790Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
7800Sstevel@tonic-gate
7810Sstevel@tonic-gate if (ud_statep->ud_stored_msg != NULL) {
7820Sstevel@tonic-gate (void) ibcm_free_out_msg(
7830Sstevel@tonic-gate ud_statep->ud_stored_reply_addr.ibmf_hdl,
7840Sstevel@tonic-gate &ud_statep->ud_stored_msg);
7850Sstevel@tonic-gate }
7860Sstevel@tonic-gate
7870Sstevel@tonic-gate /* release the ref cnt on the associated ibmf qp */
7880Sstevel@tonic-gate ASSERT(ud_statep->ud_stored_reply_addr.cm_qp_entry != NULL);
7890Sstevel@tonic-gate ibcm_release_qp(ud_statep->ud_stored_reply_addr.cm_qp_entry);
7900Sstevel@tonic-gate
7910Sstevel@tonic-gate /* Ensure the thread doing ref cnt decr releases the mutex */
7920Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
7930Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
7940Sstevel@tonic-gate
7950Sstevel@tonic-gate /* now do the mutex_destroy() and cv_destroy() */
7960Sstevel@tonic-gate mutex_destroy(&ud_statep->ud_state_mutex);
7970Sstevel@tonic-gate
7980Sstevel@tonic-gate cv_destroy(&ud_statep->ud_block_client_cv);
7990Sstevel@tonic-gate
8000Sstevel@tonic-gate /* free the req id on SIDR REQ sender side */
8010Sstevel@tonic-gate if (ud_statep->ud_mode == IBCM_ACTIVE_MODE)
8020Sstevel@tonic-gate ibcm_free_reqid(ud_statep->ud_hcap, ud_statep->ud_req_id);
8030Sstevel@tonic-gate
8040Sstevel@tonic-gate /* Decrement the resource on hcap */
8050Sstevel@tonic-gate ibcm_dec_hca_res_cnt(ud_statep->ud_hcap);
8060Sstevel@tonic-gate
8070Sstevel@tonic-gate /* free the statep */
8080Sstevel@tonic-gate kmem_free(ud_statep, sizeof (ibcm_ud_state_data_t));
8090Sstevel@tonic-gate }
8100Sstevel@tonic-gate
8110Sstevel@tonic-gate
8120Sstevel@tonic-gate /*
8130Sstevel@tonic-gate * ibcm_init_ids:
8140Sstevel@tonic-gate * Create the vmem arenas for the various global ids
8150Sstevel@tonic-gate *
8160Sstevel@tonic-gate * Arguments are:-
8170Sstevel@tonic-gate * NONE
8180Sstevel@tonic-gate *
8190Sstevel@tonic-gate * Return Values: ibcm_status_t
8200Sstevel@tonic-gate */
8210Sstevel@tonic-gate
8220Sstevel@tonic-gate ibcm_status_t
ibcm_init_ids(void)8230Sstevel@tonic-gate ibcm_init_ids(void)
8240Sstevel@tonic-gate {
8250Sstevel@tonic-gate timespec_t tv;
8260Sstevel@tonic-gate
8270Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_local_sid_arena))
8284703Shiremath _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_ip_sid_arena))
8290Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_local_sid_seed))
8300Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_local_cid_seed))
8310Sstevel@tonic-gate
8320Sstevel@tonic-gate ibcm_local_sid_arena = vmem_create("ibcm_local_sid",
8330Sstevel@tonic-gate (void *)IBCM_INITIAL_SID, IBCM_MAX_LOCAL_SIDS, 1, NULL, NULL, NULL,
8340Sstevel@tonic-gate 0, VM_SLEEP | VMC_IDENTIFIER);
8350Sstevel@tonic-gate
8360Sstevel@tonic-gate if (!ibcm_local_sid_arena)
8370Sstevel@tonic-gate return (IBCM_FAILURE);
8380Sstevel@tonic-gate
8394703Shiremath ibcm_ip_sid_arena = vmem_create("ibcm_ip_sid", (void *)IBCM_INITIAL_SID,
8404703Shiremath IBCM_MAX_IP_SIDS, 1, NULL, NULL, NULL, 0,
8414703Shiremath VM_SLEEP | VMC_IDENTIFIER);
8424703Shiremath
8434703Shiremath if (!ibcm_ip_sid_arena)
8444703Shiremath return (IBCM_FAILURE);
8454703Shiremath
8460Sstevel@tonic-gate /* create a random starting value for local service ids */
8470Sstevel@tonic-gate gethrestime(&tv);
8480Sstevel@tonic-gate ibcm_local_sid_seed = ((uint64_t)tv.tv_sec << 20) & 0x007FFFFFFFF00000;
8490Sstevel@tonic-gate ASSERT((ibcm_local_sid_seed & IB_SID_AGN_MASK) == 0);
8500Sstevel@tonic-gate ibcm_local_sid_seed |= IB_SID_AGN_LOCAL;
8514703Shiremath
8520Sstevel@tonic-gate ibcm_local_cid_seed = (ib_com_id_t)tv.tv_sec;
8530Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_local_sid_arena))
8540Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_local_sid_seed))
8554703Shiremath _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_ip_sid_arena))
8560Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_local_cid_seed))
8570Sstevel@tonic-gate
8580Sstevel@tonic-gate return (IBCM_SUCCESS);
8590Sstevel@tonic-gate }
8600Sstevel@tonic-gate
8610Sstevel@tonic-gate
8620Sstevel@tonic-gate /*
8630Sstevel@tonic-gate * ibcm_init_hca_ids:
8640Sstevel@tonic-gate * Create the vmem arenas for the various hca level ids
8650Sstevel@tonic-gate *
8660Sstevel@tonic-gate * Arguments are:-
8670Sstevel@tonic-gate * hcap pointer to ibcm_hca_info_t
8680Sstevel@tonic-gate *
8690Sstevel@tonic-gate * Return Values: ibcm_status_t
8700Sstevel@tonic-gate */
8710Sstevel@tonic-gate ibcm_status_t
ibcm_init_hca_ids(ibcm_hca_info_t * hcap)8720Sstevel@tonic-gate ibcm_init_hca_ids(ibcm_hca_info_t *hcap)
8730Sstevel@tonic-gate {
8740Sstevel@tonic-gate hcap->hca_comid_arena = vmem_create("ibcm_com_ids",
8750Sstevel@tonic-gate (void *)IBCM_INITIAL_COMID, IBCM_MAX_COMIDS,
8760Sstevel@tonic-gate 1, NULL, NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER);
8770Sstevel@tonic-gate
8780Sstevel@tonic-gate if (!hcap->hca_comid_arena)
8790Sstevel@tonic-gate return (IBCM_FAILURE);
8800Sstevel@tonic-gate
8810Sstevel@tonic-gate hcap->hca_reqid_arena = vmem_create("ibcm_req_ids",
8820Sstevel@tonic-gate (void *)IBCM_INITIAL_REQID, IBCM_MAX_REQIDS,
8830Sstevel@tonic-gate 1, NULL, NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER);
8840Sstevel@tonic-gate
8850Sstevel@tonic-gate if (!hcap->hca_reqid_arena) {
8860Sstevel@tonic-gate vmem_destroy(hcap->hca_comid_arena);
8870Sstevel@tonic-gate return (IBCM_FAILURE);
8880Sstevel@tonic-gate }
8890Sstevel@tonic-gate
8900Sstevel@tonic-gate return (IBCM_SUCCESS);
8910Sstevel@tonic-gate }
8920Sstevel@tonic-gate
8930Sstevel@tonic-gate /*
8940Sstevel@tonic-gate * ibcm_free_ids:
8950Sstevel@tonic-gate * Destroy the vmem arenas for the various ids
8960Sstevel@tonic-gate *
8970Sstevel@tonic-gate * Arguments are:-
8980Sstevel@tonic-gate * NONE
8990Sstevel@tonic-gate *
9000Sstevel@tonic-gate * Return Values: NONE
9010Sstevel@tonic-gate */
9020Sstevel@tonic-gate void
ibcm_fini_ids(void)9030Sstevel@tonic-gate ibcm_fini_ids(void)
9040Sstevel@tonic-gate {
9050Sstevel@tonic-gate /* All arenas shall be valid */
9060Sstevel@tonic-gate vmem_destroy(ibcm_local_sid_arena);
9074703Shiremath vmem_destroy(ibcm_ip_sid_arena);
9080Sstevel@tonic-gate }
9090Sstevel@tonic-gate
9100Sstevel@tonic-gate /*
9110Sstevel@tonic-gate * ibcm_free_hca_ids:
9120Sstevel@tonic-gate * Destroy the vmem arenas for the various ids
9130Sstevel@tonic-gate *
9140Sstevel@tonic-gate * Arguments are:-
9150Sstevel@tonic-gate * hcap pointer to ibcm_hca_info_t
9160Sstevel@tonic-gate *
9170Sstevel@tonic-gate * Return Values: NONE
9180Sstevel@tonic-gate */
9190Sstevel@tonic-gate void
ibcm_fini_hca_ids(ibcm_hca_info_t * hcap)9200Sstevel@tonic-gate ibcm_fini_hca_ids(ibcm_hca_info_t *hcap)
9210Sstevel@tonic-gate {
9220Sstevel@tonic-gate /* All arenas shall be valid */
9230Sstevel@tonic-gate vmem_destroy(hcap->hca_comid_arena);
9240Sstevel@tonic-gate vmem_destroy(hcap->hca_reqid_arena);
9250Sstevel@tonic-gate }
9260Sstevel@tonic-gate
9270Sstevel@tonic-gate /* Communication id management routines ie., allocate, free up comids */
9280Sstevel@tonic-gate
9290Sstevel@tonic-gate /*
9300Sstevel@tonic-gate * ibcm_alloc_comid:
9310Sstevel@tonic-gate * Allocate a new communication id
9320Sstevel@tonic-gate *
9330Sstevel@tonic-gate * Arguments are:-
9340Sstevel@tonic-gate * hcap : pointer to ibcm_hca_info_t
9350Sstevel@tonic-gate * comid: pointer to the newly allocated communication id
9360Sstevel@tonic-gate *
9370Sstevel@tonic-gate * Return Values: ibt_status_t
9380Sstevel@tonic-gate */
9390Sstevel@tonic-gate ibcm_status_t
ibcm_alloc_comid(ibcm_hca_info_t * hcap,ib_com_id_t * comidp)9400Sstevel@tonic-gate ibcm_alloc_comid(ibcm_hca_info_t *hcap, ib_com_id_t *comidp)
9410Sstevel@tonic-gate {
9420Sstevel@tonic-gate ib_com_id_t comid;
9430Sstevel@tonic-gate
9440Sstevel@tonic-gate /* Use next fit, so least recently used com id is allocated */
9450Sstevel@tonic-gate comid = (ib_com_id_t)(uintptr_t)vmem_alloc(hcap->hca_comid_arena, 1,
9460Sstevel@tonic-gate VM_SLEEP | VM_NEXTFIT);
9470Sstevel@tonic-gate
9480Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_alloc_comid: hcap 0x%p comid 0x%lX", hcap,
9490Sstevel@tonic-gate comid);
9500Sstevel@tonic-gate
9510Sstevel@tonic-gate /*
9520Sstevel@tonic-gate * As comid is 32 bits, and maximum connections possible are 2^24
9530Sstevel@tonic-gate * per hca, comid allocation would never fail
9540Sstevel@tonic-gate */
9550Sstevel@tonic-gate *comidp = comid + ibcm_local_cid_seed;
9560Sstevel@tonic-gate if (comid == 0) {
9570Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_alloc_comid: hcap 0x%p"
9580Sstevel@tonic-gate "no more comids available", hcap);
9590Sstevel@tonic-gate return (IBCM_FAILURE);
9600Sstevel@tonic-gate }
9610Sstevel@tonic-gate
9620Sstevel@tonic-gate return (IBCM_SUCCESS);
9630Sstevel@tonic-gate }
9640Sstevel@tonic-gate
9650Sstevel@tonic-gate /*
9660Sstevel@tonic-gate * ibcm_free_comid:
9670Sstevel@tonic-gate * Releases the given Communication Id
9680Sstevel@tonic-gate *
9690Sstevel@tonic-gate * Arguments are:
9700Sstevel@tonic-gate * hcap : pointer to ibcm_hca_info_t
9710Sstevel@tonic-gate * comid : Communication id to be free'd
9720Sstevel@tonic-gate *
9730Sstevel@tonic-gate * Return Values: NONE
9740Sstevel@tonic-gate */
9750Sstevel@tonic-gate void
ibcm_free_comid(ibcm_hca_info_t * hcap,ib_com_id_t comid)9760Sstevel@tonic-gate ibcm_free_comid(ibcm_hca_info_t *hcap, ib_com_id_t comid)
9770Sstevel@tonic-gate {
9780Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_free_comid: hcap 0x%p"
9790Sstevel@tonic-gate "comid %x", hcap, comid);
9800Sstevel@tonic-gate comid -= ibcm_local_cid_seed;
9810Sstevel@tonic-gate vmem_free(hcap->hca_comid_arena, (void *)(uintptr_t)comid, 1);
9820Sstevel@tonic-gate }
9830Sstevel@tonic-gate
9840Sstevel@tonic-gate /* Allocate and Free local service ids */
9850Sstevel@tonic-gate
9860Sstevel@tonic-gate /*
9870Sstevel@tonic-gate * ibcm_alloc_local_sids:
9880Sstevel@tonic-gate * Create and destroy the vmem arenas for the service ids
9890Sstevel@tonic-gate *
9900Sstevel@tonic-gate * Arguments are:-
9910Sstevel@tonic-gate * Number of contiguous SIDs needed
9920Sstevel@tonic-gate *
9930Sstevel@tonic-gate * Return Values: starting SID
9940Sstevel@tonic-gate */
9950Sstevel@tonic-gate ib_svc_id_t
ibcm_alloc_local_sids(int num_sids)9960Sstevel@tonic-gate ibcm_alloc_local_sids(int num_sids)
9970Sstevel@tonic-gate {
9980Sstevel@tonic-gate ib_svc_id_t sid;
9990Sstevel@tonic-gate
10000Sstevel@tonic-gate sid = (ib_svc_id_t)(uintptr_t)vmem_alloc(ibcm_local_sid_arena,
10010Sstevel@tonic-gate num_sids, VM_SLEEP | VM_NEXTFIT);
10020Sstevel@tonic-gate
10030Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_alloc_local_sids: ServiceID 0x%llX "
10040Sstevel@tonic-gate "num_sids %d", sid, num_sids);
10050Sstevel@tonic-gate if (sid == 0) {
10060Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_alloc_local_sids: "
10070Sstevel@tonic-gate "no more local sids available");
10080Sstevel@tonic-gate } else {
10090Sstevel@tonic-gate ASSERT((ibcm_local_sid_seed & IB_SID_AGN_MASK) ==
10100Sstevel@tonic-gate IB_SID_AGN_LOCAL);
10110Sstevel@tonic-gate sid += ibcm_local_sid_seed;
10120Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_alloc_local_sids: Success: "
10130Sstevel@tonic-gate "allocated 0x%llX:%d", sid, num_sids);
10140Sstevel@tonic-gate }
10150Sstevel@tonic-gate return (sid);
10160Sstevel@tonic-gate }
10170Sstevel@tonic-gate
10180Sstevel@tonic-gate /*
10190Sstevel@tonic-gate * ibcm_free_local_sids:
10200Sstevel@tonic-gate * Releases the given Local service id
10210Sstevel@tonic-gate *
10220Sstevel@tonic-gate * Arguments are:
10230Sstevel@tonic-gate * num_sids: Number of local service id's to be free'd
10240Sstevel@tonic-gate * service_id: Starting local service id that needs to be free'd
10250Sstevel@tonic-gate *
10260Sstevel@tonic-gate * Return Values: NONE
10270Sstevel@tonic-gate */
10280Sstevel@tonic-gate void
ibcm_free_local_sids(ib_svc_id_t service_id,int num_sids)10290Sstevel@tonic-gate ibcm_free_local_sids(ib_svc_id_t service_id, int num_sids)
10300Sstevel@tonic-gate {
10310Sstevel@tonic-gate service_id -= ibcm_local_sid_seed;
10320Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_free_local_sids: "
10330Sstevel@tonic-gate "service_id 0x%llX num_sids %d", service_id, num_sids);
10340Sstevel@tonic-gate vmem_free(ibcm_local_sid_arena,
10350Sstevel@tonic-gate (void *)(uintptr_t)service_id, num_sids);
10360Sstevel@tonic-gate }
10370Sstevel@tonic-gate
10384703Shiremath /*
10394703Shiremath * ibcm_alloc_ip_sid:
10404703Shiremath * Allocate a local IP SID.
10414703Shiremath */
10424703Shiremath ib_svc_id_t
ibcm_alloc_ip_sid()10434703Shiremath ibcm_alloc_ip_sid()
10444703Shiremath {
10454703Shiremath ib_svc_id_t sid;
10464703Shiremath
10474703Shiremath sid = (ib_svc_id_t)(uintptr_t)vmem_alloc(ibcm_ip_sid_arena, 1,
10484703Shiremath VM_SLEEP | VM_NEXTFIT);
10494703Shiremath if (sid == 0) {
10504703Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_alloc_ip_sid: no more RDMA IP "
10514703Shiremath "SIDs available");
10524703Shiremath } else {
10534703Shiremath sid += IB_SID_IPADDR_PREFIX;
10544703Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_alloc_ip_sid: Success: RDMA IP SID"
10554703Shiremath " allocated : 0x%016llX", sid);
10564703Shiremath }
10574703Shiremath return (sid);
10584703Shiremath }
10594703Shiremath
10604703Shiremath /*
10614703Shiremath * ibcm_free_ip_sid:
10624703Shiremath * Releases the given IP Service ID
10634703Shiremath */
10644703Shiremath void
ibcm_free_ip_sid(ib_svc_id_t sid)10654703Shiremath ibcm_free_ip_sid(ib_svc_id_t sid)
10664703Shiremath {
10674703Shiremath sid -= IB_SID_IPADDR_PREFIX;
10684703Shiremath vmem_free(ibcm_ip_sid_arena, (void *)(uintptr_t)sid, 1);
10694703Shiremath }
10704703Shiremath
10714703Shiremath
10720Sstevel@tonic-gate /* Allocate and free request id routines for SIDR */
10730Sstevel@tonic-gate
10740Sstevel@tonic-gate /*
10750Sstevel@tonic-gate * ibcm_alloc_reqid:
10760Sstevel@tonic-gate * Allocate a new SIDR REQ request id
10770Sstevel@tonic-gate *
10780Sstevel@tonic-gate * Arguments are:-
10790Sstevel@tonic-gate * hcap : pointer to ibcm_hca_info_t
10800Sstevel@tonic-gate * *reqid : pointer to the new request id returned
10810Sstevel@tonic-gate *
10820Sstevel@tonic-gate * Return Values: ibcm_status_t
10830Sstevel@tonic-gate */
10840Sstevel@tonic-gate ibcm_status_t
ibcm_alloc_reqid(ibcm_hca_info_t * hcap,uint32_t * reqid)10850Sstevel@tonic-gate ibcm_alloc_reqid(ibcm_hca_info_t *hcap, uint32_t *reqid)
10860Sstevel@tonic-gate {
10870Sstevel@tonic-gate /* Use next fit, so least recently used com id is allocated */
10880Sstevel@tonic-gate *reqid = (uint32_t)(uintptr_t)vmem_alloc(hcap->hca_reqid_arena, 1,
10890Sstevel@tonic-gate VM_SLEEP | VM_NEXTFIT);
10900Sstevel@tonic-gate
10910Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_alloc_reqid: hcap 0x%p reqid %x", hcap,
10920Sstevel@tonic-gate *reqid);
10930Sstevel@tonic-gate if (!(*reqid)) {
10940Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_alloc_reqid: "
10950Sstevel@tonic-gate "no more req ids available");
10960Sstevel@tonic-gate return (IBCM_FAILURE);
10970Sstevel@tonic-gate }
10980Sstevel@tonic-gate return (IBCM_SUCCESS);
10990Sstevel@tonic-gate }
11000Sstevel@tonic-gate
11010Sstevel@tonic-gate /*
11020Sstevel@tonic-gate * ibcm_free_reqid:
11030Sstevel@tonic-gate * Releases the given SIDR REQ request id
11040Sstevel@tonic-gate *
11050Sstevel@tonic-gate * Arguments are:
11060Sstevel@tonic-gate * hcap : pointer to ibcm_hca_info_t
11070Sstevel@tonic-gate * reqid : Request id to be free'd
11080Sstevel@tonic-gate *
11090Sstevel@tonic-gate * Return Values: NONE
11100Sstevel@tonic-gate */
11110Sstevel@tonic-gate void
ibcm_free_reqid(ibcm_hca_info_t * hcap,uint32_t reqid)11120Sstevel@tonic-gate ibcm_free_reqid(ibcm_hca_info_t *hcap, uint32_t reqid)
11130Sstevel@tonic-gate {
11140Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_free_reqid: hcap 0x%p reqid %x", hcap,
11150Sstevel@tonic-gate reqid);
11160Sstevel@tonic-gate vmem_free(hcap->hca_reqid_arena, (void *)(uintptr_t)reqid, 1);
11170Sstevel@tonic-gate }
11180Sstevel@tonic-gate
11190Sstevel@tonic-gate /*
11200Sstevel@tonic-gate * ibcm_generate_tranid:
11210Sstevel@tonic-gate * Generate a new transaction id based on args
11220Sstevel@tonic-gate *
11230Sstevel@tonic-gate * Arguments are:-
11240Sstevel@tonic-gate * event_type CM Message REQ/DREQ/LAP
11250Sstevel@tonic-gate * id 32 bit identifier
11260Sstevel@tonic-gate * cm_tran_priv CM private data to be filled in top 28 MSB bits of
11270Sstevel@tonic-gate * tran id
11280Sstevel@tonic-gate *
11290Sstevel@tonic-gate *
11300Sstevel@tonic-gate * Return Value: uint64_t
11310Sstevel@tonic-gate */
11320Sstevel@tonic-gate uint64_t
ibcm_generate_tranid(uint8_t event,uint32_t id,uint32_t cm_tran_priv)11330Sstevel@tonic-gate ibcm_generate_tranid(uint8_t event, uint32_t id, uint32_t cm_tran_priv)
11340Sstevel@tonic-gate {
11350Sstevel@tonic-gate /*
11360Sstevel@tonic-gate * copy comid to bits 31-0 of tran id,
11370Sstevel@tonic-gate * attr id to bits 35-32 of tran id,
11380Sstevel@tonic-gate * cm_priv to bits 63-36 of tran id
11390Sstevel@tonic-gate */
11400Sstevel@tonic-gate if (cm_tran_priv == 0)
11410Sstevel@tonic-gate /*
11420Sstevel@tonic-gate * The below ensures that no duplicate transaction id is
11430Sstevel@tonic-gate * generated atleast for next 6 months. Calculations:
11440Sstevel@tonic-gate * (2^28)/(1000 * 60 * 24 * 30) = 6 approx
11450Sstevel@tonic-gate */
11460Sstevel@tonic-gate cm_tran_priv = gethrtime() >> 20; /* ~time in ms */
11470Sstevel@tonic-gate
11480Sstevel@tonic-gate return ((((uint64_t)cm_tran_priv << 36) | (uint64_t)event << 32) | id);
11490Sstevel@tonic-gate }
11500Sstevel@tonic-gate
11510Sstevel@tonic-gate #ifdef DEBUG
11520Sstevel@tonic-gate
11530Sstevel@tonic-gate /*
11540Sstevel@tonic-gate * ibcm_decode_tranid:
11550Sstevel@tonic-gate * Decodes a given transaction id, assuming certain format.
11560Sstevel@tonic-gate *
11570Sstevel@tonic-gate * Arguments are:-
11580Sstevel@tonic-gate * tran_id Transaction id to be decoded
11590Sstevel@tonic-gate * cm_tran_priv CM private data retrieved from transaction id
11600Sstevel@tonic-gate *
11610Sstevel@tonic-gate * Return Value: None
11620Sstevel@tonic-gate */
11630Sstevel@tonic-gate void
ibcm_decode_tranid(uint64_t tran_id,uint32_t * cm_tran_priv)11640Sstevel@tonic-gate ibcm_decode_tranid(uint64_t tran_id, uint32_t *cm_tran_priv)
11650Sstevel@tonic-gate {
11660Sstevel@tonic-gate ib_com_id_t id;
11670Sstevel@tonic-gate ibcm_event_type_t event;
11680Sstevel@tonic-gate
11690Sstevel@tonic-gate id = tran_id & 0xFFFFFFFF;
11700Sstevel@tonic-gate event = (tran_id >> 32) & 0xF;
11710Sstevel@tonic-gate
11721093Shiremath IBTF_DPRINTF_L5(cmlog, "ibcm_decode_tranid: id = 0x%x, event = %x",
11730Sstevel@tonic-gate id, event);
11740Sstevel@tonic-gate
11750Sstevel@tonic-gate if (cm_tran_priv) {
11760Sstevel@tonic-gate *cm_tran_priv = tran_id >> 36;
11770Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_decode_tranid: "
11780Sstevel@tonic-gate "cm_tran_priv = %x", *cm_tran_priv);
11790Sstevel@tonic-gate }
11800Sstevel@tonic-gate }
11810Sstevel@tonic-gate
11820Sstevel@tonic-gate #endif
11830Sstevel@tonic-gate
11840Sstevel@tonic-gate /*
11850Sstevel@tonic-gate * Service ID entry create and lookup functions
11860Sstevel@tonic-gate */
11870Sstevel@tonic-gate
11880Sstevel@tonic-gate /*
11890Sstevel@tonic-gate * ibcm_svc_compare:
11900Sstevel@tonic-gate * - AVL svc tree node compare
11910Sstevel@tonic-gate *
11920Sstevel@tonic-gate * Arguments:
11930Sstevel@tonic-gate * p1 : pointer to local comid
11940Sstevel@tonic-gate * p2 : pointer to passed ibcm_state_data_t
11950Sstevel@tonic-gate *
11960Sstevel@tonic-gate * Return values:
11970Sstevel@tonic-gate * 0 : match found
11980Sstevel@tonic-gate * -1 : no match but insert to left side of the tree
11990Sstevel@tonic-gate * +1 : no match but insert to right side of the tree
12000Sstevel@tonic-gate */
12010Sstevel@tonic-gate int
ibcm_svc_compare(const void * p1,const void * p2)12020Sstevel@tonic-gate ibcm_svc_compare(const void *p1, const void *p2)
12030Sstevel@tonic-gate {
12040Sstevel@tonic-gate ibcm_svc_lookup_t *sidp = (ibcm_svc_lookup_t *)p1;
12050Sstevel@tonic-gate ibcm_svc_info_t *svcp = (ibcm_svc_info_t *)p2;
12060Sstevel@tonic-gate ib_svc_id_t start_sid = sidp->sid;
12070Sstevel@tonic-gate ib_svc_id_t end_sid = start_sid + sidp->num_sids - 1;
12080Sstevel@tonic-gate
12090Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_svc_compare: "
12100Sstevel@tonic-gate "sid: 0x%llx, numsids: %d, node_sid: 0x%llx node_num_sids: %d",
12110Sstevel@tonic-gate sidp->sid, sidp->num_sids, svcp->svc_id, svcp->svc_num_sids);
12120Sstevel@tonic-gate
12130Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ibcm_svc_info_lock));
12140Sstevel@tonic-gate
12150Sstevel@tonic-gate if (svcp->svc_id > end_sid)
12160Sstevel@tonic-gate return (-1);
12170Sstevel@tonic-gate if (svcp->svc_id + svcp->svc_num_sids - 1 < start_sid)
12180Sstevel@tonic-gate return (+1);
12190Sstevel@tonic-gate return (0); /* means there is some overlap of SIDs */
12200Sstevel@tonic-gate }
12210Sstevel@tonic-gate
12220Sstevel@tonic-gate
12230Sstevel@tonic-gate /*
12240Sstevel@tonic-gate * ibcm_create_svc_entry:
12250Sstevel@tonic-gate * Make sure no conflicting entry exists, then allocate it.
12260Sstevel@tonic-gate * Fill in the critical "look up" details that are provided
12270Sstevel@tonic-gate * in the arguments before dropping the lock.
12280Sstevel@tonic-gate *
12290Sstevel@tonic-gate * Return values:
12300Sstevel@tonic-gate * Pointer to ibcm_svc_info_t, if created, otherwise NULL.
12310Sstevel@tonic-gate */
12320Sstevel@tonic-gate ibcm_svc_info_t *
ibcm_create_svc_entry(ib_svc_id_t sid,int num_sids)12330Sstevel@tonic-gate ibcm_create_svc_entry(ib_svc_id_t sid, int num_sids)
12340Sstevel@tonic-gate {
12350Sstevel@tonic-gate ibcm_svc_info_t *svcp;
12360Sstevel@tonic-gate ibcm_svc_info_t *svcinfop;
12370Sstevel@tonic-gate ibcm_svc_lookup_t svc;
12380Sstevel@tonic-gate avl_index_t where = 0;
12390Sstevel@tonic-gate
12400Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*svcinfop))
12410Sstevel@tonic-gate
12420Sstevel@tonic-gate /* assume success, and avoid kmem while holding the writer lock */
12430Sstevel@tonic-gate svcinfop = kmem_zalloc(sizeof (*svcinfop), KM_SLEEP);
12440Sstevel@tonic-gate svcinfop->svc_id = sid;
12450Sstevel@tonic-gate svcinfop->svc_num_sids = num_sids;
12460Sstevel@tonic-gate
12470Sstevel@tonic-gate svc.sid = sid;
12480Sstevel@tonic-gate svc.num_sids = num_sids;
12490Sstevel@tonic-gate
12500Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
12510Sstevel@tonic-gate #ifdef __lock_lint
12520Sstevel@tonic-gate ibcm_svc_compare(NULL, NULL);
12530Sstevel@tonic-gate #endif
12540Sstevel@tonic-gate svcp = avl_find(&ibcm_svc_avl_tree, &svc, &where);
12550Sstevel@tonic-gate if (svcp != NULL) { /* overlab exists */
12560Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
12570Sstevel@tonic-gate kmem_free(svcinfop, sizeof (*svcinfop));
12580Sstevel@tonic-gate return (NULL);
12590Sstevel@tonic-gate }
12600Sstevel@tonic-gate avl_insert(&ibcm_svc_avl_tree, (void *)svcinfop, where);
12610Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
12620Sstevel@tonic-gate
12630Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*svcinfop))
12640Sstevel@tonic-gate
12650Sstevel@tonic-gate return (svcinfop);
12660Sstevel@tonic-gate }
12670Sstevel@tonic-gate
12680Sstevel@tonic-gate /*
12690Sstevel@tonic-gate * ibcm_find_svc_entry:
12700Sstevel@tonic-gate * Finds a ibcm_svc_info_t entry into the CM's global table.
12710Sstevel@tonic-gate * The search done here assumes the list is sorted by SID.
12720Sstevel@tonic-gate *
12730Sstevel@tonic-gate * Arguments are:
12740Sstevel@tonic-gate * sid - Service ID to look up
12750Sstevel@tonic-gate *
12760Sstevel@tonic-gate * Return values:
12770Sstevel@tonic-gate * Pointer to ibcm_svc_info_t, if found, otherwise NULL.
12780Sstevel@tonic-gate */
12790Sstevel@tonic-gate ibcm_svc_info_t *
ibcm_find_svc_entry(ib_svc_id_t sid)12800Sstevel@tonic-gate ibcm_find_svc_entry(ib_svc_id_t sid)
12810Sstevel@tonic-gate {
12820Sstevel@tonic-gate ibcm_svc_info_t *svcp;
12830Sstevel@tonic-gate ibcm_svc_lookup_t svc;
12840Sstevel@tonic-gate
12850Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_find_svc_entry: finding SID 0x%llX", sid);
12860Sstevel@tonic-gate
12870Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ibcm_svc_info_lock));
12880Sstevel@tonic-gate
12890Sstevel@tonic-gate svc.sid = sid;
12900Sstevel@tonic-gate svc.num_sids = 1;
12910Sstevel@tonic-gate #ifdef __lock_lint
12920Sstevel@tonic-gate ibcm_svc_compare(NULL, NULL);
12930Sstevel@tonic-gate #endif
12940Sstevel@tonic-gate svcp = avl_find(&ibcm_svc_avl_tree, &svc, NULL);
12950Sstevel@tonic-gate if (svcp != NULL) {
12960Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_find_svc_entry: "
12970Sstevel@tonic-gate "found SID = 0x%llX", sid);
12980Sstevel@tonic-gate return (svcp); /* found it */
12990Sstevel@tonic-gate }
13000Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_find_svc_entry: SID %llX not found", sid);
13010Sstevel@tonic-gate return (NULL);
13020Sstevel@tonic-gate }
13030Sstevel@tonic-gate
13040Sstevel@tonic-gate /*
13050Sstevel@tonic-gate * ibcm_alloc_ibmf_msg:
13060Sstevel@tonic-gate * Allocate an ibmf message structure and the additional memory required for
13070Sstevel@tonic-gate * sending an outgoing CM mad. The ibmf message structure contains two
13080Sstevel@tonic-gate * ibmf_msg_bufs_t fields, one for the incoming MAD and one for the outgoing
13090Sstevel@tonic-gate * MAD. The CM must allocate the memory for the outgoing MAD. The msg_buf
13100Sstevel@tonic-gate * field has three buffers: the mad header, the class header, and the class
13110Sstevel@tonic-gate * data. To simplify the code and reduce the number of kmem_zalloc() calls,
13120Sstevel@tonic-gate * ibcm_alloc_ibmf_msg will allocate one buffer and set the pointers to the
13130Sstevel@tonic-gate * right offsets. No class header is needed so only the mad header and class
13140Sstevel@tonic-gate * data fields are used.
13150Sstevel@tonic-gate */
13160Sstevel@tonic-gate ibt_status_t
ibcm_alloc_out_msg(ibmf_handle_t ibmf_handle,ibmf_msg_t ** ibmf_msgpp,uint8_t method)13170Sstevel@tonic-gate ibcm_alloc_out_msg(ibmf_handle_t ibmf_handle, ibmf_msg_t **ibmf_msgpp,
13180Sstevel@tonic-gate uint8_t method)
13190Sstevel@tonic-gate {
13200Sstevel@tonic-gate ib_mad_hdr_t *output_mad_hdr;
13210Sstevel@tonic-gate int sa_retval;
13220Sstevel@tonic-gate
13230Sstevel@tonic-gate if ((sa_retval =
13240Sstevel@tonic-gate ibmf_alloc_msg(ibmf_handle, IBMF_ALLOC_SLEEP, ibmf_msgpp)) !=
13250Sstevel@tonic-gate IBMF_SUCCESS) {
13260Sstevel@tonic-gate IBTF_DPRINTF_L1(cmlog, "ibcm_alloc_out_msg: "
13270Sstevel@tonic-gate "ibmf_alloc_msg failed with IBMF_ALLOC_SLEEP");
13280Sstevel@tonic-gate return (ibcm_ibmf_analyze_error(sa_retval));
13290Sstevel@tonic-gate }
13300Sstevel@tonic-gate
13310Sstevel@tonic-gate (*ibmf_msgpp)->im_msgbufs_send.im_bufs_mad_hdr = kmem_zalloc(
13320Sstevel@tonic-gate IBCM_MAD_SIZE, KM_SLEEP);
13330Sstevel@tonic-gate
13340Sstevel@tonic-gate (*ibmf_msgpp)->im_msgbufs_send.im_bufs_cl_data_len = IBCM_MSG_SIZE;
13350Sstevel@tonic-gate (*ibmf_msgpp)->im_msgbufs_send.im_bufs_cl_data =
13360Sstevel@tonic-gate (uchar_t *)((*ibmf_msgpp)->im_msgbufs_send.im_bufs_mad_hdr) +
13370Sstevel@tonic-gate IBCM_MAD_HDR_SIZE;
13380Sstevel@tonic-gate
13390Sstevel@tonic-gate /* initialize generic CM MAD header fields */
13400Sstevel@tonic-gate output_mad_hdr = IBCM_OUT_HDRP((*ibmf_msgpp));
13410Sstevel@tonic-gate output_mad_hdr->BaseVersion = IBCM_MAD_BASE_VERSION;
13420Sstevel@tonic-gate output_mad_hdr->MgmtClass = MAD_MGMT_CLASS_COMM_MGT;
13430Sstevel@tonic-gate output_mad_hdr->ClassVersion = IBCM_MAD_CLASS_VERSION;
13440Sstevel@tonic-gate output_mad_hdr->R_Method = method;
13450Sstevel@tonic-gate
13460Sstevel@tonic-gate return (IBT_SUCCESS);
13470Sstevel@tonic-gate }
13480Sstevel@tonic-gate
13490Sstevel@tonic-gate /*
13500Sstevel@tonic-gate * ibcm_free_ibmf_msg:
13510Sstevel@tonic-gate * Frees the buffer and ibmf message associated with an outgoing CM message.
13520Sstevel@tonic-gate * This function should only be used to free messages created by
13530Sstevel@tonic-gate * ibcm_alloc_out_msg. Will return IBCM_FAILURE if the ibmf_free_msg() call
13540Sstevel@tonic-gate * fails and IBCM_SUCCESS otherwise.
13550Sstevel@tonic-gate */
13560Sstevel@tonic-gate ibcm_status_t
ibcm_free_out_msg(ibmf_handle_t ibmf_handle,ibmf_msg_t ** ibmf_msgpp)13570Sstevel@tonic-gate ibcm_free_out_msg(ibmf_handle_t ibmf_handle, ibmf_msg_t **ibmf_msgpp)
13580Sstevel@tonic-gate {
13590Sstevel@tonic-gate int ibmf_status;
13600Sstevel@tonic-gate
13610Sstevel@tonic-gate kmem_free((*ibmf_msgpp)->im_msgbufs_send.im_bufs_mad_hdr,
13620Sstevel@tonic-gate IBCM_MAD_SIZE);
13630Sstevel@tonic-gate
13640Sstevel@tonic-gate if ((ibmf_status = ibmf_free_msg(ibmf_handle, ibmf_msgpp)) !=
13650Sstevel@tonic-gate IBMF_SUCCESS) {
13660Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_free_out_msg: "
13670Sstevel@tonic-gate "ibmf_free_msg failed %d", ibmf_status);
13680Sstevel@tonic-gate return (IBCM_FAILURE);
13690Sstevel@tonic-gate } else
13700Sstevel@tonic-gate return (IBCM_SUCCESS);
13710Sstevel@tonic-gate }
13720Sstevel@tonic-gate
13730Sstevel@tonic-gate ibcm_qp_list_t *
ibcm_find_qp(ibcm_hca_info_t * hcap,int port_no,ib_pkey_t pkey)13740Sstevel@tonic-gate ibcm_find_qp(ibcm_hca_info_t *hcap, int port_no, ib_pkey_t pkey)
13750Sstevel@tonic-gate {
13760Sstevel@tonic-gate ibcm_qp_list_t *entry;
13770Sstevel@tonic-gate ibmf_qp_handle_t ibmf_qp;
13780Sstevel@tonic-gate int ibmf_status;
13790Sstevel@tonic-gate
13800Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*entry))
13810Sstevel@tonic-gate
13820Sstevel@tonic-gate mutex_enter(&ibcm_qp_list_lock);
13830Sstevel@tonic-gate
13840Sstevel@tonic-gate /*
13850Sstevel@tonic-gate * CM currently does not track port up and down status. If tracking of
13860Sstevel@tonic-gate * " port status" is added in the future, then CM could be optimized to
13870Sstevel@tonic-gate * re-use other ports on hcap, if the port associated with the above
13880Sstevel@tonic-gate * port_no is down. But, the issue of "reachability" needs to be
13890Sstevel@tonic-gate * handled, before selecting an alternative port different from above.
13900Sstevel@tonic-gate */
13910Sstevel@tonic-gate entry = hcap->hca_port_info[port_no-1].port_qplist;
13920Sstevel@tonic-gate while (entry != NULL) {
13930Sstevel@tonic-gate if (entry->qp_pkey == pkey) {
13940Sstevel@tonic-gate ++entry->qp_ref_cnt;
13950Sstevel@tonic-gate mutex_exit(&ibcm_qp_list_lock);
13960Sstevel@tonic-gate return (entry);
13970Sstevel@tonic-gate }
13980Sstevel@tonic-gate entry = entry->qp_next;
13990Sstevel@tonic-gate }
14000Sstevel@tonic-gate
14010Sstevel@tonic-gate /*
14020Sstevel@tonic-gate * entry not found, attempt to alloc a qp
14030Sstevel@tonic-gate * This may be optimized in the future, to allocate ibmf qp's
14040Sstevel@tonic-gate * once the "CM mgmt pkeys" are precisely known.
14050Sstevel@tonic-gate */
14060Sstevel@tonic-gate ibmf_status = ibmf_alloc_qp(
14070Sstevel@tonic-gate hcap->hca_port_info[port_no-1].port_ibmf_hdl, pkey, IB_GSI_QKEY,
14080Sstevel@tonic-gate IBMF_ALT_QP_MAD_NO_RMPP, &ibmf_qp);
14090Sstevel@tonic-gate
14100Sstevel@tonic-gate if (ibmf_status != IBMF_SUCCESS) {
14110Sstevel@tonic-gate mutex_exit(&ibcm_qp_list_lock);
14120Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_find_qp: failed to alloc IBMF QP"
14130Sstevel@tonic-gate "for Pkey = %x port_no = %x status = %d hcaguid = %llXp",
14140Sstevel@tonic-gate pkey, port_no, ibmf_status, hcap->hca_guid);
14150Sstevel@tonic-gate /*
14160Sstevel@tonic-gate * This may be optimized in the future, so as CM would attempt
14170Sstevel@tonic-gate * to re-use other QP's whose ref cnt is 0 in the respective
14180Sstevel@tonic-gate * port_qplist, by doing an ibmf_modify_qp with pkey above.
14190Sstevel@tonic-gate */
14200Sstevel@tonic-gate return (NULL);
14210Sstevel@tonic-gate }
14220Sstevel@tonic-gate
14230Sstevel@tonic-gate entry = kmem_alloc(sizeof (ibcm_qp_list_t), KM_SLEEP);
14240Sstevel@tonic-gate entry->qp_next = hcap->hca_port_info[port_no-1].port_qplist;
14250Sstevel@tonic-gate hcap->hca_port_info[port_no-1].port_qplist = entry;
14260Sstevel@tonic-gate entry->qp_cm = ibmf_qp;
14270Sstevel@tonic-gate entry->qp_ref_cnt = 1;
14280Sstevel@tonic-gate entry->qp_pkey = pkey;
14290Sstevel@tonic-gate entry->qp_port = &(hcap->hca_port_info[port_no-1]);
14300Sstevel@tonic-gate
14310Sstevel@tonic-gate mutex_exit(&ibcm_qp_list_lock);
14320Sstevel@tonic-gate
14330Sstevel@tonic-gate /* set-up the handler */
14340Sstevel@tonic-gate ibmf_status = ibmf_setup_async_cb(
14350Sstevel@tonic-gate hcap->hca_port_info[port_no-1].port_ibmf_hdl, ibmf_qp,
14360Sstevel@tonic-gate ibcm_recv_cb, entry, 0);
14370Sstevel@tonic-gate
14380Sstevel@tonic-gate ASSERT(ibmf_status == IBMF_SUCCESS);
14390Sstevel@tonic-gate
14400Sstevel@tonic-gate #ifdef DEBUG
14410Sstevel@tonic-gate ibcm_query_qp(hcap->hca_port_info[port_no-1].port_ibmf_hdl, ibmf_qp);
14420Sstevel@tonic-gate #endif
14430Sstevel@tonic-gate
14440Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*entry))
14450Sstevel@tonic-gate
14460Sstevel@tonic-gate return (entry);
14470Sstevel@tonic-gate }
14480Sstevel@tonic-gate
14490Sstevel@tonic-gate void
ibcm_release_qp(ibcm_qp_list_t * cm_qp_entry)14500Sstevel@tonic-gate ibcm_release_qp(ibcm_qp_list_t *cm_qp_entry)
14510Sstevel@tonic-gate {
14520Sstevel@tonic-gate mutex_enter(&ibcm_qp_list_lock);
14530Sstevel@tonic-gate --cm_qp_entry->qp_ref_cnt;
14540Sstevel@tonic-gate ASSERT(cm_qp_entry->qp_ref_cnt >= 0);
14550Sstevel@tonic-gate mutex_exit(&ibcm_qp_list_lock);
14560Sstevel@tonic-gate }
14570Sstevel@tonic-gate
14580Sstevel@tonic-gate
14590Sstevel@tonic-gate /* called holding the ibcm_qp_list_lock mutex */
14600Sstevel@tonic-gate ibcm_status_t
ibcm_free_qp(ibcm_qp_list_t * cm_qp_entry)14610Sstevel@tonic-gate ibcm_free_qp(ibcm_qp_list_t *cm_qp_entry)
14620Sstevel@tonic-gate {
14630Sstevel@tonic-gate int ibmf_status;
14640Sstevel@tonic-gate
14650Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_free_qp: qp_hdl %p ref_cnt %d pkey %x",
14660Sstevel@tonic-gate cm_qp_entry->qp_cm, cm_qp_entry->qp_ref_cnt, cm_qp_entry->qp_pkey);
14670Sstevel@tonic-gate
14680Sstevel@tonic-gate /* check, there are no users of this ibmf qp */
14690Sstevel@tonic-gate if (cm_qp_entry->qp_ref_cnt != 0)
14700Sstevel@tonic-gate return (IBCM_FAILURE);
14710Sstevel@tonic-gate
14720Sstevel@tonic-gate /* Tear down the receive callback */
14730Sstevel@tonic-gate ibmf_status = ibmf_tear_down_async_cb(
14740Sstevel@tonic-gate cm_qp_entry->qp_port->port_ibmf_hdl, cm_qp_entry->qp_cm, 0);
14750Sstevel@tonic-gate if (ibmf_status != IBMF_SUCCESS) {
14760Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_free_qp: "
14770Sstevel@tonic-gate "ibmf_tear_down_async_cb failed %d port_num %d",
14780Sstevel@tonic-gate ibmf_status, cm_qp_entry->qp_port->port_num);
14790Sstevel@tonic-gate return (IBCM_FAILURE);
14800Sstevel@tonic-gate }
14810Sstevel@tonic-gate
14820Sstevel@tonic-gate ibmf_status = ibmf_free_qp(cm_qp_entry->qp_port->port_ibmf_hdl,
14830Sstevel@tonic-gate &cm_qp_entry->qp_cm, 0);
14840Sstevel@tonic-gate if (ibmf_status != IBMF_SUCCESS) {
14850Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_free_qp: ibmf_free_qp failed for"
14860Sstevel@tonic-gate " ibmf_status %d qp hdl %p port_no %x", ibmf_status,
14870Sstevel@tonic-gate cm_qp_entry->qp_cm, cm_qp_entry->qp_port->port_num);
14880Sstevel@tonic-gate return (IBCM_FAILURE);
14890Sstevel@tonic-gate }
14900Sstevel@tonic-gate
14910Sstevel@tonic-gate return (IBCM_SUCCESS);
14920Sstevel@tonic-gate }
14930Sstevel@tonic-gate
14940Sstevel@tonic-gate ibcm_status_t
ibcm_free_allqps(ibcm_hca_info_t * hcap,int port_no)14950Sstevel@tonic-gate ibcm_free_allqps(ibcm_hca_info_t *hcap, int port_no)
14960Sstevel@tonic-gate {
14970Sstevel@tonic-gate ibcm_qp_list_t *entry, *freed;
14980Sstevel@tonic-gate ibcm_status_t ibcm_status = IBCM_SUCCESS;
14990Sstevel@tonic-gate
15000Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_free_allqps: hcap %p port_no %d", hcap,
15010Sstevel@tonic-gate port_no);
15020Sstevel@tonic-gate
15030Sstevel@tonic-gate mutex_enter(&ibcm_qp_list_lock);
15040Sstevel@tonic-gate entry = hcap->hca_port_info[port_no-1].port_qplist;
15050Sstevel@tonic-gate while ((entry != NULL) &&
15060Sstevel@tonic-gate ((ibcm_status = ibcm_free_qp(entry)) == IBCM_SUCCESS)) {
15070Sstevel@tonic-gate freed = entry;
15080Sstevel@tonic-gate entry = entry->qp_next;
15090Sstevel@tonic-gate kmem_free(freed, sizeof (ibcm_qp_list_t));
15100Sstevel@tonic-gate }
15110Sstevel@tonic-gate
15120Sstevel@tonic-gate if (ibcm_status != IBCM_SUCCESS) /* sanity the linked list */
15130Sstevel@tonic-gate hcap->hca_port_info[port_no-1].port_qplist = entry;
15140Sstevel@tonic-gate else /* all ibmf qp's of port must have been free'd successfully */
15150Sstevel@tonic-gate hcap->hca_port_info[port_no-1].port_qplist = NULL;
15160Sstevel@tonic-gate
15170Sstevel@tonic-gate mutex_exit(&ibcm_qp_list_lock);
15180Sstevel@tonic-gate return (ibcm_status);
15190Sstevel@tonic-gate }
15200Sstevel@tonic-gate
15210Sstevel@tonic-gate /*
15220Sstevel@tonic-gate * ibt_bind_service() and ibt_get_paths() needs the following helper function
15230Sstevel@tonic-gate * to handle endianess in case of Service Data.
15240Sstevel@tonic-gate */
15250Sstevel@tonic-gate void
ibcm_swizzle_from_srv(ibt_srv_data_t * sb_data,uint8_t * service_bytes)15260Sstevel@tonic-gate ibcm_swizzle_from_srv(ibt_srv_data_t *sb_data, uint8_t *service_bytes)
15270Sstevel@tonic-gate {
15280Sstevel@tonic-gate uint8_t *p8 = service_bytes;
15290Sstevel@tonic-gate uint16_t *p16;
15300Sstevel@tonic-gate uint32_t *p32;
15310Sstevel@tonic-gate uint64_t *p64;
15320Sstevel@tonic-gate int i;
15330Sstevel@tonic-gate
15340Sstevel@tonic-gate for (i = 0; i < 16; i++)
15350Sstevel@tonic-gate *p8++ = sb_data->s_data8[i];
15360Sstevel@tonic-gate
15370Sstevel@tonic-gate p16 = (uint16_t *)p8;
15380Sstevel@tonic-gate for (i = 0; i < 8; i++)
15390Sstevel@tonic-gate *p16++ = h2b16(sb_data->s_data16[i]);
15400Sstevel@tonic-gate
15410Sstevel@tonic-gate p32 = (uint32_t *)p16;
15420Sstevel@tonic-gate for (i = 0; i < 4; i++)
15430Sstevel@tonic-gate *p32++ = h2b32(sb_data->s_data32[i]);
15440Sstevel@tonic-gate
15450Sstevel@tonic-gate p64 = (uint64_t *)p32;
15460Sstevel@tonic-gate for (i = 0; i < 2; i++)
15470Sstevel@tonic-gate *p64++ = h2b64(sb_data->s_data64[i]);
15480Sstevel@tonic-gate }
15490Sstevel@tonic-gate
15500Sstevel@tonic-gate void
ibcm_swizzle_to_srv(uint8_t * service_bytes,ibt_srv_data_t * sb_data)15510Sstevel@tonic-gate ibcm_swizzle_to_srv(uint8_t *service_bytes, ibt_srv_data_t *sb_data)
15520Sstevel@tonic-gate {
15530Sstevel@tonic-gate uint8_t *p8 = service_bytes;
15540Sstevel@tonic-gate uint16_t *p16;
15550Sstevel@tonic-gate uint32_t *p32;
15560Sstevel@tonic-gate uint64_t *p64;
15570Sstevel@tonic-gate int i;
15580Sstevel@tonic-gate
15590Sstevel@tonic-gate for (i = 0; i < 16; i++)
15600Sstevel@tonic-gate sb_data->s_data8[i] = *p8++;
15610Sstevel@tonic-gate
15620Sstevel@tonic-gate p16 = (uint16_t *)p8;
15630Sstevel@tonic-gate for (i = 0; i < 8; i++)
15640Sstevel@tonic-gate sb_data->s_data16[i] = h2b16(*p16++);
15650Sstevel@tonic-gate
15660Sstevel@tonic-gate p32 = (uint32_t *)p16;
15670Sstevel@tonic-gate for (i = 0; i < 4; i++)
15680Sstevel@tonic-gate sb_data->s_data32[i] = h2b32(*p32++);
15690Sstevel@tonic-gate p64 = (uint64_t *)p32;
15700Sstevel@tonic-gate
15710Sstevel@tonic-gate for (i = 0; i < 2; i++)
15720Sstevel@tonic-gate sb_data->s_data64[i] = h2b64(*p64++);
15730Sstevel@tonic-gate }
15740Sstevel@tonic-gate
15750Sstevel@tonic-gate /* Trace related functions */
15760Sstevel@tonic-gate
15770Sstevel@tonic-gate void
ibcm_init_conn_trace(ibcm_state_data_t * sp)15780Sstevel@tonic-gate ibcm_init_conn_trace(ibcm_state_data_t *sp)
15790Sstevel@tonic-gate {
15800Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_init_conn_trace: statep %p", sp);
15810Sstevel@tonic-gate
15820Sstevel@tonic-gate /* Initialize trace related fields */
15830Sstevel@tonic-gate
15840Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sp->conn_trace))
15850Sstevel@tonic-gate sp->conn_trace = kmem_zalloc(sizeof (ibcm_conn_trace_t), KM_SLEEP);
15860Sstevel@tonic-gate if ((ibcm_enable_trace & 1) == 0)
15870Sstevel@tonic-gate sp->conn_trace->conn_base_tm = gethrtime();
15880Sstevel@tonic-gate sp->conn_trace->conn_allocated_trcnt = ibcm_conn_max_trcnt;
15890Sstevel@tonic-gate sp->conn_trace->conn_trace_events =
15900Sstevel@tonic-gate kmem_zalloc(sp->conn_trace->conn_allocated_trcnt, KM_SLEEP);
15910Sstevel@tonic-gate sp->conn_trace->conn_trace_event_times =
15920Sstevel@tonic-gate kmem_zalloc(sp->conn_trace->conn_allocated_trcnt *
15930Sstevel@tonic-gate sizeof (tm_diff_type), KM_SLEEP);
15940Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*sp->conn_trace))
15950Sstevel@tonic-gate }
15960Sstevel@tonic-gate
15970Sstevel@tonic-gate void
ibcm_fini_conn_trace(ibcm_state_data_t * statep)15980Sstevel@tonic-gate ibcm_fini_conn_trace(ibcm_state_data_t *statep)
15990Sstevel@tonic-gate {
16000Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_fini_conn_trace: statep %p tracep %p",
16010Sstevel@tonic-gate statep, statep->conn_trace);
16020Sstevel@tonic-gate
16030Sstevel@tonic-gate /* free the trace data */
16040Sstevel@tonic-gate if (statep->conn_trace) {
16050Sstevel@tonic-gate if (statep->conn_trace->conn_trace_events)
16060Sstevel@tonic-gate kmem_free(statep->conn_trace->conn_trace_events,
16070Sstevel@tonic-gate statep->conn_trace->conn_allocated_trcnt);
16080Sstevel@tonic-gate if (statep->conn_trace->conn_trace_event_times)
16090Sstevel@tonic-gate kmem_free(statep->conn_trace->conn_trace_event_times,
16100Sstevel@tonic-gate statep->conn_trace->conn_allocated_trcnt *
16110Sstevel@tonic-gate sizeof (tm_diff_type));
16120Sstevel@tonic-gate
16130Sstevel@tonic-gate kmem_free(statep->conn_trace, sizeof (ibcm_conn_trace_t));
16140Sstevel@tonic-gate }
16150Sstevel@tonic-gate }
16160Sstevel@tonic-gate
16171093Shiremath /* mostly used to profile connection establishment times with dtrace */
16181093Shiremath void
ibcm_established(hrtime_t time_diff)16191093Shiremath ibcm_established(hrtime_t time_diff)
16201093Shiremath {
16211093Shiremath if (time_diff > 1000000000LL) /* 1 second */
16221093Shiremath IBTF_DPRINTF_L2(cmlog, "slow connection time (%d seconds)",
16231093Shiremath (uint_t)(time_diff >> 30));
16241093Shiremath }
16251093Shiremath
16260Sstevel@tonic-gate void
ibcm_insert_trace(void * statep,ibcm_state_rc_trace_qualifier_t event_qualifier)16270Sstevel@tonic-gate ibcm_insert_trace(void *statep, ibcm_state_rc_trace_qualifier_t event_qualifier)
16280Sstevel@tonic-gate {
16290Sstevel@tonic-gate ibcm_conn_trace_t *conn_trace;
16300Sstevel@tonic-gate uint8_t conn_trace_ind;
1631401Shiremath hrtime_t time_diff;
1632401Shiremath hrtime_t hrt;
16330Sstevel@tonic-gate
16340Sstevel@tonic-gate if (!(((ibcm_state_data_t *)statep)->conn_trace))
16350Sstevel@tonic-gate return;
16360Sstevel@tonic-gate
16370Sstevel@tonic-gate conn_trace = ((ibcm_state_data_t *)statep)->conn_trace;
16380Sstevel@tonic-gate
16390Sstevel@tonic-gate if (!conn_trace->conn_trace_events)
16400Sstevel@tonic-gate return;
16410Sstevel@tonic-gate
16420Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_insert_trace: statep %p event %d",
16430Sstevel@tonic-gate statep, event_qualifier);
16440Sstevel@tonic-gate
16450Sstevel@tonic-gate mutex_enter(&ibcm_trace_mutex);
16460Sstevel@tonic-gate
16470Sstevel@tonic-gate /* No more trace memory available, hence return */
16480Sstevel@tonic-gate if (conn_trace->conn_trace_ind == conn_trace->conn_allocated_trcnt) {
16490Sstevel@tonic-gate mutex_exit(&ibcm_trace_mutex);
16500Sstevel@tonic-gate return;
16510Sstevel@tonic-gate } else
16520Sstevel@tonic-gate ++conn_trace->conn_trace_ind;
16530Sstevel@tonic-gate
16540Sstevel@tonic-gate conn_trace_ind = conn_trace->conn_trace_ind - 1;
16550Sstevel@tonic-gate
16560Sstevel@tonic-gate conn_trace->conn_trace_events[conn_trace_ind] = event_qualifier;
16570Sstevel@tonic-gate
16580Sstevel@tonic-gate if ((ibcm_enable_trace & 1) == 0) {
1659401Shiremath hrt = gethrtime();
16601093Shiremath time_diff = hrt - conn_trace->conn_base_tm;
16611093Shiremath if (event_qualifier == IBCM_TRACE_CALLED_CONN_EST_EVENT)
16621093Shiremath ibcm_established(time_diff);
16631093Shiremath time_diff >>= 10;
1664401Shiremath if (time_diff >= TM_DIFF_MAX) {
1665401Shiremath /* RESET, future times are relative to new base time. */
1666401Shiremath conn_trace->conn_base_tm = hrt;
16670Sstevel@tonic-gate time_diff = 0;
1668401Shiremath }
16690Sstevel@tonic-gate conn_trace->conn_trace_event_times[conn_trace_ind] = time_diff;
16700Sstevel@tonic-gate }
16710Sstevel@tonic-gate
16720Sstevel@tonic-gate mutex_exit(&ibcm_trace_mutex);
16730Sstevel@tonic-gate
16740Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_insert_trace: statep %p inserted event %d",
16750Sstevel@tonic-gate statep, event_qualifier);
16760Sstevel@tonic-gate }
16770Sstevel@tonic-gate
16780Sstevel@tonic-gate void
ibcm_dump_conn_trace(void * statep)16790Sstevel@tonic-gate ibcm_dump_conn_trace(void *statep)
16800Sstevel@tonic-gate {
16810Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_dump_conn_trace: statep %p",
16820Sstevel@tonic-gate statep);
16830Sstevel@tonic-gate
16840Sstevel@tonic-gate mutex_enter(&ibcm_trace_print_mutex);
16850Sstevel@tonic-gate ibcm_debug_buf[0] = '\0';
16860Sstevel@tonic-gate ibcm_dump_conn_trbuf(statep, "ibcm: ", ibcm_debug_buf,
16870Sstevel@tonic-gate IBCM_DEBUG_BUF_SIZE);
16880Sstevel@tonic-gate if (ibcm_debug_buf[0] != '\0')
16890Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "\n%s", ibcm_debug_buf);
16900Sstevel@tonic-gate
16910Sstevel@tonic-gate #ifdef DEBUG
16920Sstevel@tonic-gate
16930Sstevel@tonic-gate if (ibcm_test_mode > 1)
16940Sstevel@tonic-gate cmn_err(CE_CONT, "IBCM DEBUG TRACE:\n%s", ibcm_debug_buf);
16950Sstevel@tonic-gate #endif
16960Sstevel@tonic-gate
16970Sstevel@tonic-gate mutex_exit(&ibcm_trace_print_mutex);
16980Sstevel@tonic-gate }
16990Sstevel@tonic-gate
17000Sstevel@tonic-gate void
ibcm_dump_conn_trbuf(void * statep,char * line_prefix,char * buf,int buf_size)17010Sstevel@tonic-gate ibcm_dump_conn_trbuf(void *statep, char *line_prefix, char *buf, int buf_size)
17020Sstevel@tonic-gate {
17030Sstevel@tonic-gate ibcm_conn_trace_t *conn_trace;
17040Sstevel@tonic-gate int tr_ind;
17050Sstevel@tonic-gate ibcm_state_data_t *sp;
17060Sstevel@tonic-gate int cur_size = 0; /* size of item copied */
17070Sstevel@tonic-gate int rem_size; /* remaining size in trace buffer */
17080Sstevel@tonic-gate int next_data = 0; /* location where next item copied */
17090Sstevel@tonic-gate
17100Sstevel@tonic-gate if ((buf == NULL) || (buf_size <= 0))
17110Sstevel@tonic-gate return;
17120Sstevel@tonic-gate
17130Sstevel@tonic-gate sp = (ibcm_state_data_t *)statep;
17140Sstevel@tonic-gate
17150Sstevel@tonic-gate if (!sp->conn_trace)
17160Sstevel@tonic-gate return;
17170Sstevel@tonic-gate
17180Sstevel@tonic-gate conn_trace = sp->conn_trace;
17190Sstevel@tonic-gate
17200Sstevel@tonic-gate if (!conn_trace->conn_trace_events)
17210Sstevel@tonic-gate return;
17220Sstevel@tonic-gate
17230Sstevel@tonic-gate rem_size = buf_size;
17240Sstevel@tonic-gate
17250Sstevel@tonic-gate /* Print connection level global data */
17260Sstevel@tonic-gate
17270Sstevel@tonic-gate /* Print statep, local comid, local qpn */
17280Sstevel@tonic-gate cur_size = snprintf(&buf[next_data], rem_size, "%s%s0x%p\n%s%s0x%p\n"
1729401Shiremath "%s%s0x%x/%llx/%d\n%s%s0x%x\n%s%s0x%x/%llx\n%s%s0x%x\n%s%s%llu\n",
17300Sstevel@tonic-gate line_prefix, event_str[IBCM_DISPLAY_SID], (void *)sp,
17310Sstevel@tonic-gate line_prefix, event_str[IBCM_DISPLAY_CHAN], (void *)sp->channel,
17320Sstevel@tonic-gate line_prefix, event_str[IBCM_DISPLAY_LCID], sp->local_comid,
17330Sstevel@tonic-gate (longlong_t)sp->local_hca_guid, sp->prim_port,
17340Sstevel@tonic-gate line_prefix, event_str[IBCM_DISPLAY_LQPN], sp->local_qpn,
17350Sstevel@tonic-gate line_prefix, event_str[IBCM_DISPLAY_RCID], sp->remote_comid,
17360Sstevel@tonic-gate (longlong_t)sp->remote_hca_guid,
17370Sstevel@tonic-gate line_prefix, event_str[IBCM_DISPLAY_RQPN], sp->remote_qpn,
17380Sstevel@tonic-gate line_prefix, event_str[IBCM_DISPLAY_TM], conn_trace->conn_base_tm);
17390Sstevel@tonic-gate
17400Sstevel@tonic-gate rem_size = rem_size - cur_size;
17410Sstevel@tonic-gate if (rem_size <= 0) {
17420Sstevel@tonic-gate buf[buf_size-1] = '\n';
17430Sstevel@tonic-gate return;
17440Sstevel@tonic-gate }
17450Sstevel@tonic-gate
17460Sstevel@tonic-gate next_data = next_data + cur_size;
17470Sstevel@tonic-gate
17480Sstevel@tonic-gate for (tr_ind = 0; tr_ind < conn_trace->conn_trace_ind; tr_ind++) {
17490Sstevel@tonic-gate cur_size = snprintf(&buf[next_data], rem_size,
17500Sstevel@tonic-gate "%s%sTM_DIFF %u\n", line_prefix,
17510Sstevel@tonic-gate event_str[conn_trace->conn_trace_events[tr_ind]],
17520Sstevel@tonic-gate conn_trace->conn_trace_event_times[tr_ind]);
17530Sstevel@tonic-gate rem_size = rem_size - cur_size;
17540Sstevel@tonic-gate if (rem_size <= 0) {
17550Sstevel@tonic-gate buf[buf_size-1] = '\n';
17560Sstevel@tonic-gate return;
17570Sstevel@tonic-gate }
17580Sstevel@tonic-gate next_data = next_data + cur_size;
17590Sstevel@tonic-gate }
17600Sstevel@tonic-gate
17610Sstevel@tonic-gate buf[next_data] = '\0';
17620Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_dump_conn_trbuf: statep %p "
17630Sstevel@tonic-gate "debug buf size %d bytes", statep, next_data);
17640Sstevel@tonic-gate }
17650Sstevel@tonic-gate
17660Sstevel@tonic-gate
17670Sstevel@tonic-gate #ifdef DEBUG
17680Sstevel@tonic-gate
17690Sstevel@tonic-gate void
ibcm_query_qp(ibmf_handle_t ibmf_hdl,ibmf_qp_handle_t ibmf_qp)17700Sstevel@tonic-gate ibcm_query_qp(ibmf_handle_t ibmf_hdl, ibmf_qp_handle_t ibmf_qp)
17710Sstevel@tonic-gate {
17720Sstevel@tonic-gate uint8_t qp_port_num;
17730Sstevel@tonic-gate ib_qpn_t qp_num;
17740Sstevel@tonic-gate ib_pkey_t qp_pkey;
17750Sstevel@tonic-gate ib_qkey_t qp_qkey;
17760Sstevel@tonic-gate int ibmf_status;
17770Sstevel@tonic-gate
17780Sstevel@tonic-gate if (ibmf_qp == IBMF_QP_HANDLE_DEFAULT) {
17790Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_query_qp: QP1");
17800Sstevel@tonic-gate return;
17810Sstevel@tonic-gate }
17820Sstevel@tonic-gate
17830Sstevel@tonic-gate ibmf_status =
17840Sstevel@tonic-gate ibmf_query_qp(ibmf_hdl, ibmf_qp, &qp_num, &qp_pkey, &qp_qkey,
17850Sstevel@tonic-gate &qp_port_num, 0);
17860Sstevel@tonic-gate
17870Sstevel@tonic-gate ASSERT(ibmf_status == IBMF_SUCCESS);
17880Sstevel@tonic-gate
17891093Shiremath IBTF_DPRINTF_L5(cmlog, "ibcm_query_qp: qpn %x qkey %x pkey %x port %d",
17900Sstevel@tonic-gate qp_num, qp_qkey, qp_pkey, qp_port_num);
17910Sstevel@tonic-gate }
17920Sstevel@tonic-gate
17930Sstevel@tonic-gate /*
17940Sstevel@tonic-gate * ibcm_dump_raw_message:
17950Sstevel@tonic-gate * dumps 256 bytes of data of a raw message (REP/REQ/DREQ ...)
17960Sstevel@tonic-gate * (can be called from the kernel debugger w/ the message pointer)
17970Sstevel@tonic-gate *
17980Sstevel@tonic-gate * Arguments:
17990Sstevel@tonic-gate * msgp - the messages that needs to be dumped
18000Sstevel@tonic-gate *
18010Sstevel@tonic-gate * Return values: NONE
18020Sstevel@tonic-gate */
18030Sstevel@tonic-gate void
ibcm_dump_raw_message(uchar_t * c)18040Sstevel@tonic-gate ibcm_dump_raw_message(uchar_t *c)
18050Sstevel@tonic-gate {
18060Sstevel@tonic-gate int i;
18070Sstevel@tonic-gate
18080Sstevel@tonic-gate for (i = 0; i < IBCM_MAD_SIZE; i += 16) {
18090Sstevel@tonic-gate /* print in batches of 16 chars at a time */
18100Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog,
18110Sstevel@tonic-gate "%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
18120Sstevel@tonic-gate c[i], c[i + 1], c[i + 2], c[i + 3], c[i + 4], c[i + 5],
18130Sstevel@tonic-gate c[i + 6], c[i + 7], c[i + 8], c[i + 9], c[i + 10],
18140Sstevel@tonic-gate c[i + 11], c[i + 12], c[i + 13], c[i + 14], c[i + 15]);
18150Sstevel@tonic-gate }
18160Sstevel@tonic-gate }
18170Sstevel@tonic-gate
18180Sstevel@tonic-gate
18190Sstevel@tonic-gate /*
18200Sstevel@tonic-gate * ibcm_dump_srv_rec:
18210Sstevel@tonic-gate * Dumps Service Records.
18220Sstevel@tonic-gate *
18230Sstevel@tonic-gate * Arguments:
18240Sstevel@tonic-gate * srv_rec - the pointer to sa_service_record_t struct.
18250Sstevel@tonic-gate *
18260Sstevel@tonic-gate * Return values: NONE
18270Sstevel@tonic-gate */
18280Sstevel@tonic-gate void
ibcm_dump_srvrec(sa_service_record_t * srv_rec)18290Sstevel@tonic-gate ibcm_dump_srvrec(sa_service_record_t *srv_rec)
18300Sstevel@tonic-gate {
18310Sstevel@tonic-gate uint8_t i;
18320Sstevel@tonic-gate
18330Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_dump_srvrec: Service Records");
18340Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "SID : 0x%016llX", srv_rec->ServiceID);
18350Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "Svc GID : 0x%016llX:0x%016llX",
18360Sstevel@tonic-gate srv_rec->ServiceGID.gid_prefix, srv_rec->ServiceGID.gid_guid);
18370Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "Svc PKey : 0x%X", srv_rec->ServiceP_Key);
18380Sstevel@tonic-gate
18390Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "Svc Lease : 0x%lX", srv_rec->ServiceLease);
18400Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "Svc Key-hi: 0x%016llX", srv_rec->ServiceKey_hi);
18410Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "Svc Key-lo: 0x%016llX", srv_rec->ServiceKey_lo);
18420Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "Svc Name : %s", srv_rec->ServiceName);
18430Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "Svc Data : ");
18440Sstevel@tonic-gate for (i = 0; i < IB_SVC_DATA_LEN; i += 8) {
18450Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog,
18460Sstevel@tonic-gate "\t 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X",
18470Sstevel@tonic-gate srv_rec->ServiceData[i], srv_rec->ServiceData[i+1],
18480Sstevel@tonic-gate srv_rec->ServiceData[i+2], srv_rec->ServiceData[i+3],
18490Sstevel@tonic-gate srv_rec->ServiceData[i+4], srv_rec->ServiceData[i+5],
18500Sstevel@tonic-gate srv_rec->ServiceData[i+6], srv_rec->ServiceData[i+7]);
18510Sstevel@tonic-gate }
18520Sstevel@tonic-gate }
18530Sstevel@tonic-gate
18540Sstevel@tonic-gate
18550Sstevel@tonic-gate /*
18560Sstevel@tonic-gate * ibcm_dump_pathrec:
18570Sstevel@tonic-gate * Dumps Path Records.
18580Sstevel@tonic-gate *
18590Sstevel@tonic-gate * Arguments:
18600Sstevel@tonic-gate * path_rec - the pointer to sa_path_record_t struct.
18610Sstevel@tonic-gate *
18620Sstevel@tonic-gate * Return values: NONE
18630Sstevel@tonic-gate */
18640Sstevel@tonic-gate void
ibcm_dump_pathrec(sa_path_record_t * path_rec)18650Sstevel@tonic-gate ibcm_dump_pathrec(sa_path_record_t *path_rec)
18660Sstevel@tonic-gate {
18670Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Path Record:");
18680Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "SGID: (sn_prefix) %016llX",
18690Sstevel@tonic-gate path_rec->SGID.gid_prefix);
18700Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "SGID: (GUID) %016llX",
18710Sstevel@tonic-gate path_rec->SGID.gid_guid);
18720Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "DGID: (sn_prefix) %016llX",
18730Sstevel@tonic-gate path_rec->DGID.gid_prefix);
18740Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "DGID: (GUID) %016llX",
18750Sstevel@tonic-gate path_rec->DGID.gid_guid);
18760Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "SLID: %04X", path_rec->SLID);
18770Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "DLID: %04X", path_rec->DLID);
18780Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Raw Traffic: %01X", path_rec->RawTraffic);
18790Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Flow Label: %05X", path_rec->FlowLabel);
18800Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Hop Limit: %02X", path_rec->HopLimit);
18810Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "TClass: %02X", path_rec->TClass);
18820Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Reversible: %01X", path_rec->Reversible);
18830Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Numb Paths: %02d", path_rec->NumbPath);
18840Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "P_Key: %04X", path_rec->P_Key);
18850Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "SL: %02X", path_rec->SL);
18860Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Path MTU Selector: %01X",
18870Sstevel@tonic-gate path_rec->MtuSelector);
18880Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Path MTU: %02X", path_rec->Mtu);
18890Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Path Rate Selector:%01X",
18900Sstevel@tonic-gate path_rec->RateSelector);
18910Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Path Rate: %02X", path_rec->Rate);
18920Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Packet LT Selector:%01X",
18930Sstevel@tonic-gate path_rec->PacketLifeTimeSelector);
18940Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Packet Life Time: %d (dec)",
18950Sstevel@tonic-gate path_rec->PacketLifeTime);
18960Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Preference Bit: %02X", path_rec->Preference);
18970Sstevel@tonic-gate }
18980Sstevel@tonic-gate
18990Sstevel@tonic-gate /*
19000Sstevel@tonic-gate * ibcm_dump_node_rec:
19010Sstevel@tonic-gate * Dumps Node Records.
19020Sstevel@tonic-gate *
19030Sstevel@tonic-gate * Arguments:
19040Sstevel@tonic-gate * nrec - the pointer to sa_node_record_t struct.
19050Sstevel@tonic-gate *
19060Sstevel@tonic-gate * Return values: NONE
19070Sstevel@tonic-gate */
19080Sstevel@tonic-gate void
ibcm_dump_noderec(sa_node_record_t * nrec)19090Sstevel@tonic-gate ibcm_dump_noderec(sa_node_record_t *nrec)
19100Sstevel@tonic-gate {
19110Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_dump_noderec: Node Info Record");
19120Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "LID : %04X", nrec->LID);
19130Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Base Ver : %02X", nrec->NodeInfo.BaseVersion);
19140Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Class Ver : %02X", nrec->NodeInfo.ClassVersion);
19150Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Node Type : %02d", nrec->NodeInfo.NodeType);
19160Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Num Ports : %02X", nrec->NodeInfo.NumPorts);
19170Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "SysImgGUID: %016llX",
19180Sstevel@tonic-gate nrec->NodeInfo.SystemImageGUID);
19190Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "NODE GUID : %016llX", nrec->NodeInfo.NodeGUID);
19200Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Port GUID : %016llX", nrec->NodeInfo.PortGUID);
19210Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "PartionCap: %04X", nrec->NodeInfo.PartitionCap);
19220Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Device ID : %04X", nrec->NodeInfo.DeviceID);
19230Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Revision : %06X", nrec->NodeInfo.Revision);
19240Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "LocalPort#: %02X", nrec->NodeInfo.LocalPortNum);
19250Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Vendor ID : %06X", nrec->NodeInfo.VendorID);
19260Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "Description: %s",
19270Sstevel@tonic-gate (char *)&nrec->NodeDescription);
19280Sstevel@tonic-gate }
19290Sstevel@tonic-gate #endif
19300Sstevel@tonic-gate
1931*9891SRajkumar.Sivaprakasam@Sun.COM /*
1932*9891SRajkumar.Sivaprakasam@Sun.COM * ibcm_ibtl_node_info:
1933*9891SRajkumar.Sivaprakasam@Sun.COM * Get the node record of the destination specified by lid via the HCA
1934*9891SRajkumar.Sivaprakasam@Sun.COM * and port specified.
1935*9891SRajkumar.Sivaprakasam@Sun.COM *
1936*9891SRajkumar.Sivaprakasam@Sun.COM * Arguments:
1937*9891SRajkumar.Sivaprakasam@Sun.COM * hca_guid - GUID of the local HCA.
1938*9891SRajkumar.Sivaprakasam@Sun.COM * port - port in the HCA to be used.
1939*9891SRajkumar.Sivaprakasam@Sun.COM * lid - destination LID
1940*9891SRajkumar.Sivaprakasam@Sun.COM * node_info_p - pointer to the Node Info to be returned.
1941*9891SRajkumar.Sivaprakasam@Sun.COM *
1942*9891SRajkumar.Sivaprakasam@Sun.COM * Return values:
1943*9891SRajkumar.Sivaprakasam@Sun.COM * IBT_SUCCESS : Got the node record sucessfully
1944*9891SRajkumar.Sivaprakasam@Sun.COM * IBT_FILURE : Failed to get the node record.
1945*9891SRajkumar.Sivaprakasam@Sun.COM */
1946*9891SRajkumar.Sivaprakasam@Sun.COM 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*9891SRajkumar.Sivaprakasam@Sun.COM ibcm_ibtl_node_info(ib_guid_t hca_guid, uint8_t port, ib_lid_t lid,
1948*9891SRajkumar.Sivaprakasam@Sun.COM ibt_node_info_t *node_info_p)
1949*9891SRajkumar.Sivaprakasam@Sun.COM {
1950*9891SRajkumar.Sivaprakasam@Sun.COM sa_node_record_t nr_req, *nr_resp;
1951*9891SRajkumar.Sivaprakasam@Sun.COM void *res_p;
1952*9891SRajkumar.Sivaprakasam@Sun.COM ibmf_saa_handle_t saa_handle;
1953*9891SRajkumar.Sivaprakasam@Sun.COM ibt_status_t ibt_status;
1954*9891SRajkumar.Sivaprakasam@Sun.COM ibcm_hca_info_t *hcap;
1955*9891SRajkumar.Sivaprakasam@Sun.COM uint_t num_rec;
1956*9891SRajkumar.Sivaprakasam@Sun.COM size_t len;
1957*9891SRajkumar.Sivaprakasam@Sun.COM
1958*9891SRajkumar.Sivaprakasam@Sun.COM IBTF_DPRINTF_L3(cmlog, "ibcm_ibtl_node_info: ENTER: port %x "
1959*9891SRajkumar.Sivaprakasam@Sun.COM "guid %llx\n", port, hca_guid);
1960*9891SRajkumar.Sivaprakasam@Sun.COM
1961*9891SRajkumar.Sivaprakasam@Sun.COM hcap = ibcm_find_hca_entry(hca_guid);
1962*9891SRajkumar.Sivaprakasam@Sun.COM if (hcap == NULL) {
1963*9891SRajkumar.Sivaprakasam@Sun.COM IBTF_DPRINTF_L2(cmlog, "ibcm_ibtl_node_info: "
1964*9891SRajkumar.Sivaprakasam@Sun.COM "HCA(%llX) info not found", hca_guid);
1965*9891SRajkumar.Sivaprakasam@Sun.COM return (IBT_FAILURE);
1966*9891SRajkumar.Sivaprakasam@Sun.COM }
1967*9891SRajkumar.Sivaprakasam@Sun.COM
1968*9891SRajkumar.Sivaprakasam@Sun.COM /* Get SA Access Handle. */
1969*9891SRajkumar.Sivaprakasam@Sun.COM saa_handle = ibcm_get_saa_handle(hcap, port);
1970*9891SRajkumar.Sivaprakasam@Sun.COM if (saa_handle == NULL) {
1971*9891SRajkumar.Sivaprakasam@Sun.COM IBTF_DPRINTF_L2(cmlog, "ibcm_ibtl_node_info: "
1972*9891SRajkumar.Sivaprakasam@Sun.COM "Port %d of HCA (%llX) is NOT ACTIVE", port, hca_guid);
1973*9891SRajkumar.Sivaprakasam@Sun.COM ibcm_dec_hca_acc_cnt(hcap);
1974*9891SRajkumar.Sivaprakasam@Sun.COM return (IBT_FAILURE);
1975*9891SRajkumar.Sivaprakasam@Sun.COM }
1976*9891SRajkumar.Sivaprakasam@Sun.COM
1977*9891SRajkumar.Sivaprakasam@Sun.COM /* Retrieve Node Records from SA Access. */
1978*9891SRajkumar.Sivaprakasam@Sun.COM bzero(&nr_req, sizeof (sa_node_record_t));
1979*9891SRajkumar.Sivaprakasam@Sun.COM nr_req.LID = lid;
1980*9891SRajkumar.Sivaprakasam@Sun.COM
1981*9891SRajkumar.Sivaprakasam@Sun.COM ibt_status = ibcm_get_node_rec(saa_handle, &nr_req,
1982*9891SRajkumar.Sivaprakasam@Sun.COM SA_NODEINFO_COMPMASK_NODELID, &res_p, &len);
1983*9891SRajkumar.Sivaprakasam@Sun.COM if (ibt_status != IBT_SUCCESS) {
1984*9891SRajkumar.Sivaprakasam@Sun.COM IBTF_DPRINTF_L2(cmlog, "ibcm_ibtl_node_info: "
1985*9891SRajkumar.Sivaprakasam@Sun.COM "failed (%d) to get Node records", ibt_status);
1986*9891SRajkumar.Sivaprakasam@Sun.COM ibcm_dec_hca_acc_cnt(hcap);
1987*9891SRajkumar.Sivaprakasam@Sun.COM return (IBT_FAILURE);
1988*9891SRajkumar.Sivaprakasam@Sun.COM }
1989*9891SRajkumar.Sivaprakasam@Sun.COM
1990*9891SRajkumar.Sivaprakasam@Sun.COM num_rec = len/sizeof (sa_node_record_t);
1991*9891SRajkumar.Sivaprakasam@Sun.COM nr_resp = (sa_node_record_t *)(uchar_t *)res_p;
1992*9891SRajkumar.Sivaprakasam@Sun.COM
1993*9891SRajkumar.Sivaprakasam@Sun.COM if ((nr_resp != NULL) && (num_rec > 0)) {
1994*9891SRajkumar.Sivaprakasam@Sun.COM IBCM_DUMP_NODE_REC(nr_resp);
1995*9891SRajkumar.Sivaprakasam@Sun.COM
1996*9891SRajkumar.Sivaprakasam@Sun.COM _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(
1997*9891SRajkumar.Sivaprakasam@Sun.COM *node_info_p))
1998*9891SRajkumar.Sivaprakasam@Sun.COM
1999*9891SRajkumar.Sivaprakasam@Sun.COM node_info_p->n_sys_img_guid =
2000*9891SRajkumar.Sivaprakasam@Sun.COM nr_resp->NodeInfo.SystemImageGUID;
2001*9891SRajkumar.Sivaprakasam@Sun.COM node_info_p->n_node_guid =
2002*9891SRajkumar.Sivaprakasam@Sun.COM nr_resp->NodeInfo.NodeGUID;
2003*9891SRajkumar.Sivaprakasam@Sun.COM node_info_p->n_port_guid =
2004*9891SRajkumar.Sivaprakasam@Sun.COM nr_resp->NodeInfo.PortGUID;
2005*9891SRajkumar.Sivaprakasam@Sun.COM node_info_p->n_dev_id =
2006*9891SRajkumar.Sivaprakasam@Sun.COM nr_resp->NodeInfo.DeviceID;
2007*9891SRajkumar.Sivaprakasam@Sun.COM node_info_p->n_revision =
2008*9891SRajkumar.Sivaprakasam@Sun.COM nr_resp->NodeInfo.Revision;
2009*9891SRajkumar.Sivaprakasam@Sun.COM node_info_p->n_vendor_id =
2010*9891SRajkumar.Sivaprakasam@Sun.COM nr_resp->NodeInfo.VendorID;
2011*9891SRajkumar.Sivaprakasam@Sun.COM node_info_p->n_num_ports =
2012*9891SRajkumar.Sivaprakasam@Sun.COM nr_resp->NodeInfo.NumPorts;
2013*9891SRajkumar.Sivaprakasam@Sun.COM node_info_p->n_port_num =
2014*9891SRajkumar.Sivaprakasam@Sun.COM nr_resp->NodeInfo.LocalPortNum;
2015*9891SRajkumar.Sivaprakasam@Sun.COM node_info_p->n_node_type =
2016*9891SRajkumar.Sivaprakasam@Sun.COM nr_resp->NodeInfo.NodeType;
2017*9891SRajkumar.Sivaprakasam@Sun.COM (void) strncpy(node_info_p->n_description,
2018*9891SRajkumar.Sivaprakasam@Sun.COM (char *)&nr_resp->NodeDescription, 64);
2019*9891SRajkumar.Sivaprakasam@Sun.COM _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(
2020*9891SRajkumar.Sivaprakasam@Sun.COM *node_info_p))
2021*9891SRajkumar.Sivaprakasam@Sun.COM
2022*9891SRajkumar.Sivaprakasam@Sun.COM
2023*9891SRajkumar.Sivaprakasam@Sun.COM kmem_free(nr_resp, len);
2024*9891SRajkumar.Sivaprakasam@Sun.COM }
2025*9891SRajkumar.Sivaprakasam@Sun.COM ibcm_dec_hca_acc_cnt(hcap);
2026*9891SRajkumar.Sivaprakasam@Sun.COM return (IBT_SUCCESS);
2027*9891SRajkumar.Sivaprakasam@Sun.COM }
20280Sstevel@tonic-gate
20290Sstevel@tonic-gate /*
20300Sstevel@tonic-gate * ibcm_ibmf_analyze_error:
20310Sstevel@tonic-gate * Checks IBMF status and determines appropriate ibt status.
20320Sstevel@tonic-gate *
20330Sstevel@tonic-gate * Arguments:
20340Sstevel@tonic-gate * ibmf_status - IBMF Status
20350Sstevel@tonic-gate *
20360Sstevel@tonic-gate * Return values:
20370Sstevel@tonic-gate * ibt_status_t
20380Sstevel@tonic-gate */
20390Sstevel@tonic-gate ibt_status_t
ibcm_ibmf_analyze_error(int ibmf_status)20400Sstevel@tonic-gate ibcm_ibmf_analyze_error(int ibmf_status)
20410Sstevel@tonic-gate {
20420Sstevel@tonic-gate if (ibt_check_failure(ibmf_status, NULL) != IBT_FAILURE_STANDARD) {
20430Sstevel@tonic-gate /*
20440Sstevel@tonic-gate * IBMF specific failure, return special error code
20450Sstevel@tonic-gate * to the client so that it can retrieve any associated ENA.
20460Sstevel@tonic-gate */
20470Sstevel@tonic-gate return (ibmf_status);
20489335SShantkumar.Hiremath@Sun.COM } else if (ibmf_status == IBMF_TRANS_TIMEOUT) {
20499335SShantkumar.Hiremath@Sun.COM return (IBT_IBMF_TIMEOUT);
20500Sstevel@tonic-gate } else {
20510Sstevel@tonic-gate /*
20520Sstevel@tonic-gate * IBMF failed for some other reason, invalid arguments etc.
20530Sstevel@tonic-gate * Analyze, log ENA with IBTF and obtain a special ibt_status_t
20540Sstevel@tonic-gate * that indicates IBMF failure.
20550Sstevel@tonic-gate */
20560Sstevel@tonic-gate if ((ibmf_status == IBMF_BAD_CLASS) ||
20570Sstevel@tonic-gate (ibmf_status == IBMF_BAD_HANDLE) ||
20580Sstevel@tonic-gate (ibmf_status == IBMF_BAD_QP_HANDLE) ||
20590Sstevel@tonic-gate (ibmf_status == IBMF_BAD_NODE) ||
20600Sstevel@tonic-gate (ibmf_status == IBMF_BAD_PORT) ||
20610Sstevel@tonic-gate (ibmf_status == IBMF_BAD_VERSION) ||
20620Sstevel@tonic-gate (ibmf_status == IBMF_BAD_FLAGS) ||
20630Sstevel@tonic-gate (ibmf_status == IBMF_BAD_SIZE) ||
20640Sstevel@tonic-gate (ibmf_status == IBMF_INVALID_GID) ||
20650Sstevel@tonic-gate (ibmf_status == IBMF_INVALID_ARG) ||
20660Sstevel@tonic-gate (ibmf_status == IBMF_INVALID_FIELD) ||
20670Sstevel@tonic-gate (ibmf_status == IBMF_UNSUPP_METHOD) ||
20680Sstevel@tonic-gate (ibmf_status == IBMF_UNSUPP_METHOD_ATTR)) {
20690Sstevel@tonic-gate
20700Sstevel@tonic-gate /*
20710Sstevel@tonic-gate * These errors, we should not see...
20720Sstevel@tonic-gate * something really bad happened!.
20730Sstevel@tonic-gate */
20740Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_ibmf_analyze_error: "
20750Sstevel@tonic-gate "Unexpected ERROR from IBMF - %d", ibmf_status);
20760Sstevel@tonic-gate }
20770Sstevel@tonic-gate return (ibt_get_module_failure(IBT_FAILURE_IBMF, 0));
20780Sstevel@tonic-gate }
20790Sstevel@tonic-gate }
2080