Print this page
8368 remove warlock leftovers from usr/src/uts


  23  */
  24 
  25 #include <sys/ib/mgt/ibcm/ibcm_impl.h>
  26 #include <sys/ib/ibtl/ibti.h>
  27 #include <sys/ib/mgt/ibcm/ibcm_arp.h>
  28 
  29 /*
  30  * ibcm_ti.c
  31  *      These routines implement the Communication Manager's interfaces to IBTL.
  32  */
  33 
  34 /* CM rc recycle task args structure definition */
  35 typedef struct ibcm_taskq_recycle_arg_s {
  36         ibt_channel_hdl_t       rc_chan;
  37         ibt_cep_flags_t         control;
  38         uint8_t                 hca_port_num;
  39         ibt_recycle_handler_t   func;
  40         void                    *arg;
  41 } ibcm_taskq_recycle_arg_t;
  42 
  43 _NOTE(READ_ONLY_DATA(ibcm_taskq_recycle_arg_s))
  44 
  45 static ibt_status_t     ibcm_init_reply_addr(ibcm_hca_info_t *hcap,
  46     ibcm_mad_addr_t *reply_addr, ibt_chan_open_args_t *chan_args,
  47     ibt_chan_open_flags_t flags, ib_time_t *cm_pkt_lt, ib_lid_t prim_slid);
  48 static void             ibcm_process_abort_via_taskq(void *args);
  49 static ibt_status_t     ibcm_process_rc_recycle_ret(void *recycle_arg);
  50 static ibt_status_t     ibcm_process_join_mcg(void *taskq_arg);
  51 static void             ibcm_process_async_join_mcg(void *tq_arg);
  52 
  53 ibt_status_t ibcm_get_node_rec(ibmf_saa_handle_t, sa_node_record_t *,
  54     uint64_t c_mask, void *, size_t *);
  55 
  56 static ibt_status_t ibcm_close_rc_channel(ibt_channel_hdl_t channel,
  57     ibcm_state_data_t *statep, ibt_execution_mode_t mode);
  58 
  59 /* Address Record management definitions */
  60 #define IBCM_DAPL_ATS_NAME      "DAPL Address Translation Service"
  61 #define IBCM_DAPL_ATS_SID       0x10000CE100415453ULL
  62 #define IBCM_DAPL_ATS_NBYTES    16
  63 ibcm_svc_info_t *ibcm_ar_svcinfop;
  64 ibcm_ar_t       *ibcm_ar_list;
  65 
  66 /*
  67  * Tunable parameter to turnoff the overriding of pi_path_mtu value.
  68  *      1       By default override the path record's pi_path_mtu value to
  69  *              IB_MTU_1K for all RC channels. This is done only for the
  70  *              channels established on Tavor HCA and the path's pi_path_mtu
  71  *              is greater than IB_MTU_1K.
  72  *      0       Do not override, use pi_path_mtu by default.
  73  */
  74 int     ibcm_override_path_mtu = 1;
  75 
  76 #ifdef DEBUG
  77 static void     ibcm_print_reply_addr(ibt_channel_hdl_t channel,
  78                     ibcm_mad_addr_t *cm_reply_addr);
  79 #endif
  80 
  81 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibcm_port_info_s::{port_ibmf_hdl}))
  82 
  83 /* access is controlled between ibcm_sm.c and ibcm_ti.c by CVs */
  84 _NOTE(SCHEME_PROTECTS_DATA("Serialized access by CV", {ibt_rc_returns_t
  85     ibt_ud_returns_t ibt_ap_returns_t ibt_ar_t}))
  86 
  87 /*
  88  * Typically, clients initialize these args in one api call, and use in
  89  * another api
  90  */
  91 _NOTE(SCHEME_PROTECTS_DATA("Expected usage of ibtl api by client",
  92     {ibt_path_info_s ibt_cep_path_s ibt_adds_vect_s ibt_mcg_info_s ib_gid_s
  93     ibt_ud_dest_attr_s ibt_ud_dest_s ibt_srv_data_s ibt_redirect_info_s}))
  94 
  95 /*
  96  * ibt_open_rc_channel()
  97  *      ibt_open_rc_channel opens a communication channel on the specified
  98  *      channel to the specified service. For connection service type qp's
  99  *      the CM initiates the CEP to establish the connection and transitions
 100  *      the QP/EEC to the "Ready to send" State modifying the QP/EEC's
 101  *      attributes as necessary.
 102  *      The implementation of this function assumes that alt path is different
 103  *      from primary path. It is assumed that the Path functions ensure that.
 104  *
 105  * RETURN VALUES:
 106  *      IBT_SUCCESS     on success (or respective failure on error)
 107  */
 108 ibt_status_t
 109 ibt_open_rc_channel(ibt_channel_hdl_t channel, ibt_chan_open_flags_t flags,
 110     ibt_execution_mode_t mode, ibt_chan_open_args_t *chan_args,
 111     ibt_rc_returns_t *ret_args)
 112 {
 113         /* all fields that are related to REQ MAD formation */
 114 
 115         ib_pkey_t               prim_pkey;


 559                         IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: "
 560                             "chan 0x%p ibt_modify_qp() = %d", channel, status);
 561         }
 562 
 563         /* allocate ibcm_state_data_t before grabbing the WRITER lock */
 564         statep = kmem_zalloc(sizeof (ibcm_state_data_t), KM_SLEEP);
 565         rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
 566         lkup_status = ibcm_lookup_msg(IBCM_OUTGOING_REQ, local_comid, 0, 0,
 567             hcap, &statep);
 568         rw_exit(&hcap->hca_state_rwlock);
 569 
 570         /* CM should be seeing this for the first time */
 571         ASSERT(lkup_status == IBCM_LOOKUP_NEW);
 572 
 573         /* Increment the hca's resource count */
 574         ibcm_inc_hca_res_cnt(hcap);
 575 
 576         /* Once a resource created on hca, no need to hold the acc cnt */
 577         ibcm_dec_hca_acc_cnt(hcap);
 578 
 579         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
 580 
 581         statep->timerid = 0;
 582         statep->local_hca_guid = hca_guid;
 583         statep->local_qpn = local_qpn;
 584         statep->stored_reply_addr.cm_qp_entry = cm_qp_entry;
 585         statep->prim_port = IBCM_PRIM_CEP_PATH(chan_args).cep_hca_port_num;
 586         statep->alt_port = IBCM_ALT_CEP_PATH(chan_args).cep_hca_port_num;
 587 
 588 
 589         /* Save "statep" as channel's CM private data.  */
 590         statep->channel = channel;
 591         IBCM_SET_CHAN_PRIVATE(statep->channel, statep);
 592 
 593         statep->stored_msg = ibmf_msg;
 594         statep->dreq_msg = ibmf_msg_dreq;
 595 
 596         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*req_msgp))
 597 
 598         /* Start filling in the REQ MAD */
 599         req_msgp = (ibcm_req_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
 600         req_msgp->req_local_comm_id = h2b32(local_comid);
 601         req_msgp->req_svc_id = h2b64(chan_args->oc_path->pi_sid);
 602         req_msgp->req_local_ca_guid = h2b64(hca_guid);
 603         req_msgp->req_local_qkey = h2b32(local_qkey);        /* for EEC/RD */
 604 
 605         /* Bytes 32-35 are req_local_qpn and req_off_resp_resources */
 606         req_msgp->req_local_qpn_plus = h2b32(local_qpn << 8 | rdma_in);
 607 
 608         /* Bytes 36-39 are req_local_eec_no and req_off_initiator_depth */
 609         req_msgp->req_local_eec_no_plus = h2b32(local_eecn << 8 | rdma_out);
 610 
 611         if (flags & IBT_OCHAN_REMOTE_CM_TM)
 612                 remote_cm_resp_time = chan_args->oc_remote_cm_time;
 613         else
 614                 remote_cm_resp_time = ibcm_remote_response_time;
 615 
 616         /*
 617          * Bytes 40-43 - remote_eecn, remote_cm_resp_time, tran_type,


 793                     IBCM_ALT_ADDS_VECT(chan_args).av_srvl << 4 |
 794                     ((alternate_grh == B_TRUE) ? 0 : 8);
 795                 req_msgp->req_alt_localtime_plus = ibt_usec2ib((2 *
 796                     ibt_ib2usec(chan_args->oc_path->pi_alt_pkt_lt)) +
 797                     ibt_ib2usec(hcap->hca_ack_delay)) << 3;
 798 
 799                 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
 800                     "alt_dlid %x ", channel,
 801                     IBCM_ALT_ADDS_VECT(chan_args).av_dlid);
 802 
 803                 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
 804                     "alt GID %llX:%llX", channel,
 805                     IBCM_ALT_ADDS_VECT(chan_args).av_dgid.gid_prefix,
 806                     IBCM_ALT_ADDS_VECT(chan_args).av_dgid.gid_guid);
 807         }
 808 
 809         len = min(chan_args->oc_priv_data_len, IBT_REQ_PRIV_DATA_SZ);
 810         if ((len > 0) && chan_args->oc_priv_data)
 811                 bcopy(chan_args->oc_priv_data, req_msgp->req_private_data, len);
 812 
 813         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*req_msgp))
 814 
 815         /* return_data is filled up in the state machine code */
 816         if (ret_args != NULL) {
 817                 statep->open_return_data = ret_args;
 818         }
 819 
 820         /* initialize some statep fields here */
 821         statep->mode = IBCM_ACTIVE_MODE;
 822         statep->hcap = hcap;
 823 
 824         statep->cm_handler = chan_args->oc_cm_handler;
 825         statep->state_cm_private = chan_args->oc_cm_clnt_private;
 826 
 827         statep->pkt_life_time =
 828             ibt_ib2usec(chan_args->oc_path->pi_prim_pkt_lt);
 829 
 830         statep->timer_value = ibt_ib2usec(ibt_usec2ib(
 831             2 * ibt_ib2usec(cm_pkt_lt) + remote_cm_resp_time));
 832 
 833         /* Initialize statep->stored_reply_addr */
 834         statep->stored_reply_addr.ibmf_hdl = ibmf_hdl;


 854         statep->open_done = B_FALSE;
 855         statep->state = statep->timer_stored_state = IBCM_STATE_REQ_SENT;
 856         IBCM_REF_CNT_INCR(statep);      /* Decremented before return */
 857         IBCM_REF_CNT_INCR(statep);      /* Decremented after REQ is posted */
 858         statep->send_mad_flags |= IBCM_REQ_POST_BUSY;
 859 
 860         /*
 861          * Skip moving channel to error state during close, for OFUV clients.
 862          * OFUV clients transition the channel to error state by itself.
 863          */
 864         if (flags & IBT_OCHAN_OFUV)
 865                 statep->is_this_ofuv_chan = B_TRUE;
 866 
 867         IBCM_OUT_HDRP(statep->stored_msg)->AttributeID =
 868             h2b16(IBCM_INCOMING_REQ + IBCM_ATTR_BASE_ID);
 869 
 870         IBCM_OUT_HDRP(statep->stored_msg)->TransactionID =
 871             h2b64(ibcm_generate_tranid(IBCM_INCOMING_REQ, statep->local_comid,
 872             0));
 873 
 874         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*statep))
 875 
 876         ibtl_cm_chan_is_opening(channel);
 877 
 878         ibcm_open_enqueue(statep);
 879 
 880         mutex_enter(&statep->state_mutex);
 881 
 882         if (mode == IBT_BLOCKING) {
 883 
 884                 /* wait for REQ/REP/RTU */
 885                 while (statep->open_done != B_TRUE) {
 886                         cv_wait(&statep->block_client_cv, &statep->state_mutex);
 887                 }
 888 
 889                 /*
 890                  * In the case that open_channel() fails because of a
 891                  * REJ or timeout, change retval to IBT_CM_FAILURE
 892                  */
 893                 if (statep->open_return_data->rc_status != IBT_CM_SUCCESS) {
 894                         status = IBT_CM_FAILURE;
 895                         ibtl_cm_chan_open_is_aborted(channel);


 923  *              If Redirect GID is not specified or specified to be on the same
 924  *                  subnet, then
 925  *                      Build CM path from chan_args->oc_cm_redirect_info
 926  *                      Set CM pkt lt to subnet timeout
 927  *              Else (ie., GID specified, but on a different subnet)
 928  *                      Do a path lookup to build CM Path and set CM pkt lt
 929  *
 930  */
 931 static ibt_status_t
 932 ibcm_init_reply_addr(ibcm_hca_info_t *hcap, ibcm_mad_addr_t *reply_addr,
 933     ibt_chan_open_args_t *chan_args, ibt_chan_open_flags_t flags,
 934     ib_time_t *cm_pkt_lt, ib_lid_t prim_slid)
 935 {
 936         ibt_adds_vect_t *cm_adds;
 937         ibt_path_info_t path;
 938         boolean_t       cm_grh;
 939         ibt_status_t    status;
 940 
 941         IBTF_DPRINTF_L5(cmlog, "ibcm_init_reply_addr:");
 942 
 943         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*reply_addr))
 944 
 945         /*
 946          * sending side CM lid/gid/port num are not based on any redirect
 947          * params. These values are set to primary RC path lid/gid/port num.
 948          * In the future, these values can be set based on framework policy
 949          * decisions ensuring reachability.
 950          */
 951         reply_addr->grh_hdr.ig_sender_gid =
 952             IBCM_PRIM_ADDS_VECT(chan_args).av_sgid;
 953         reply_addr->rcvd_addr.ia_local_lid = prim_slid;
 954         reply_addr->port_num = IBCM_PRIM_CEP_PATH(chan_args).cep_hca_port_num;
 955 
 956         if (flags & IBT_OCHAN_PORT_REDIRECTED) {
 957                 IBTF_DPRINTF_L4(cmlog, "ibcm_init_rely_addr: "
 958                     "IBT_OCHAN_PORT_REDIRECTED specified");
 959 
 960                 status = ibt_index2pkey_byguid(hcap->hca_guid,
 961                     chan_args->oc_cm_cep_path->cep_hca_port_num,
 962                     chan_args->oc_cm_cep_path->cep_pkey_ix,
 963                     &reply_addr->rcvd_addr.ia_p_key);
 964 


1089                 cm_adds = &(IBCM_PRIM_ADDS_VECT(chan_args));
1090         }
1091 
1092 
1093         cm_grh = cm_adds->av_send_grh;
1094         reply_addr->grh_exists = cm_grh;
1095 
1096         reply_addr->rcvd_addr.ia_remote_lid =
1097             cm_adds->av_dlid;
1098         reply_addr->grh_hdr.ig_recver_gid =
1099             cm_adds->av_dgid;
1100         reply_addr->grh_hdr.ig_flow_label =
1101             cm_adds->av_flow & IB_GRH_FLOW_LABEL_MASK;
1102         reply_addr->grh_hdr.ig_tclass =
1103             (cm_grh == B_TRUE) ? cm_adds->av_tclass : 0;
1104         reply_addr->grh_hdr.ig_hop_limit =
1105             (cm_grh == B_TRUE) ? cm_adds->av_hop : 1;
1106         reply_addr->rcvd_addr.ia_service_level =
1107             cm_adds->av_srvl;
1108 
1109         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*reply_addr))
1110 
1111         return (IBT_SUCCESS);
1112 }
1113 
1114 
1115 /*
1116  * ibt_prime_close_rc_channel()
1117  *      It allocates resources required for close channel operation, so
1118  *      ibt_close_rc_channel can be called from interrupt routine.
1119  *
1120  * INPUTS:
1121  *      channel                 The address of an ibt_channel_t struct that
1122  *                              specifies the channel to open.
1123  *
1124  * RETURN VALUES:
1125  *      IBT_SUCCESS     on success(or respective failure on error)
1126  *
1127  * Clients are typically expected to call this function in established state
1128  */
1129 ibt_status_t
1130 ibt_prime_close_rc_channel(ibt_channel_hdl_t channel)


1317         ibcm_close_enqueue(statep);
1318         mutex_exit(&statep->state_mutex);
1319 
1320         return (IBT_SUCCESS);
1321 }
1322 
1323 void
1324 ibcm_close_start(ibcm_state_data_t *statep)
1325 {
1326         mutex_enter(&statep->state_mutex);
1327         (void) ibcm_close_rc_channel(statep->channel, statep, IBT_NONBLOCKING);
1328 }
1329 
1330 static
1331 ibt_status_t
1332 ibcm_close_rc_channel(ibt_channel_hdl_t channel, ibcm_state_data_t *statep,
1333     ibt_execution_mode_t mode)
1334 {
1335         ibcm_hca_info_t         *hcap;
1336 
1337         _NOTE(LOCK_RELEASED_AS_SIDE_EFFECT(&statep->state_mutex));
1338         ASSERT(MUTEX_HELD(&statep->state_mutex));
1339 
1340         IBTF_DPRINTF_L3(cmlog, "ibcm_close_rc_channel: chan 0x%p statep %p",
1341             channel, statep);
1342 
1343         hcap = statep->hcap;
1344 
1345         /* HCA must have been in active state. If not, it's a client bug */
1346         if (!IBCM_ACCESS_HCA_OK(hcap)) {
1347                 IBTF_DPRINTF_L2(cmlog, "ibcm_close_rc_channel: chan 0x%p "
1348                     "hcap 0x%p not active", channel, hcap);
1349                 IBCM_REF_CNT_DECR(statep);
1350                 mutex_exit(&statep->state_mutex);
1351                 return (IBT_CHAN_HDL_INVALID);
1352         }
1353 
1354         if (statep->state == IBCM_STATE_TRANSIENT_ESTABLISHED) {
1355                 while (statep->cep_in_rts == IBCM_BLOCK)
1356                         cv_wait(&statep->block_mad_cv, &statep->state_mutex);
1357         }


1636         IBTF_DPRINTF_L3(cmlog, "ibt_recycle_rc (%p, 0x%X, %d, %p, %p)", rc_chan,
1637             control, hca_port_num, func, arg);
1638 
1639         if (IBCM_INVALID_CHANNEL(rc_chan)) {
1640                 IBTF_DPRINTF_L2(cmlog, "ibt_recycle_rc: invalid channel");
1641                 return (IBT_CHAN_HDL_INVALID);
1642         }
1643 
1644         /* check qp state */
1645         retval = ibt_query_qp(rc_chan, &qp_attr);
1646 
1647         if (retval != IBT_SUCCESS)
1648                 return (retval);
1649 
1650         if (qp_attr.qp_info.qp_trans != IBT_RC_SRV)
1651                 return (IBT_CHAN_SRV_TYPE_INVALID);
1652 
1653         if (qp_attr.qp_info.qp_state != IBT_STATE_ERROR)
1654                 return (IBT_CHAN_STATE_INVALID);
1655 
1656         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ibcm_tq_recycle_arg))
1657 
1658         ibcm_tq_recycle_arg = kmem_alloc(sizeof (ibcm_taskq_recycle_arg_t),
1659             KM_SLEEP);
1660 
1661         ibcm_tq_recycle_arg->rc_chan         = rc_chan;
1662         ibcm_tq_recycle_arg->control         = control;
1663         ibcm_tq_recycle_arg->hca_port_num    = hca_port_num;
1664         ibcm_tq_recycle_arg->func            = func;
1665         ibcm_tq_recycle_arg->arg             = arg;
1666 
1667         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ibcm_tq_recycle_arg))
1668 
1669         IBCM_GET_CHAN_PRIVATE(rc_chan, statep);
1670 
1671         /*
1672          * If non-blocking ie., func specified and channel has not yet completed
1673          * the timewait, then schedule the work for later
1674          */
1675         if ((func != NULL) && (statep != NULL)) {
1676                 IBCM_RELEASE_CHAN_PRIVATE(rc_chan);
1677                 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(statep->recycle_arg))
1678                 statep->recycle_arg = ibcm_tq_recycle_arg;
1679                 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(statep->recycle_arg))
1680                 return (IBT_SUCCESS);
1681         }
1682 
1683         /*
1684          * if blocking ie., func specified, and channel has not yet completed
1685          * the timewait, then block until the channel completes the timewait
1686          */
1687         if (statep != NULL)
1688                 IBCM_RELEASE_CHAN_PRIVATE(rc_chan);
1689         IBCM_WAIT_CHAN_PRIVATE(rc_chan);
1690 
1691         if (func) {     /* NON BLOCKING case. Taskq for QP state change */
1692                 (void) taskq_dispatch(ibcm_taskq, ibcm_process_rc_recycle,
1693                     ibcm_tq_recycle_arg, TQ_SLEEP);
1694                 return (IBT_SUCCESS);
1695         } else  /* BLOCKING case */
1696                 return (ibcm_process_rc_recycle_ret(ibcm_tq_recycle_arg));
1697 }
1698 
1699 void


1785 ibcm_process_abort_via_taskq(void *args)
1786 {
1787         ibcm_state_data_t       *statep = (ibcm_state_data_t *)args;
1788 
1789         ibcm_process_abort(statep);
1790         mutex_enter(&statep->state_mutex);
1791         IBCM_REF_CNT_DECR(statep);
1792         mutex_exit(&statep->state_mutex);
1793 }
1794 
1795 /*
1796  * Local UD CM Handler's private data, used during ibt_request_ud_dest() in
1797  * Non-Blocking mode operations.
1798  */
1799 typedef struct ibcm_local_handler_s {
1800         ibt_cm_ud_handler_t     actual_cm_handler;
1801         void                    *actual_cm_private;
1802         ibt_ud_dest_t           *dest_hdl;
1803 } ibcm_local_handler_t;
1804 
1805 _NOTE(READ_ONLY_DATA(ibcm_local_handler_s))
1806 
1807 /*
1808  * Local UD CM Handler, used when ibt_alloc_ud_dest() is issued in
1809  * NON-Blocking mode.
1810  *
1811  * Out here, we update the UD Destination handle with
1812  * the obtained DQPN and QKey (from SIDR REP) and invokes actual client
1813  * handler that was specified by the client.
1814  */
1815 static ibt_cm_status_t
1816 ibcm_local_cm_handler(void *priv, ibt_cm_ud_event_t *event,
1817     ibt_cm_ud_return_args_t *ret_args, void *priv_data, ibt_priv_data_len_t len)
1818 {
1819         ibcm_local_handler_t    *handler_priv = (ibcm_local_handler_t *)priv;
1820 
1821         IBTF_DPRINTF_L4(cmlog, "ibcm_local_cm_handler: event %d",
1822             event->cm_type);
1823 
1824         ASSERT(handler_priv != NULL);
1825 
1826         switch (event->cm_type) {


1956         /* Return failure if the HCA device or Port is not operational */
1957 
1958         if ((retval = ibt_get_port_state_byguid(port.hp_hca_guid, port.hp_port,
1959             NULL, NULL)) != IBT_SUCCESS) {
1960                 /* Device Port is not in good state, don't use it. */
1961                 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: Invalid "
1962                     "port specified or port not active");
1963                 ibcm_dec_hca_acc_cnt(hcap);
1964                 return (retval);
1965         }
1966 
1967         retval = ibt_index2pkey_byguid(port.hp_hca_guid, port.hp_port,
1968             attr->ud_pkey_ix, &ud_pkey);
1969         if (retval != IBT_SUCCESS) {
1970                 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: "
1971                     "Failed to convert index2pkey: %d", retval);
1972                 ibcm_dec_hca_acc_cnt(hcap);
1973                 return (retval);
1974         }
1975 
1976         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(sidr_entry))
1977 
1978         /* Allocate a new request id */
1979         if (ibcm_alloc_reqid(hcap, &sidr_entry.srch_req_id) == IBCM_FAILURE) {
1980                 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: "
1981                     "no req id available");
1982                 ibcm_dec_hca_acc_cnt(hcap);
1983                 return (IBT_INSUFF_KERNEL_RESOURCE);
1984         }
1985 
1986         if ((hcap->hca_port_info[port.hp_port - 1].port_ibmf_hdl == NULL) &&
1987             ((retval = ibcm_hca_reinit_port(hcap, port.hp_port - 1))
1988             != IBT_SUCCESS)) {
1989                 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: "
1990                     "ibmf reg or callback setup failed during re-initialize");
1991                 return (retval);
1992         }
1993 
1994         ibmf_hdl = hcap->hca_port_info[port.hp_port - 1].port_ibmf_hdl;
1995 
1996         /* find the ibmf QP to post the SIDR REQ */
1997         if ((cm_qp_entry = ibcm_find_qp(hcap, port.hp_port, ud_pkey)) ==


1999                 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: IBMF QP allocation"
2000                     " failed");
2001                 ibcm_dec_hca_acc_cnt(hcap);
2002                 return (IBT_INSUFF_RESOURCE);
2003         }
2004 
2005         if ((retval = ibcm_alloc_out_msg(ibmf_hdl, &ibmf_msg, MAD_METHOD_SEND))
2006             != IBT_SUCCESS) {
2007                 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: IBMF MSG allocation"
2008                     " failed");
2009                 ibcm_release_qp(cm_qp_entry);
2010                 ibcm_dec_hca_acc_cnt(hcap);
2011                 return (retval);
2012         }
2013 
2014         sidr_entry.srch_lid = port.hp_base_lid;
2015         sidr_entry.srch_gid = attr->ud_addr->av_sgid;
2016         sidr_entry.srch_grh_exists = attr->ud_addr->av_send_grh;
2017         sidr_entry.srch_mode = IBCM_ACTIVE_MODE;
2018 
2019         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(sidr_entry))
2020 
2021         /* do various allocations needed here */
2022         rw_enter(&hcap->hca_sidr_list_lock, RW_WRITER);
2023 
2024         (void) ibcm_find_sidr_entry(&sidr_entry, hcap, &ud_statep,
2025             IBCM_FLAG_ADD);
2026         rw_exit(&hcap->hca_sidr_list_lock);
2027 
2028         /* Increment hca's resource count */
2029         ibcm_inc_hca_res_cnt(hcap);
2030 
2031         /* After a resource created on hca, no need to hold the acc cnt */
2032         ibcm_dec_hca_acc_cnt(hcap);
2033 
2034         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ud_statep))
2035 
2036         /* Initialize some ud_statep fields */
2037         ud_statep->ud_stored_msg = ibmf_msg;
2038         ud_statep->ud_svc_id = attr->ud_sid;
2039         ud_statep->ud_pkt_life_time =
2040             ibt_ib2usec(attr->ud_pkt_lt);
2041         ud_statep->ud_stored_reply_addr.cm_qp_entry = cm_qp_entry;
2042 
2043         /* set remaining retry cnt */
2044         ud_statep->ud_remaining_retry_cnt = ud_statep->ud_max_cm_retries;
2045 
2046         /*
2047          * Get UD handler and corresponding args which is pass it back
2048          * as first argument for the handler.
2049          */
2050         ud_statep->ud_state_cm_private = attr->ud_cm_private;
2051 
2052         if (mode == IBT_BLOCKING)
2053                 ud_statep->ud_return_data = ret_args;
2054         else
2055                 ud_statep->ud_cm_handler = attr->ud_cm_handler;


2068         ud_statep->ud_stored_reply_addr.grh_hdr.ig_flow_label =
2069             attr->ud_addr->av_flow & IB_GRH_FLOW_LABEL_MASK;
2070 
2071         /* needs to be derived based on the base LID and path bits */
2072         ud_statep->ud_stored_reply_addr.rcvd_addr.ia_local_lid =
2073             port.hp_base_lid;
2074         ud_statep->ud_stored_reply_addr.rcvd_addr.ia_remote_lid =
2075             attr->ud_addr->av_dlid;
2076         ud_statep->ud_stored_reply_addr.rcvd_addr.ia_p_key = ud_pkey;
2077         ud_statep->ud_stored_reply_addr.rcvd_addr.ia_q_key = IB_GSI_QKEY;
2078         ud_statep->ud_stored_reply_addr.rcvd_addr.ia_service_level =
2079             attr->ud_addr->av_srvl;
2080 
2081         /*
2082          * This may be enchanced later, to use a remote qno based on past
2083          * redirect rej mad responses. This would be the place to specify
2084          * appropriate remote qno
2085          */
2086         ud_statep->ud_stored_reply_addr.rcvd_addr.ia_remote_qno = 1;
2087 
2088         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sidr_req_msgp))
2089 
2090         /* Initialize the SIDR REQ message fields */
2091         sidr_req_msgp =
2092             (ibcm_sidr_req_msg_t *)IBCM_OUT_MSGP(ud_statep->ud_stored_msg);
2093 
2094         sidr_req_msgp->sidr_req_request_id = h2b32(ud_statep->ud_req_id);
2095         sidr_req_msgp->sidr_req_service_id = h2b64(attr->ud_sid);
2096         sidr_req_msgp->sidr_req_pkey = h2b16(ud_pkey);
2097         IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->AttributeID =
2098             h2b16(IBCM_INCOMING_SIDR_REQ + IBCM_ATTR_BASE_ID);
2099 
2100         if ((attr->ud_priv_data != NULL) && (attr->ud_priv_data_len > 0)) {
2101                 bcopy(attr->ud_priv_data, sidr_req_msgp->sidr_req_private_data,
2102                     min(attr->ud_priv_data_len, IBT_SIDR_REQ_PRIV_DATA_SZ));
2103         }
2104 
2105         /* Send out the SIDR REQ message */
2106         ud_statep->ud_state = IBCM_STATE_SIDR_REQ_SENT;
2107         ud_statep->ud_timer_stored_state = IBCM_STATE_SIDR_REQ_SENT;
2108         IBCM_UD_REF_CNT_INCR(ud_statep); /* for non-blocking SIDR REQ post */
2109         ud_statep->ud_timer_value = ibt_ib2usec(ibcm_max_sidr_rep_proctime) +
2110             (ud_statep->ud_pkt_life_time * 2);
2111 
2112         IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->TransactionID =
2113             h2b64(ibcm_generate_tranid(IBCM_INCOMING_SIDR_REQ,
2114             ud_statep->ud_req_id, 0));
2115 
2116         IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: timer_value in HZ = %x",
2117             ud_statep->ud_timer_value);
2118 
2119         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ud_statep))
2120         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*sidr_req_msgp))
2121 
2122         ibcm_post_ud_mad(ud_statep, ud_statep->ud_stored_msg,
2123             ibcm_post_sidr_req_complete, ud_statep);
2124 
2125         mutex_enter(&ud_statep->ud_state_mutex);
2126 
2127         /* Wait for SIDR_REP */
2128         if (mode == IBT_BLOCKING) {
2129                 IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: blocking");
2130 
2131                 while (ud_statep->ud_blocking_done != B_TRUE) {
2132                         cv_wait(&ud_statep->ud_block_client_cv,
2133                             &ud_statep->ud_state_mutex);
2134                 }
2135 
2136                 IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: finished blocking");
2137 
2138                 if (ret_args->ud_status == IBT_CM_SREP_QPN_VALID) {
2139                         IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: DQPN = %x, "
2140                             "status = %x, QKey = %x", ret_args->ud_dqpn,
2141                             ret_args->ud_status, ret_args->ud_qkey);


2196             attr->ud_addr);
2197         if (retval != IBT_SUCCESS) {
2198                 IBTF_DPRINTF_L2(cmlog, "ibt_request_ud_dest: "
2199                     "Address Handle Modification failed: %d", retval);
2200                 return (retval);
2201         }
2202 
2203         if (mode == IBT_NONBLOCKING) {
2204                 /*
2205                  * In NON-BLOCKING mode, and we need to update the destination
2206                  * handle with the DQPN and QKey that are obtained from
2207                  * SIDR REP, hook-up our own handler, so that we can catch
2208                  * the event, and we ourselves call the actual client's
2209                  * ud_cm_handler, in our handler.
2210                  */
2211 
2212                 /* Allocate memory for local handler's private data. */
2213                 local_handler_priv =
2214                     kmem_alloc(sizeof (*local_handler_priv), KM_SLEEP);
2215 
2216                 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*local_handler_priv))
2217 
2218                 local_handler_priv->actual_cm_handler = attr->ud_cm_handler;
2219                 local_handler_priv->actual_cm_private = attr->ud_cm_private;
2220                 local_handler_priv->dest_hdl = ud_destp;
2221 
2222                 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*local_handler_priv))
2223 
2224                 attr->ud_cm_handler = ibcm_local_cm_handler;
2225                 attr->ud_cm_private = local_handler_priv;
2226         }
2227 
2228         /* In order to get DQPN and Destination QKey, perform SIDR */
2229         retval = ibcm_ud_get_dqpn(attr, mode, ud_ret_args);
2230         if (retval != IBT_SUCCESS) {
2231                 IBTF_DPRINTF_L2(cmlog, "ibt_request_ud_dest: "
2232                     "Failed to get DQPN: %d", retval);
2233 
2234                 /* Free memory allocated for local handler's private data. */
2235                 if (local_handler_priv != NULL)
2236                         kmem_free(local_handler_priv,
2237                             sizeof (*local_handler_priv));
2238                 return (retval);
2239         }
2240 
2241         /*
2242          * Fill in the dqpn and dqkey as obtained from ud_ret_args,
2243          * values will be valid only on BLOCKING mode.


2328         statep = (ibcm_state_data_t *)cm_session_id;
2329 
2330         if (statep == NULL) {
2331                 IBTF_DPRINTF_L2(cmlog, "ibt_cm_delay: statep NULL");
2332                 return (IBT_INVALID_PARAM);
2333         }
2334 
2335         IBTF_DPRINTF_L4(cmlog, "ibt_cm_delay: statep %p", statep);
2336 
2337         /* Allocate an ibmf msg for mra, if not allocated yet */
2338         if (statep->mra_msg == NULL) {
2339                 if ((status = ibcm_alloc_out_msg(
2340                     statep->stored_reply_addr.ibmf_hdl, &statep->mra_msg,
2341                     MAD_METHOD_SEND)) != IBT_SUCCESS) {
2342                         IBTF_DPRINTF_L2(cmlog, "ibt_cm_delay: chan 0x%p"
2343                             "IBMF MSG allocation failed", statep->channel);
2344                         return (status);
2345                 }
2346         }
2347 
2348         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*mra_msgp))
2349 
2350         mra_msgp = (ibcm_mra_msg_t *)IBCM_OUT_MSGP(statep->mra_msg);
2351         mra_msgp->mra_local_comm_id = h2b32(statep->local_comid);
2352         mra_msgp->mra_remote_comm_id = h2b32(statep->remote_comid);
2353 
2354         /* fill in rest of MRA's fields - Message MRAed and Service Timeout */
2355         if (flags == IBT_CM_DELAY_REQ) {
2356                 msg_typ = IBT_CM_MRA_TYPE_REQ;
2357         } else if (flags == IBT_CM_DELAY_REP) {
2358                 msg_typ = IBT_CM_MRA_TYPE_REP;
2359         } else if (flags == IBT_CM_DELAY_LAP) {
2360                 msg_typ = IBT_CM_MRA_TYPE_LAP;
2361         }
2362 
2363         mra_msgp->mra_message_type_plus = msg_typ << 6;
2364         mra_msgp->mra_service_timeout_plus = ibt_usec2ib(service_time) << 3;
2365 
2366         len = min(len, IBT_MRA_PRIV_DATA_SZ);
2367         if (priv_data && (len > 0))
2368                 bcopy(priv_data, mra_msgp->mra_private_data, len);
2369 
2370         IBCM_OUT_HDRP(statep->mra_msg)->AttributeID =
2371             h2b16(IBCM_INCOMING_MRA + IBCM_ATTR_BASE_ID);
2372 
2373         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*mra_msgp))
2374 
2375         mutex_enter(&statep->state_mutex);
2376 
2377         if ((statep->mode == IBCM_ACTIVE_MODE) &&
2378             (statep->state == IBCM_STATE_REP_RCVD)) {
2379                 statep->state = IBCM_STATE_MRA_REP_SENT;
2380         } else if (statep->mode == IBCM_PASSIVE_MODE) {
2381                 if (statep->state == IBCM_STATE_REQ_RCVD) {
2382                         statep->state = IBCM_STATE_MRA_SENT;
2383                 } else if (statep->ap_state == IBCM_AP_STATE_LAP_RCVD) {
2384                         statep->ap_state = IBCM_AP_STATE_MRA_LAP_RCVD;
2385                 } else {
2386                         IBTF_DPRINTF_L2(cmlog, "ibt_cm_delay: invalid state "
2387                             "/ap_state/mode %x, %x, %x", statep->state,
2388                             statep->ap_state, statep->mode);
2389                         mutex_exit(&statep->state_mutex);
2390                         return (IBT_CHAN_STATE_INVALID);
2391                 }
2392         } else {
2393                 IBTF_DPRINTF_L2(cmlog, "ibt_cm_delay: invalid state "
2394                     "/ap_state/mode %x, %x, %x", statep->state,


2448  *                      in the range.
2449  *
2450  * ibt_register_service() returns:
2451  *      IBT_SUCCESS             - added a service successfully.
2452  *      IBT_INVALID_PARAM       - invalid input parameter.
2453  *      IBT_CM_FAILURE          - failed to add the service.
2454  *      IBT_CM_SERVICE_EXISTS   - service already exists.
2455  *      IBT_INSUFF_KERNEL_RESOURCE - ran out of local service ids (should
2456  *                                   never happen).
2457  */
2458 ibt_status_t
2459 ibt_register_service(ibt_clnt_hdl_t ibt_hdl, ibt_srv_desc_t *srv,
2460     ib_svc_id_t sid, int num_sids, ibt_srv_hdl_t *srv_hdl, ib_svc_id_t *ret_sid)
2461 {
2462         ibcm_svc_info_t         *svcinfop;
2463 
2464         IBTF_DPRINTF_L2(cmlog, "ibt_register_service(%p (%s), %p, 0x%llX, %d)",
2465             ibt_hdl, ibtl_cm_get_clnt_name(ibt_hdl), srv, (longlong_t)sid,
2466             num_sids);
2467 
2468         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*svcinfop))
2469 
2470         *srv_hdl = NULL;
2471 
2472         if (num_sids <= 0) {
2473                 IBTF_DPRINTF_L2(cmlog, "ibt_register_service: "
2474                     "Invalid number of service-ids specified (%d)", num_sids);
2475                 return (IBT_INVALID_PARAM);
2476         }
2477 
2478         if (sid == 0) {
2479                 if (ret_sid == NULL)
2480                         return (IBT_INVALID_PARAM);
2481                 sid = ibcm_alloc_local_sids(num_sids);
2482                 if (sid == 0)
2483                         return (IBT_INSUFF_KERNEL_RESOURCE);
2484 
2485         /* Make sure that the ServiceId specified is not of LOCAL AGN type. */
2486         } else if ((sid & IB_SID_AGN_MASK) == IB_SID_AGN_LOCAL) {
2487                 IBTF_DPRINTF_L2(cmlog, "ibt_register_service: "
2488                     "Invalid non-LOCAL SID specified: 0x%llX",
2489                     (longlong_t)sid);


2499         }
2500 
2501         /*
2502          * 'sid' and 'num_sids' are filled in ibcm_create_svc_entry()
2503          */
2504         svcinfop->svc_flags = srv->sd_flags;
2505         svcinfop->svc_rc_handler = srv->sd_handler;
2506         svcinfop->svc_ud_handler = srv->sd_ud_handler;
2507 
2508         if (ret_sid != NULL)
2509                 *ret_sid = sid;
2510 
2511         *srv_hdl = svcinfop;
2512 
2513         ibtl_cm_change_service_cnt(ibt_hdl, num_sids);
2514 
2515         /* If this message isn't seen, then ibt_register_service failed. */
2516         IBTF_DPRINTF_L2(cmlog, "ibt_register_service: done (%p, %llX)",
2517             svcinfop, sid);
2518 
2519         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*svcinfop))
2520 
2521         return (IBT_SUCCESS);
2522 }
2523 
2524 
2525 static ibt_status_t
2526 ibcm_write_service_record(ibmf_saa_handle_t saa_handle,
2527     sa_service_record_t *srv_recp, ibmf_saa_access_type_t saa_type)
2528 {
2529         int     rval;
2530         int     retry;
2531 
2532         ibcm_sa_access_enter();
2533         for (retry = 0; retry < ibcm_max_sa_retries; retry++) {
2534                 rval = ibmf_saa_update_service_record(
2535                     saa_handle, srv_recp, saa_type, 0);
2536                 if (rval != IBMF_TRANS_TIMEOUT) {
2537                         break;
2538                 }
2539                 IBTF_DPRINTF_L2(cmlog, "ibcm_write_service_record: "
2540                     "ibmf_saa_update_service_record timed out"


2612                                 mutex_exit(&ibcm_svc_info_lock);
2613                                 IBTF_DPRINTF_L3(cmlog, "ibcm_rem_stale_srec: "
2614                                     "This is not Stale, it's an active record");
2615                                 continue;
2616                         }
2617                         mutex_exit(&ibcm_svc_info_lock);
2618 
2619                         IBTF_DPRINTF_L2(cmlog, "ibcm_rem_stale_srec: "
2620                             "Removing Stale Rec: %s, %llX",
2621                             srv_resp->ServiceName, srv_resp->ServiceID);
2622 
2623                         IBCM_DUMP_SERVICE_REC(srv_resp);
2624 
2625                         /*
2626                          * Remove the Service Record Entry from SA.
2627                          *
2628                          * Get ServiceID info from Response Buf, other
2629                          * attributes are already filled-in.
2630                          */
2631 
2632                          _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(srec->ServiceID))
2633 
2634                         srec->ServiceID = srv_resp->ServiceID;
2635 
2636                          _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(srec->ServiceID))
2637 
2638                         (void) ibcm_write_service_record(saa_handle, srec,
2639                             IBMF_SAA_DELETE);
2640                 }
2641 
2642                 /* Deallocate the memory for results_p. */
2643                 kmem_free(results_p, length);
2644         }
2645 }
2646 
2647 
2648 
2649 /*
2650  * ibt_bind_service()
2651  *      Register a service with the IBCM
2652  *
2653  * INPUTS:
2654  *      srv_hdl         The service id handle returned to the client
2655  *                      on an ibt_service_register() call.
2656  *
2657  *      gid             The GID to which to bind the service.


2680  */
2681 ibt_status_t
2682 ibt_bind_service(ibt_srv_hdl_t srv_hdl, ib_gid_t gid, ibt_srv_bind_t *srv_bind,
2683     void *cm_private, ibt_sbind_hdl_t *sb_hdl_p)
2684 {
2685         ibt_status_t            status;
2686         ibtl_cm_hca_port_t      port;
2687         ibcm_svc_bind_t         *sbindp, *sbp;
2688         ibcm_hca_info_t         *hcap;
2689         ib_svc_id_t             sid, start_sid, end_sid;
2690         ibmf_saa_handle_t       saa_handle;
2691         sa_service_record_t     srv_rec;
2692         uint16_t                pkey_ix;
2693 
2694         if (sb_hdl_p != NULL)
2695                 *sb_hdl_p = NULL;       /* return value for error cases */
2696 
2697         IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: srv_hdl %p, gid (%llX:%llX)",
2698             srv_hdl, (longlong_t)gid.gid_prefix, (longlong_t)gid.gid_guid);
2699 
2700         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sbindp))
2701 
2702         /* Call ibtl_cm_get_hca_port to get the port number and the HCA GUID. */
2703         if ((status = ibtl_cm_get_hca_port(gid, 0, &port)) != IBT_SUCCESS) {
2704                 IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: "
2705                     "ibtl_cm_get_hca_port failed: %d", status);
2706                 return (status);
2707         }
2708         IBTF_DPRINTF_L4(cmlog, "ibt_bind_service: Port:%d HCA GUID:%llX",
2709             port.hp_port, port.hp_hca_guid);
2710 
2711         hcap = ibcm_find_hca_entry(port.hp_hca_guid);
2712         if (hcap == NULL) {
2713                 IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: NO HCA found");
2714                 return (IBT_HCA_BUSY_DETACHING);
2715         }
2716         IBTF_DPRINTF_L4(cmlog, "ibt_bind_service: hcap = %p", hcap);
2717 
2718         if (srv_bind != NULL) {
2719                 saa_handle = ibcm_get_saa_handle(hcap, port.hp_port);
2720                 if (saa_handle == NULL) {
2721                         IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: "


2875                                         }
2876                                         mutex_exit(&ibcm_svc_info_lock);
2877                                         ibcm_dec_hca_acc_cnt(hcap);
2878 
2879                                         kmem_free(sbindp, sizeof (*sbindp));
2880                                 }
2881                                 return (status);
2882                         }
2883                 }
2884         }
2885         ibcm_inc_hca_svc_cnt(hcap);
2886         ibcm_dec_hca_acc_cnt(hcap);
2887 
2888         /* If this message isn't seen then ibt_bind_service failed */
2889         IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: DONE (%p, %llX:%llX)",
2890             srv_hdl, gid.gid_prefix, gid.gid_guid);
2891 
2892         if (sb_hdl_p != NULL)
2893                 *sb_hdl_p = sbindp;
2894 
2895         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*sbindp))
2896 
2897         return (IBT_SUCCESS);
2898 }
2899 
2900 ibt_status_t
2901 ibt_unbind_service(ibt_srv_hdl_t srv_hdl, ibt_sbind_hdl_t sbindp)
2902 {
2903         ib_svc_id_t     sid, end_sid;
2904         ibt_status_t    rval;
2905         ibcm_hca_info_t *hcap;
2906         ibcm_svc_bind_t *sbp, **sbpp;
2907 
2908         IBTF_DPRINTF_L2(cmlog, "ibt_unbind_service(%p, %p)",
2909             srv_hdl, sbindp);
2910 
2911         hcap = ibcm_find_hca_entry(sbindp->sbind_hcaguid);
2912 
2913         /* If there is a service on hca, respective hcap cannot go away */
2914         ASSERT(hcap != NULL);
2915 
2916         mutex_enter(&ibcm_svc_info_lock);


3049 {
3050         ibcm_svc_info_t         *svcp;
3051         ibcm_svc_lookup_t       svc;
3052 
3053         IBTF_DPRINTF_L2(cmlog, "ibt_deregister_service(%p (%s), %p)",
3054             ibt_hdl, ibtl_cm_get_clnt_name(ibt_hdl), srv_hdl);
3055 
3056         mutex_enter(&ibcm_svc_info_lock);
3057 
3058         if (srv_hdl->svc_bind_list != NULL) {
3059                 IBTF_DPRINTF_L2(cmlog, "ibt_deregister_service:"
3060                     " srv_hdl %p still has bindings", srv_hdl);
3061                 mutex_exit(&ibcm_svc_info_lock);
3062                 return (IBT_CM_SERVICE_BUSY);
3063         }
3064         svc.sid = srv_hdl->svc_id;
3065         svc.num_sids = 1;
3066         IBTF_DPRINTF_L3(cmlog, "ibt_deregister_service: SID 0x%llX, numsids %d",
3067             srv_hdl->svc_id, srv_hdl->svc_num_sids);
3068 
3069 #ifdef __lock_lint
3070         ibcm_svc_compare(NULL, NULL);
3071 #endif
3072         svcp = avl_find(&ibcm_svc_avl_tree, &svc, NULL);
3073         if (svcp != srv_hdl) {
3074                 mutex_exit(&ibcm_svc_info_lock);
3075                 IBTF_DPRINTF_L2(cmlog, "ibt_deregister_service(): "
3076                     "srv_hdl %p not found", srv_hdl);
3077                 return (IBT_INVALID_PARAM);
3078         }
3079         avl_remove(&ibcm_svc_avl_tree, svcp);
3080 
3081         /* wait for active REQ/SREQ handling to be done */
3082         svcp->svc_to_delete = 1;
3083         while (svcp->svc_ref_cnt != 0)
3084                 cv_wait(&ibcm_svc_info_cv, &ibcm_svc_info_lock);
3085 
3086         mutex_exit(&ibcm_svc_info_lock);
3087 
3088         if ((srv_hdl->svc_id & IB_SID_AGN_MASK) == IB_SID_AGN_LOCAL)
3089                 ibcm_free_local_sids(srv_hdl->svc_id, srv_hdl->svc_num_sids);
3090 
3091         ibtl_cm_change_service_cnt(ibt_hdl, -srv_hdl->svc_num_sids);


3994         /* wait until client's CM handler returns DEFER status back to CM */
3995 
3996         while (statep->clnt_proceed == IBCM_BLOCK) {
3997                 IBTF_DPRINTF_L5(cmlog, "ibt_cm_proceed : chan 0x%p blocked for "
3998                     "return of client's cm handler", statep->channel);
3999                 cv_wait(&statep->block_client_cv, &statep->state_mutex);
4000         }
4001 
4002         if (statep->clnt_proceed == IBCM_FAIL) {
4003                 mutex_exit(&statep->state_mutex);
4004                 IBTF_DPRINTF_L2(cmlog, "ibt_cm_proceed : chan 0x%p Failed as "
4005                     "client returned non-DEFER status from cm handler",
4006                     statep->channel);
4007                 return (IBT_CHAN_STATE_INVALID);
4008         }
4009 
4010         ASSERT(statep->clnt_proceed == IBCM_UNBLOCK);
4011         statep->clnt_proceed = IBCM_FAIL;
4012         mutex_exit(&statep->state_mutex);
4013 
4014         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*proceed_targs))
4015 
4016         /* the state machine processing is done in a separate thread */
4017 
4018         /* proceed_targs is freed in ibcm_proceed_via_taskq */
4019         proceed_targs = kmem_alloc(sizeof (ibcm_proceed_targs_t),
4020             KM_SLEEP);
4021 
4022         proceed_targs->event  = event;
4023         proceed_targs->status = status;
4024         proceed_targs->priv_data_len = priv_data_len;
4025 
4026         bcopy(priv_data, proceed_targs->priv_data, priv_data_len);
4027 
4028         proceed_targs->tst.rc.statep = statep;
4029         bcopy(cm_event_data, &proceed_targs->tst.rc.rc_cm_event_data,
4030             sizeof (ibt_cm_proceed_reply_t));
4031 
4032         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*proceed_targs))
4033 
4034         (void) taskq_dispatch(ibcm_taskq, ibcm_proceed_via_taskq,
4035             proceed_targs, TQ_SLEEP);
4036 
4037         return (IBT_SUCCESS);
4038 }
4039 
4040 /*
4041  * Function:
4042  *      ibcm_proceed_via_taskq
4043  *
4044  * Called from taskq, dispatched by ibt_cm_proceed
4045  * Completes the cm state processing for ibt_cm_proceed
4046  */
4047 void
4048 ibcm_proceed_via_taskq(void *targs)
4049 {
4050         ibcm_proceed_targs_t    *proceed_targs = (ibcm_proceed_targs_t *)targs;
4051         ibcm_state_data_t *statep = proceed_targs->tst.rc.statep;
4052         ibt_cm_reason_t reject_reason;
4053         uint8_t arej_len;


4159         /* wait until client's CM handler returns DEFER status back to CM */
4160 
4161         while (ud_statep->ud_clnt_proceed == IBCM_BLOCK) {
4162                 IBTF_DPRINTF_L5(cmlog, "ibt_cm_ud_proceed : Blocked for return"
4163                     " of client's ud cm handler");
4164                 cv_wait(&ud_statep->ud_block_client_cv,
4165                     &ud_statep->ud_state_mutex);
4166         }
4167 
4168         if (ud_statep->ud_clnt_proceed == IBCM_FAIL) {
4169                 mutex_exit(&ud_statep->ud_state_mutex);
4170                 IBTF_DPRINTF_L2(cmlog, "ibt_cm_ud_proceed : Failed as client "
4171                     "returned non-DEFER status from cm handler");
4172                 return (IBT_INVALID_PARAM);
4173         }
4174 
4175         ASSERT(ud_statep->ud_clnt_proceed == IBCM_UNBLOCK);
4176         ud_statep->ud_clnt_proceed = IBCM_FAIL;
4177         mutex_exit(&ud_statep->ud_state_mutex);
4178 
4179         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*proceed_targs))
4180 
4181         /* the state machine processing is done in a separate thread */
4182 
4183         /* proceed_targs is freed in ibcm_proceed_via_taskq */
4184         proceed_targs = kmem_zalloc(sizeof (ibcm_proceed_targs_t),
4185             KM_SLEEP);
4186 
4187         proceed_targs->status = status;
4188         proceed_targs->priv_data_len = priv_data_len;
4189 
4190         bcopy(priv_data, proceed_targs->priv_data, priv_data_len);
4191 
4192         if (status == IBT_CM_ACCEPT) {
4193                 proceed_targs->tst.ud.ud_qkey =
4194                     qp_attr.qp_info.qp_transport.ud.ud_qkey;
4195                 proceed_targs->tst.ud.ud_qpn = qp_attr.qp_qpn;
4196         }
4197 
4198         proceed_targs->tst.ud.ud_statep = ud_statep;
4199 
4200         /* copy redirect info based on status */
4201         if (status == IBT_CM_REDIRECT)
4202                 bcopy(redirect_infop, &proceed_targs->tst.ud.ud_redirect_info,
4203                     sizeof (ibt_redirect_info_t));
4204 
4205         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*proceed_targs))
4206 
4207         (void) taskq_dispatch(ibcm_taskq, ibcm_ud_proceed_via_taskq,
4208             proceed_targs, TQ_SLEEP);
4209 
4210         return (IBT_SUCCESS);
4211 }
4212 
4213 /*
4214  * Function:
4215  *      ibcm_ud_proceed_via_taskq
4216  *
4217  * Called from taskq, dispatched by ibt_cm_ud_proceed
4218  * Completes the cm state processing for ibt_cm_ud_proceed
4219  */
4220 void
4221 ibcm_ud_proceed_via_taskq(void *targs)
4222 {
4223         ibcm_proceed_targs_t    *proceed_targs = (ibcm_proceed_targs_t *)targs;
4224         ibcm_ud_state_data_t    *ud_statep = proceed_targs->tst.ud.ud_statep;
4225         ibcm_ud_clnt_reply_info_t ud_clnt_info;
4226         ibt_sidr_status_t       sidr_status;


4427                 ibcm_lapr_exit();
4428                 return (IBT_CHAN_STATE_INVALID);
4429         } else {
4430                 /* Set to LAP Sent state */
4431                 statep->ap_state = IBCM_AP_STATE_LAP_SENT;
4432                 statep->ap_done = B_FALSE;
4433                 statep->remaining_retry_cnt = statep->max_cm_retries;
4434                 statep->timer_stored_state = statep->state;
4435                 statep->timer_stored_ap_state = statep->ap_state;
4436                 IBCM_REF_CNT_INCR(statep); /* for ibcm_post_lap_complete */
4437         }
4438 
4439         mutex_exit(&statep->state_mutex);
4440 
4441         /* No more failure returns below */
4442 
4443         /* Allocate MAD for LAP */
4444         IBTF_DPRINTF_L5(cmlog, "ibt_set_alt_path:"
4445             " statep's mad addr = 0x%p", IBCM_OUT_HDRP(statep->lapr_msg));
4446 
4447         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lap_msgp))
4448 
4449         lap_msgp = (ibcm_lap_msg_t *)IBCM_OUT_MSGP(statep->lapr_msg);
4450 
4451         lap_msgp->lap_alt_l_port_lid = h2b16(alternate_slid);
4452         lap_msgp->lap_alt_r_port_lid =
4453             h2b16(alt_path->ap_alt_cep_path.cep_adds_vect.av_dlid);
4454 
4455         /* Fill in remote port gid */
4456         lap_msgp->lap_alt_r_port_gid.gid_prefix =
4457             h2b64(alt_path->ap_alt_cep_path.cep_adds_vect.av_dgid.gid_prefix);
4458         lap_msgp->lap_alt_r_port_gid.gid_guid =
4459             h2b64(alt_path->ap_alt_cep_path.cep_adds_vect.av_dgid.gid_guid);
4460 
4461         /* Fill in local port gid */
4462         lap_msgp->lap_alt_l_port_gid.gid_prefix =
4463             h2b64(alt_path->ap_alt_cep_path.cep_adds_vect.av_sgid.gid_prefix);
4464         lap_msgp->lap_alt_l_port_gid.gid_guid =
4465             h2b64(alt_path->ap_alt_cep_path.cep_adds_vect.av_sgid.gid_guid);
4466 
4467         alt_grh = alt_path->ap_alt_cep_path.cep_adds_vect.av_send_grh;
4468 


4480             alt_path->ap_alt_cep_path.cep_adds_vect.av_srvl << 4 |
4481             ((alt_grh == B_FALSE) ? 0x8 : 0);
4482 
4483         lap_msgp->lap_alt_local_acktime_plus = ibt_usec2ib(
4484             (2 * statep->rc_alt_pkt_lt) +
4485             ibt_ib2usec(hcap->hca_ack_delay)) << 3;
4486 
4487         lap_msgp->lap_local_comm_id = h2b32(statep->local_comid);
4488         lap_msgp->lap_remote_comm_id = h2b32(statep->remote_comid);
4489 
4490         lap_msgp->lap_remote_qpn_eecn_plus =
4491             h2b32((statep->remote_qpn << 8) |
4492             ibt_usec2ib(ibcm_remote_response_time) << 3);
4493 
4494         len = min(priv_data_len, IBT_LAP_PRIV_DATA_SZ);
4495         if ((len > 0) && priv_data) {
4496                 bcopy(priv_data, lap_msgp->lap_private_data, len);
4497         }
4498 
4499         /* only rc_alt_pkt_lt and ap_return_data fields are initialized */
4500         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
4501 
4502         statep->rc_alt_pkt_lt = ibt_ib2usec(alt_path->ap_alt_pkt_lt);
4503 
4504         /* return_data is filled up in the state machine code */
4505         statep->ap_return_data = ret_args;
4506 
4507         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*statep))
4508 
4509         IBCM_OUT_HDRP(statep->lapr_msg)->AttributeID =
4510             h2b16(IBCM_INCOMING_LAP + IBCM_ATTR_BASE_ID);
4511 
4512         IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID =
4513             h2b64(ibcm_generate_tranid(IBCM_INCOMING_LAP, statep->local_comid,
4514             0));
4515         IBTF_DPRINTF_L3(cmlog, "ibt_set_alt_path: statep %p, tid %llx",
4516             statep, IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID);
4517 
4518         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*lap_msgp))
4519 
4520         /* Send LAP */
4521         ibcm_post_rc_mad(statep, statep->lapr_msg, ibcm_post_lap_complete,
4522             statep);
4523 
4524         mutex_enter(&statep->state_mutex);
4525 
4526         if (mode == IBT_BLOCKING) {
4527                 IBTF_DPRINTF_L4(cmlog, "ibt_set_alt_path: blocking");
4528 
4529                 /* wait for APR */
4530                 while (statep->ap_done != B_TRUE) {
4531                         cv_wait(&statep->block_client_cv,
4532                             &statep->state_mutex);
4533                 }
4534 
4535                 IBTF_DPRINTF_L4(cmlog, "ibt_set_alt_path: done blocking");
4536 
4537                 /*
4538                  * In the case that ibt_set_alt_path fails,
4539                  * change retval to IBT_CM_FAILURE


4650             cm_reply_addr->grh_hdr.ig_flow_label,
4651             cm_reply_addr->grh_hdr.ig_tclass,
4652             cm_reply_addr->grh_hdr.ig_hop_limit);
4653 }
4654 
4655 #endif
4656 
4657 /* For MCG List search */
4658 typedef struct ibcm_mcg_list_s {
4659         struct ibcm_mcg_list_s  *ml_next;
4660         ib_gid_t                ml_sgid;
4661         ib_gid_t                ml_mgid;
4662         ib_pkey_t               ml_pkey;
4663         ib_qkey_t               ml_qkey;
4664         uint_t                  ml_refcnt;
4665         uint8_t                 ml_jstate;
4666 } ibcm_mcg_list_t;
4667 
4668 ibcm_mcg_list_t *ibcm_mcglist = NULL;
4669 
4670 _NOTE(MUTEX_PROTECTS_DATA(ibcm_mcglist_lock, ibcm_mcg_list_s))
4671 _NOTE(MUTEX_PROTECTS_DATA(ibcm_mcglist_lock, ibcm_mcglist))
4672 
4673 typedef struct ibcm_join_mcg_tqarg_s {
4674         ib_gid_t                rgid;
4675         ibt_mcg_attr_t          mcg_attr;
4676         ibt_mcg_info_t          *mcg_infop;
4677         ibt_mcg_handler_t       func;
4678         void                    *arg;
4679 } ibcm_join_mcg_tqarg_t;
4680 
4681 _NOTE(READ_ONLY_DATA(ibcm_join_mcg_tqarg_s))
4682 
4683 void
4684 ibcm_add_incr_mcg_entry(sa_mcmember_record_t *mcg_req,
4685     sa_mcmember_record_t *mcg_resp)
4686 {
4687         ibcm_mcg_list_t *new = NULL;
4688         ibcm_mcg_list_t *head = NULL;
4689 
4690         IBTF_DPRINTF_L3(cmlog, "ibcm_add_incr_mcg_entry: MGID %llX:%llX"
4691             "\n SGID %llX:%llX, JState %X)", mcg_req->MGID.gid_prefix,
4692             mcg_req->MGID.gid_guid, mcg_req->PortGID.gid_prefix,
4693             mcg_req->PortGID.gid_guid, mcg_req->JoinState);
4694 
4695         mutex_enter(&ibcm_mcglist_lock);
4696         head = ibcm_mcglist;
4697 
4698         while (head != NULL) {
4699                 if ((head->ml_mgid.gid_guid == mcg_resp->MGID.gid_guid) &&
4700                     (head->ml_mgid.gid_prefix == mcg_resp->MGID.gid_prefix) &&
4701                     (head->ml_sgid.gid_guid == mcg_resp->PortGID.gid_guid)) {
4702                         /* Increment the count */


4859                 IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: Request GID is required");
4860                 return (IBT_INVALID_PARAM);
4861         }
4862 
4863         if ((mcg_attr->mc_pkey == IB_PKEY_INVALID_LIMITED) ||
4864             (mcg_attr->mc_pkey == IB_PKEY_INVALID_FULL)) {
4865                 IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: Invalid P_Key specified");
4866                 return (IBT_INVALID_PARAM);
4867         }
4868 
4869         if (mcg_attr->mc_join_state == 0) {
4870                 IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: JoinState not specified");
4871                 return (IBT_INVALID_PARAM);
4872         }
4873 
4874         if (mcg_info_p == NULL) {
4875                 IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: mcg_info_p is NULL");
4876                 return (IBT_INVALID_PARAM);
4877         }
4878 
4879         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*mcg_tq))
4880 
4881         mcg_tq = kmem_alloc(sizeof (ibcm_join_mcg_tqarg_t), flag);
4882         if (mcg_tq == NULL) {
4883                 IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: "
4884                     "Unable to allocate memory for local usage.");
4885                 return (IBT_INSUFF_KERNEL_RESOURCE);
4886         }
4887 
4888         mcg_tq->rgid = rgid;
4889         bcopy(mcg_attr, &mcg_tq->mcg_attr, sizeof (ibt_mcg_attr_t));
4890         mcg_tq->mcg_infop = mcg_info_p;
4891         mcg_tq->func = func;
4892         mcg_tq->arg = arg;
4893 
4894         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*mcg_tq))
4895 
4896         if (func != NULL) {     /* Non-Blocking */
4897                 IBTF_DPRINTF_L3(cmlog, "ibt_join_mcg: Non-Blocking Call");
4898                 if (taskq_dispatch(ibcm_taskq, ibcm_process_async_join_mcg,
4899                     mcg_tq, TQ_NOSLEEP) == 0) {
4900                         IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: Failed to "
4901                             "Dispatch the TaskQ");
4902                         kmem_free(mcg_tq, sizeof (ibcm_join_mcg_tqarg_t));
4903                         return (IBT_INSUFF_KERNEL_RESOURCE);
4904                 } else
4905                         return (IBT_SUCCESS);
4906         } else {                /* Blocking */
4907                 return (ibcm_process_join_mcg(mcg_tq));
4908         }
4909 }
4910 
4911 static void
4912 ibcm_process_async_join_mcg(void *tq_arg)
4913 {
4914         (void) ibcm_process_join_mcg(tq_arg);
4915 }


5812                             SA_NODEINFO_COMPMASK_NODELID, &res_p, &len);
5813                         if (retval == IBT_NODE_RECORDS_NOT_FOUND) {
5814                                 IBTF_DPRINTF_L2(cmlog, "ibt_gid_to_node_info: "
5815                                     "failed (%d) to get Node records", retval);
5816                                 continue;
5817                         } else if (retval != IBT_SUCCESS) {
5818                                 IBTF_DPRINTF_L2(cmlog, "ibt_gid_to_node_info: "
5819                                     "failed (%d) to get Node records", retval);
5820                                 ibcm_dec_hca_acc_cnt(hcap);
5821                                 goto gid_to_ni_exit;
5822                         }
5823 
5824                         num_rec = len/sizeof (sa_node_record_t);
5825                         nr_resp = (sa_node_record_t *)(uchar_t *)res_p;
5826 
5827                         /* Validate the returned number of records. */
5828                         if ((nr_resp != NULL) && (num_rec > 0)) {
5829 
5830                                 IBCM_DUMP_NODE_REC(nr_resp);
5831 
5832                                 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(
5833                                     *node_info_p))
5834 
5835                                 node_info_p->n_sys_img_guid =
5836                                     nr_resp->NodeInfo.SystemImageGUID;
5837                                 node_info_p->n_node_guid =
5838                                     nr_resp->NodeInfo.NodeGUID;
5839                                 node_info_p->n_port_guid =
5840                                     nr_resp->NodeInfo.PortGUID;
5841                                 node_info_p->n_dev_id =
5842                                     nr_resp->NodeInfo.DeviceID;
5843                                 node_info_p->n_revision =
5844                                     nr_resp->NodeInfo.Revision;
5845                                 node_info_p->n_vendor_id =
5846                                     nr_resp->NodeInfo.VendorID;
5847                                 node_info_p->n_num_ports =
5848                                     nr_resp->NodeInfo.NumPorts;
5849                                 node_info_p->n_port_num =
5850                                     nr_resp->NodeInfo.LocalPortNum;
5851                                 node_info_p->n_node_type =
5852                                     nr_resp->NodeInfo.NodeType;
5853                                 (void) strncpy(node_info_p->n_description,
5854                                     (char *)&nr_resp->NodeDescription, 64);
5855 
5856                                 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(
5857                                     *node_info_p))
5858 
5859                                 /*
5860                                  * Deallocate the memory allocated by SA for
5861                                  * 'nr_resp'.
5862                                  */
5863                                 ibcm_dec_hca_acc_cnt(hcap);
5864                                 kmem_free(nr_resp, len);
5865                                 retval = IBT_SUCCESS;
5866 
5867                                 goto gid_to_ni_exit;
5868                         } else {
5869                                 retval = IBT_NODE_RECORDS_NOT_FOUND;
5870                                 IBTF_DPRINTF_L3(cmlog, "ibt_gid_to_node_info: "
5871                                     "Node Records NOT found - PortGUID %016llX",
5872                                     gid.gid_guid);
5873                         }
5874                 }
5875                 ibcm_dec_hca_acc_cnt(hcap);
5876 
5877                 if (local_node == B_TRUE)
5878                         break;


6010                             SA_NODEINFO_COMPMASK_NODELID, &res_p, &len);
6011                         if (retval == IBT_NODE_RECORDS_NOT_FOUND) {
6012                                 IBTF_DPRINTF_L2(cmlog, "ibt_lid_to_node_info: "
6013                                     "failed (%d) to get Node records", retval);
6014                                 continue;
6015                         } else if (retval != IBT_SUCCESS) {
6016                                 IBTF_DPRINTF_L2(cmlog, "ibt_lid_to_node_info: "
6017                                     "failed (%d) to get Node records", retval);
6018                                 ibcm_dec_hca_acc_cnt(hcap);
6019                                 goto lid_to_ni_exit;
6020                         }
6021 
6022                         num_rec = len/sizeof (sa_node_record_t);
6023                         nr_resp = (sa_node_record_t *)(uchar_t *)res_p;
6024 
6025                         /* Validate the returned number of records. */
6026                         if ((nr_resp != NULL) && (num_rec > 0)) {
6027 
6028                                 IBCM_DUMP_NODE_REC(nr_resp);
6029 
6030                                 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(
6031                                     *node_info_p))
6032 
6033                                 node_info_p->n_sys_img_guid =
6034                                     nr_resp->NodeInfo.SystemImageGUID;
6035                                 node_info_p->n_node_guid =
6036                                     nr_resp->NodeInfo.NodeGUID;
6037                                 node_info_p->n_port_guid =
6038                                     nr_resp->NodeInfo.PortGUID;
6039                                 node_info_p->n_dev_id =
6040                                     nr_resp->NodeInfo.DeviceID;
6041                                 node_info_p->n_revision =
6042                                     nr_resp->NodeInfo.Revision;
6043                                 node_info_p->n_vendor_id =
6044                                     nr_resp->NodeInfo.VendorID;
6045                                 node_info_p->n_num_ports =
6046                                     nr_resp->NodeInfo.NumPorts;
6047                                 node_info_p->n_port_num =
6048                                     nr_resp->NodeInfo.LocalPortNum;
6049                                 node_info_p->n_node_type =
6050                                     nr_resp->NodeInfo.NodeType;
6051                                 (void) strncpy(node_info_p->n_description,
6052                                     (char *)&nr_resp->NodeDescription, 64);
6053 
6054                                 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(
6055                                     *node_info_p))
6056 
6057                                 /*
6058                                  * Deallocate the memory allocated by SA for
6059                                  * 'nr_resp'.
6060                                  */
6061                                 ibcm_dec_hca_acc_cnt(hcap);
6062                                 kmem_free(nr_resp, len);
6063                                 retval = IBT_SUCCESS;
6064 
6065                                 goto lid_to_ni_exit;
6066                         } else {
6067                                 retval = IBT_NODE_RECORDS_NOT_FOUND;
6068                                 IBTF_DPRINTF_L3(cmlog, "ibt_lid_to_node_info: "
6069                                     "Node Records NOT found - LID 0x%lX",
6070                                     lid);
6071                         }
6072                 }
6073                 ibcm_dec_hca_acc_cnt(hcap);
6074         }
6075 
6076 lid_to_ni_exit:


6555                 *src_info_p = s_ip;
6556                 *entries_p = count;
6557 
6558                 j = 0;
6559                 for (i = 0, ipp = ibds.ibcm_arp_ip; i < ibds.ibcm_arp_ibd_cnt;
6560                     i++, ipp++) {
6561                         if (ipp->ip_inet_family == AF_UNSPEC)
6562                                 continue;
6563                         if ((ipp->ip_port_gid.gid_prefix ==
6564                             sattr->sip_gid.gid_prefix) &&
6565                             (ipp->ip_port_gid.gid_guid ==
6566                             sattr->sip_gid.gid_guid)) {
6567                                 if ((sattr->sip_pkey) &&
6568                                     (ipp->ip_pkey != sattr->sip_pkey))
6569                                         continue;
6570 
6571                                 if ((sattr->sip_zoneid != ALL_ZONES) &&
6572                                     (sattr->sip_zoneid != ipp->ip_zoneid))
6573                                         continue;
6574 
6575                                 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*s_ip))
6576                                 s_ip[j].ip_addr.family = ipp->ip_inet_family;
6577                                 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*s_ip))
6578                                 if (s_ip[j].ip_addr.family == AF_INET) {
6579                                         bcopy(&ipp->ip_cm_sin.sin_addr,
6580                                             &s_ip[j].ip_addr.un.ip4addr,
6581                                             sizeof (in_addr_t));
6582                                 } else if (s_ip[j].ip_addr.family == AF_INET6) {
6583                                         bcopy(&ipp->ip_cm_sin6.sin6_addr,
6584                                             &s_ip[j].ip_addr.un.ip6addr,
6585                                             sizeof (in6_addr_t));
6586                                         /* TBD: scope_id */
6587                                 }
6588                                 IBCM_PRINT_IP("ibt_get_src_ip",
6589                                     &s_ip[j].ip_addr);
6590                                 j++;
6591                         }
6592                 }
6593         } else {
6594                 retval = IBT_SRC_IP_NOT_FOUND;
6595         }
6596 
6597 get_src_ip_end:


6667         }
6668 
6669         ibcm_free_ip_sid(ip_sid);
6670 
6671         return (IBT_SUCCESS);
6672 }
6673 
6674 
6675 uint8_t
6676 ibt_get_ip_protocol_num(ib_svc_id_t sid)
6677 {
6678         return ((sid & IB_SID_IPADDR_IPNUM_MASK) >> 16);
6679 }
6680 
6681 in_port_t
6682 ibt_get_ip_dst_port(ib_svc_id_t sid)
6683 {
6684         return (sid & IB_SID_IPADDR_PORTNUM_MASK);
6685 }
6686 
6687 _NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibt_ip_cm_info_t))
6688 _NOTE(SCHEME_PROTECTS_DATA("Unshared data", ibcm_ip_pvtdata_t))
6689 
6690 ibt_status_t
6691 ibt_format_ip_private_data(ibt_ip_cm_info_t *ip_cm_info,
6692     ibt_priv_data_len_t priv_data_len, void *priv_data_p)
6693 {
6694         ibcm_ip_pvtdata_t       ip_data;
6695 
6696         IBTF_DPRINTF_L4(cmlog, "ibt_format_ip_private_data(%p, %d, %p)",
6697             ip_cm_info, priv_data_len, priv_data_p);
6698 
6699         if ((ip_cm_info == NULL) || (priv_data_p == NULL) ||
6700             (priv_data_len < IBT_IP_HDR_PRIV_DATA_SZ)) {
6701                 IBTF_DPRINTF_L2(cmlog, "ibt_format_ip_private_data: ERROR "
6702                     "Invalid Inputs.");
6703                 return (IBT_INVALID_PARAM);
6704         }
6705 
6706         bzero(&ip_data, sizeof (ibcm_ip_pvtdata_t));
6707         ip_data.ip_srcport = ip_cm_info->src_port; /* Source Port */
6708 
6709         IBCM_PRINT_IP("format_ip_pvt: src", &ip_cm_info->src_addr);


6759                     AF_INET;
6760                 ip_cm_infop->src_addr.un.ip4addr = ip_data.ip_srcv4;
6761                 ip_cm_infop->dst_addr.un.ip4addr = ip_data.ip_dstv4;
6762         } else if (ip_data.ip_ipv == IBT_CM_IP_IPV_V6) {
6763                 /* Copy IPv6 Addr */
6764                 ip_cm_infop->src_addr.family = ip_cm_infop->dst_addr.family =
6765                     AF_INET6;
6766                 bcopy(&ip_data.ip_srcv6, &ip_cm_infop->src_addr.un.ip6addr,
6767                     sizeof (in6_addr_t));
6768                 bcopy(&ip_data.ip_dstv6, &ip_cm_infop->dst_addr.un.ip6addr,
6769                     sizeof (in6_addr_t));
6770         } else {
6771                 IBTF_DPRINTF_L2(cmlog, "ibt_get_ip_data: ERROR: IP Addr needs"
6772                     " to be either AF_INET or AF_INET6 family.");
6773                 return (IBT_INVALID_PARAM);
6774         }
6775         IBCM_PRINT_IP("ibt_get_ip_data: src", &ip_cm_infop->src_addr);
6776         IBCM_PRINT_IP("ibt_get_ip_data: dst", &ip_cm_infop->dst_addr);
6777 
6778         return (IBT_SUCCESS);
6779 }
6780 
6781 
6782 /* Routines for warlock */
6783 
6784 /* ARGSUSED */
6785 static void
6786 ibcm_dummy_mcg_handler(void *arg, ibt_status_t retval, ibt_mcg_info_t *minfo)
6787 {
6788         ibcm_join_mcg_tqarg_t   dummy_mcg;
6789 
6790         dummy_mcg.func = ibcm_dummy_mcg_handler;
6791 
6792         IBTF_DPRINTF_L5(cmlog, "ibcm_dummy_mcg_handler: "
6793             "dummy_mcg.func %p", dummy_mcg.func);
6794 }
6795 
6796 
6797 /* ARGSUSED */
6798 static void
6799 ibcm_dummy_recycle_rc_handler(ibt_status_t retval, void *arg)
6800 {
6801         ibcm_taskq_recycle_arg_t        dummy_rc_recycle;
6802 
6803         dummy_rc_recycle.func = ibcm_dummy_recycle_rc_handler;
6804 
6805         IBTF_DPRINTF_L5(cmlog, "ibcm_dummy_recycle_rc_handler: "
6806             "dummy_rc_recycle.func %p", dummy_rc_recycle.func);
6807 }
6808 
6809 
6810 /* ARGSUSED */
6811 static ibt_cm_status_t
6812 ibcm_dummy_ud_handler(void *priv, ibt_cm_ud_event_t *event,
6813     ibt_cm_ud_return_args_t *ret_args,
6814     void *priv_data, ibt_priv_data_len_t len)
6815 {
6816         /*
6817          * Let warlock see that ibcm_local_handler_s::actual_cm_handler
6818          * points to this routine.
6819          */
6820         ibcm_local_handler_t    p;
6821         ibcm_ud_state_data_t    dummy_ud;
6822 
6823         p.actual_cm_handler = ibcm_dummy_ud_handler;
6824         dummy_ud.ud_cm_handler = ibcm_dummy_ud_handler;
6825 
6826         IBTF_DPRINTF_L5(cmlog, "ibcm_dummy_ud_handler: p.actual_cm_handler %p"
6827             "dummy_ud.ud_cm_handler %p", p.actual_cm_handler,
6828             dummy_ud.ud_cm_handler);
6829         /*
6830          * Call all routines that the client's callback routine could call.
6831          */
6832 
6833         return (IBT_CM_ACCEPT);
6834 }
6835 
6836 /* ARGSUSED */
6837 static ibt_cm_status_t
6838 ibcm_dummy_rc_handler(void *priv, ibt_cm_event_t *event,
6839     ibt_cm_return_args_t *ret_args, void *priv_data, ibt_priv_data_len_t len)
6840 {
6841         ibcm_state_data_t       dummy_rc;
6842 
6843         dummy_rc.cm_handler = ibcm_dummy_rc_handler;
6844 
6845         IBTF_DPRINTF_L5(cmlog, "ibcm_dummy_rc_handler: "
6846             "dummy_ud.ud_cm_handler %p", dummy_rc.cm_handler);
6847         /*
6848          * Call all routines that the client's callback routine could call.
6849          */
6850 
6851         return (IBT_CM_ACCEPT);
6852 }


  23  */
  24 
  25 #include <sys/ib/mgt/ibcm/ibcm_impl.h>
  26 #include <sys/ib/ibtl/ibti.h>
  27 #include <sys/ib/mgt/ibcm/ibcm_arp.h>
  28 
  29 /*
  30  * ibcm_ti.c
  31  *      These routines implement the Communication Manager's interfaces to IBTL.
  32  */
  33 
  34 /* CM rc recycle task args structure definition */
  35 typedef struct ibcm_taskq_recycle_arg_s {
  36         ibt_channel_hdl_t       rc_chan;
  37         ibt_cep_flags_t         control;
  38         uint8_t                 hca_port_num;
  39         ibt_recycle_handler_t   func;
  40         void                    *arg;
  41 } ibcm_taskq_recycle_arg_t;
  42 


  43 static ibt_status_t     ibcm_init_reply_addr(ibcm_hca_info_t *hcap,
  44     ibcm_mad_addr_t *reply_addr, ibt_chan_open_args_t *chan_args,
  45     ibt_chan_open_flags_t flags, ib_time_t *cm_pkt_lt, ib_lid_t prim_slid);
  46 static void             ibcm_process_abort_via_taskq(void *args);
  47 static ibt_status_t     ibcm_process_rc_recycle_ret(void *recycle_arg);
  48 static ibt_status_t     ibcm_process_join_mcg(void *taskq_arg);
  49 static void             ibcm_process_async_join_mcg(void *tq_arg);
  50 
  51 ibt_status_t ibcm_get_node_rec(ibmf_saa_handle_t, sa_node_record_t *,
  52     uint64_t c_mask, void *, size_t *);
  53 
  54 static ibt_status_t ibcm_close_rc_channel(ibt_channel_hdl_t channel,
  55     ibcm_state_data_t *statep, ibt_execution_mode_t mode);
  56 
  57 /* Address Record management definitions */
  58 #define IBCM_DAPL_ATS_NAME      "DAPL Address Translation Service"
  59 #define IBCM_DAPL_ATS_SID       0x10000CE100415453ULL
  60 #define IBCM_DAPL_ATS_NBYTES    16
  61 ibcm_svc_info_t *ibcm_ar_svcinfop;
  62 ibcm_ar_t       *ibcm_ar_list;
  63 
  64 /*
  65  * Tunable parameter to turnoff the overriding of pi_path_mtu value.
  66  *      1       By default override the path record's pi_path_mtu value to
  67  *              IB_MTU_1K for all RC channels. This is done only for the
  68  *              channels established on Tavor HCA and the path's pi_path_mtu
  69  *              is greater than IB_MTU_1K.
  70  *      0       Do not override, use pi_path_mtu by default.
  71  */
  72 int     ibcm_override_path_mtu = 1;
  73 
  74 #ifdef DEBUG
  75 static void     ibcm_print_reply_addr(ibt_channel_hdl_t channel,
  76                     ibcm_mad_addr_t *cm_reply_addr);
  77 #endif
  78 






  79 /*








  80  * ibt_open_rc_channel()
  81  *      ibt_open_rc_channel opens a communication channel on the specified
  82  *      channel to the specified service. For connection service type qp's
  83  *      the CM initiates the CEP to establish the connection and transitions
  84  *      the QP/EEC to the "Ready to send" State modifying the QP/EEC's
  85  *      attributes as necessary.
  86  *      The implementation of this function assumes that alt path is different
  87  *      from primary path. It is assumed that the Path functions ensure that.
  88  *
  89  * RETURN VALUES:
  90  *      IBT_SUCCESS     on success (or respective failure on error)
  91  */
  92 ibt_status_t
  93 ibt_open_rc_channel(ibt_channel_hdl_t channel, ibt_chan_open_flags_t flags,
  94     ibt_execution_mode_t mode, ibt_chan_open_args_t *chan_args,
  95     ibt_rc_returns_t *ret_args)
  96 {
  97         /* all fields that are related to REQ MAD formation */
  98 
  99         ib_pkey_t               prim_pkey;


 543                         IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: "
 544                             "chan 0x%p ibt_modify_qp() = %d", channel, status);
 545         }
 546 
 547         /* allocate ibcm_state_data_t before grabbing the WRITER lock */
 548         statep = kmem_zalloc(sizeof (ibcm_state_data_t), KM_SLEEP);
 549         rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
 550         lkup_status = ibcm_lookup_msg(IBCM_OUTGOING_REQ, local_comid, 0, 0,
 551             hcap, &statep);
 552         rw_exit(&hcap->hca_state_rwlock);
 553 
 554         /* CM should be seeing this for the first time */
 555         ASSERT(lkup_status == IBCM_LOOKUP_NEW);
 556 
 557         /* Increment the hca's resource count */
 558         ibcm_inc_hca_res_cnt(hcap);
 559 
 560         /* Once a resource created on hca, no need to hold the acc cnt */
 561         ibcm_dec_hca_acc_cnt(hcap);
 562 


 563         statep->timerid = 0;
 564         statep->local_hca_guid = hca_guid;
 565         statep->local_qpn = local_qpn;
 566         statep->stored_reply_addr.cm_qp_entry = cm_qp_entry;
 567         statep->prim_port = IBCM_PRIM_CEP_PATH(chan_args).cep_hca_port_num;
 568         statep->alt_port = IBCM_ALT_CEP_PATH(chan_args).cep_hca_port_num;
 569 
 570 
 571         /* Save "statep" as channel's CM private data.  */
 572         statep->channel = channel;
 573         IBCM_SET_CHAN_PRIVATE(statep->channel, statep);
 574 
 575         statep->stored_msg = ibmf_msg;
 576         statep->dreq_msg = ibmf_msg_dreq;
 577 


 578         /* Start filling in the REQ MAD */
 579         req_msgp = (ibcm_req_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
 580         req_msgp->req_local_comm_id = h2b32(local_comid);
 581         req_msgp->req_svc_id = h2b64(chan_args->oc_path->pi_sid);
 582         req_msgp->req_local_ca_guid = h2b64(hca_guid);
 583         req_msgp->req_local_qkey = h2b32(local_qkey);        /* for EEC/RD */
 584 
 585         /* Bytes 32-35 are req_local_qpn and req_off_resp_resources */
 586         req_msgp->req_local_qpn_plus = h2b32(local_qpn << 8 | rdma_in);
 587 
 588         /* Bytes 36-39 are req_local_eec_no and req_off_initiator_depth */
 589         req_msgp->req_local_eec_no_plus = h2b32(local_eecn << 8 | rdma_out);
 590 
 591         if (flags & IBT_OCHAN_REMOTE_CM_TM)
 592                 remote_cm_resp_time = chan_args->oc_remote_cm_time;
 593         else
 594                 remote_cm_resp_time = ibcm_remote_response_time;
 595 
 596         /*
 597          * Bytes 40-43 - remote_eecn, remote_cm_resp_time, tran_type,


 773                     IBCM_ALT_ADDS_VECT(chan_args).av_srvl << 4 |
 774                     ((alternate_grh == B_TRUE) ? 0 : 8);
 775                 req_msgp->req_alt_localtime_plus = ibt_usec2ib((2 *
 776                     ibt_ib2usec(chan_args->oc_path->pi_alt_pkt_lt)) +
 777                     ibt_ib2usec(hcap->hca_ack_delay)) << 3;
 778 
 779                 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
 780                     "alt_dlid %x ", channel,
 781                     IBCM_ALT_ADDS_VECT(chan_args).av_dlid);
 782 
 783                 IBTF_DPRINTF_L5(cmlog, "ibt_open_rc_channel: chan 0x%p "
 784                     "alt GID %llX:%llX", channel,
 785                     IBCM_ALT_ADDS_VECT(chan_args).av_dgid.gid_prefix,
 786                     IBCM_ALT_ADDS_VECT(chan_args).av_dgid.gid_guid);
 787         }
 788 
 789         len = min(chan_args->oc_priv_data_len, IBT_REQ_PRIV_DATA_SZ);
 790         if ((len > 0) && chan_args->oc_priv_data)
 791                 bcopy(chan_args->oc_priv_data, req_msgp->req_private_data, len);
 792 


 793         /* return_data is filled up in the state machine code */
 794         if (ret_args != NULL) {
 795                 statep->open_return_data = ret_args;
 796         }
 797 
 798         /* initialize some statep fields here */
 799         statep->mode = IBCM_ACTIVE_MODE;
 800         statep->hcap = hcap;
 801 
 802         statep->cm_handler = chan_args->oc_cm_handler;
 803         statep->state_cm_private = chan_args->oc_cm_clnt_private;
 804 
 805         statep->pkt_life_time =
 806             ibt_ib2usec(chan_args->oc_path->pi_prim_pkt_lt);
 807 
 808         statep->timer_value = ibt_ib2usec(ibt_usec2ib(
 809             2 * ibt_ib2usec(cm_pkt_lt) + remote_cm_resp_time));
 810 
 811         /* Initialize statep->stored_reply_addr */
 812         statep->stored_reply_addr.ibmf_hdl = ibmf_hdl;


 832         statep->open_done = B_FALSE;
 833         statep->state = statep->timer_stored_state = IBCM_STATE_REQ_SENT;
 834         IBCM_REF_CNT_INCR(statep);      /* Decremented before return */
 835         IBCM_REF_CNT_INCR(statep);      /* Decremented after REQ is posted */
 836         statep->send_mad_flags |= IBCM_REQ_POST_BUSY;
 837 
 838         /*
 839          * Skip moving channel to error state during close, for OFUV clients.
 840          * OFUV clients transition the channel to error state by itself.
 841          */
 842         if (flags & IBT_OCHAN_OFUV)
 843                 statep->is_this_ofuv_chan = B_TRUE;
 844 
 845         IBCM_OUT_HDRP(statep->stored_msg)->AttributeID =
 846             h2b16(IBCM_INCOMING_REQ + IBCM_ATTR_BASE_ID);
 847 
 848         IBCM_OUT_HDRP(statep->stored_msg)->TransactionID =
 849             h2b64(ibcm_generate_tranid(IBCM_INCOMING_REQ, statep->local_comid,
 850             0));
 851 


 852         ibtl_cm_chan_is_opening(channel);
 853 
 854         ibcm_open_enqueue(statep);
 855 
 856         mutex_enter(&statep->state_mutex);
 857 
 858         if (mode == IBT_BLOCKING) {
 859 
 860                 /* wait for REQ/REP/RTU */
 861                 while (statep->open_done != B_TRUE) {
 862                         cv_wait(&statep->block_client_cv, &statep->state_mutex);
 863                 }
 864 
 865                 /*
 866                  * In the case that open_channel() fails because of a
 867                  * REJ or timeout, change retval to IBT_CM_FAILURE
 868                  */
 869                 if (statep->open_return_data->rc_status != IBT_CM_SUCCESS) {
 870                         status = IBT_CM_FAILURE;
 871                         ibtl_cm_chan_open_is_aborted(channel);


 899  *              If Redirect GID is not specified or specified to be on the same
 900  *                  subnet, then
 901  *                      Build CM path from chan_args->oc_cm_redirect_info
 902  *                      Set CM pkt lt to subnet timeout
 903  *              Else (ie., GID specified, but on a different subnet)
 904  *                      Do a path lookup to build CM Path and set CM pkt lt
 905  *
 906  */
 907 static ibt_status_t
 908 ibcm_init_reply_addr(ibcm_hca_info_t *hcap, ibcm_mad_addr_t *reply_addr,
 909     ibt_chan_open_args_t *chan_args, ibt_chan_open_flags_t flags,
 910     ib_time_t *cm_pkt_lt, ib_lid_t prim_slid)
 911 {
 912         ibt_adds_vect_t *cm_adds;
 913         ibt_path_info_t path;
 914         boolean_t       cm_grh;
 915         ibt_status_t    status;
 916 
 917         IBTF_DPRINTF_L5(cmlog, "ibcm_init_reply_addr:");
 918 


 919         /*
 920          * sending side CM lid/gid/port num are not based on any redirect
 921          * params. These values are set to primary RC path lid/gid/port num.
 922          * In the future, these values can be set based on framework policy
 923          * decisions ensuring reachability.
 924          */
 925         reply_addr->grh_hdr.ig_sender_gid =
 926             IBCM_PRIM_ADDS_VECT(chan_args).av_sgid;
 927         reply_addr->rcvd_addr.ia_local_lid = prim_slid;
 928         reply_addr->port_num = IBCM_PRIM_CEP_PATH(chan_args).cep_hca_port_num;
 929 
 930         if (flags & IBT_OCHAN_PORT_REDIRECTED) {
 931                 IBTF_DPRINTF_L4(cmlog, "ibcm_init_rely_addr: "
 932                     "IBT_OCHAN_PORT_REDIRECTED specified");
 933 
 934                 status = ibt_index2pkey_byguid(hcap->hca_guid,
 935                     chan_args->oc_cm_cep_path->cep_hca_port_num,
 936                     chan_args->oc_cm_cep_path->cep_pkey_ix,
 937                     &reply_addr->rcvd_addr.ia_p_key);
 938 


1063                 cm_adds = &(IBCM_PRIM_ADDS_VECT(chan_args));
1064         }
1065 
1066 
1067         cm_grh = cm_adds->av_send_grh;
1068         reply_addr->grh_exists = cm_grh;
1069 
1070         reply_addr->rcvd_addr.ia_remote_lid =
1071             cm_adds->av_dlid;
1072         reply_addr->grh_hdr.ig_recver_gid =
1073             cm_adds->av_dgid;
1074         reply_addr->grh_hdr.ig_flow_label =
1075             cm_adds->av_flow & IB_GRH_FLOW_LABEL_MASK;
1076         reply_addr->grh_hdr.ig_tclass =
1077             (cm_grh == B_TRUE) ? cm_adds->av_tclass : 0;
1078         reply_addr->grh_hdr.ig_hop_limit =
1079             (cm_grh == B_TRUE) ? cm_adds->av_hop : 1;
1080         reply_addr->rcvd_addr.ia_service_level =
1081             cm_adds->av_srvl;
1082 


1083         return (IBT_SUCCESS);
1084 }
1085 
1086 
1087 /*
1088  * ibt_prime_close_rc_channel()
1089  *      It allocates resources required for close channel operation, so
1090  *      ibt_close_rc_channel can be called from interrupt routine.
1091  *
1092  * INPUTS:
1093  *      channel                 The address of an ibt_channel_t struct that
1094  *                              specifies the channel to open.
1095  *
1096  * RETURN VALUES:
1097  *      IBT_SUCCESS     on success(or respective failure on error)
1098  *
1099  * Clients are typically expected to call this function in established state
1100  */
1101 ibt_status_t
1102 ibt_prime_close_rc_channel(ibt_channel_hdl_t channel)


1289         ibcm_close_enqueue(statep);
1290         mutex_exit(&statep->state_mutex);
1291 
1292         return (IBT_SUCCESS);
1293 }
1294 
1295 void
1296 ibcm_close_start(ibcm_state_data_t *statep)
1297 {
1298         mutex_enter(&statep->state_mutex);
1299         (void) ibcm_close_rc_channel(statep->channel, statep, IBT_NONBLOCKING);
1300 }
1301 
1302 static
1303 ibt_status_t
1304 ibcm_close_rc_channel(ibt_channel_hdl_t channel, ibcm_state_data_t *statep,
1305     ibt_execution_mode_t mode)
1306 {
1307         ibcm_hca_info_t         *hcap;
1308 

1309         ASSERT(MUTEX_HELD(&statep->state_mutex));
1310 
1311         IBTF_DPRINTF_L3(cmlog, "ibcm_close_rc_channel: chan 0x%p statep %p",
1312             channel, statep);
1313 
1314         hcap = statep->hcap;
1315 
1316         /* HCA must have been in active state. If not, it's a client bug */
1317         if (!IBCM_ACCESS_HCA_OK(hcap)) {
1318                 IBTF_DPRINTF_L2(cmlog, "ibcm_close_rc_channel: chan 0x%p "
1319                     "hcap 0x%p not active", channel, hcap);
1320                 IBCM_REF_CNT_DECR(statep);
1321                 mutex_exit(&statep->state_mutex);
1322                 return (IBT_CHAN_HDL_INVALID);
1323         }
1324 
1325         if (statep->state == IBCM_STATE_TRANSIENT_ESTABLISHED) {
1326                 while (statep->cep_in_rts == IBCM_BLOCK)
1327                         cv_wait(&statep->block_mad_cv, &statep->state_mutex);
1328         }


1607         IBTF_DPRINTF_L3(cmlog, "ibt_recycle_rc (%p, 0x%X, %d, %p, %p)", rc_chan,
1608             control, hca_port_num, func, arg);
1609 
1610         if (IBCM_INVALID_CHANNEL(rc_chan)) {
1611                 IBTF_DPRINTF_L2(cmlog, "ibt_recycle_rc: invalid channel");
1612                 return (IBT_CHAN_HDL_INVALID);
1613         }
1614 
1615         /* check qp state */
1616         retval = ibt_query_qp(rc_chan, &qp_attr);
1617 
1618         if (retval != IBT_SUCCESS)
1619                 return (retval);
1620 
1621         if (qp_attr.qp_info.qp_trans != IBT_RC_SRV)
1622                 return (IBT_CHAN_SRV_TYPE_INVALID);
1623 
1624         if (qp_attr.qp_info.qp_state != IBT_STATE_ERROR)
1625                 return (IBT_CHAN_STATE_INVALID);
1626 


1627         ibcm_tq_recycle_arg = kmem_alloc(sizeof (ibcm_taskq_recycle_arg_t),
1628             KM_SLEEP);
1629 
1630         ibcm_tq_recycle_arg->rc_chan         = rc_chan;
1631         ibcm_tq_recycle_arg->control         = control;
1632         ibcm_tq_recycle_arg->hca_port_num    = hca_port_num;
1633         ibcm_tq_recycle_arg->func            = func;
1634         ibcm_tq_recycle_arg->arg             = arg;
1635 


1636         IBCM_GET_CHAN_PRIVATE(rc_chan, statep);
1637 
1638         /*
1639          * If non-blocking ie., func specified and channel has not yet completed
1640          * the timewait, then schedule the work for later
1641          */
1642         if ((func != NULL) && (statep != NULL)) {
1643                 IBCM_RELEASE_CHAN_PRIVATE(rc_chan);

1644                 statep->recycle_arg = ibcm_tq_recycle_arg;

1645                 return (IBT_SUCCESS);
1646         }
1647 
1648         /*
1649          * if blocking ie., func specified, and channel has not yet completed
1650          * the timewait, then block until the channel completes the timewait
1651          */
1652         if (statep != NULL)
1653                 IBCM_RELEASE_CHAN_PRIVATE(rc_chan);
1654         IBCM_WAIT_CHAN_PRIVATE(rc_chan);
1655 
1656         if (func) {     /* NON BLOCKING case. Taskq for QP state change */
1657                 (void) taskq_dispatch(ibcm_taskq, ibcm_process_rc_recycle,
1658                     ibcm_tq_recycle_arg, TQ_SLEEP);
1659                 return (IBT_SUCCESS);
1660         } else  /* BLOCKING case */
1661                 return (ibcm_process_rc_recycle_ret(ibcm_tq_recycle_arg));
1662 }
1663 
1664 void


1750 ibcm_process_abort_via_taskq(void *args)
1751 {
1752         ibcm_state_data_t       *statep = (ibcm_state_data_t *)args;
1753 
1754         ibcm_process_abort(statep);
1755         mutex_enter(&statep->state_mutex);
1756         IBCM_REF_CNT_DECR(statep);
1757         mutex_exit(&statep->state_mutex);
1758 }
1759 
1760 /*
1761  * Local UD CM Handler's private data, used during ibt_request_ud_dest() in
1762  * Non-Blocking mode operations.
1763  */
1764 typedef struct ibcm_local_handler_s {
1765         ibt_cm_ud_handler_t     actual_cm_handler;
1766         void                    *actual_cm_private;
1767         ibt_ud_dest_t           *dest_hdl;
1768 } ibcm_local_handler_t;
1769 


1770 /*
1771  * Local UD CM Handler, used when ibt_alloc_ud_dest() is issued in
1772  * NON-Blocking mode.
1773  *
1774  * Out here, we update the UD Destination handle with
1775  * the obtained DQPN and QKey (from SIDR REP) and invokes actual client
1776  * handler that was specified by the client.
1777  */
1778 static ibt_cm_status_t
1779 ibcm_local_cm_handler(void *priv, ibt_cm_ud_event_t *event,
1780     ibt_cm_ud_return_args_t *ret_args, void *priv_data, ibt_priv_data_len_t len)
1781 {
1782         ibcm_local_handler_t    *handler_priv = (ibcm_local_handler_t *)priv;
1783 
1784         IBTF_DPRINTF_L4(cmlog, "ibcm_local_cm_handler: event %d",
1785             event->cm_type);
1786 
1787         ASSERT(handler_priv != NULL);
1788 
1789         switch (event->cm_type) {


1919         /* Return failure if the HCA device or Port is not operational */
1920 
1921         if ((retval = ibt_get_port_state_byguid(port.hp_hca_guid, port.hp_port,
1922             NULL, NULL)) != IBT_SUCCESS) {
1923                 /* Device Port is not in good state, don't use it. */
1924                 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: Invalid "
1925                     "port specified or port not active");
1926                 ibcm_dec_hca_acc_cnt(hcap);
1927                 return (retval);
1928         }
1929 
1930         retval = ibt_index2pkey_byguid(port.hp_hca_guid, port.hp_port,
1931             attr->ud_pkey_ix, &ud_pkey);
1932         if (retval != IBT_SUCCESS) {
1933                 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: "
1934                     "Failed to convert index2pkey: %d", retval);
1935                 ibcm_dec_hca_acc_cnt(hcap);
1936                 return (retval);
1937         }
1938 


1939         /* Allocate a new request id */
1940         if (ibcm_alloc_reqid(hcap, &sidr_entry.srch_req_id) == IBCM_FAILURE) {
1941                 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: "
1942                     "no req id available");
1943                 ibcm_dec_hca_acc_cnt(hcap);
1944                 return (IBT_INSUFF_KERNEL_RESOURCE);
1945         }
1946 
1947         if ((hcap->hca_port_info[port.hp_port - 1].port_ibmf_hdl == NULL) &&
1948             ((retval = ibcm_hca_reinit_port(hcap, port.hp_port - 1))
1949             != IBT_SUCCESS)) {
1950                 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: "
1951                     "ibmf reg or callback setup failed during re-initialize");
1952                 return (retval);
1953         }
1954 
1955         ibmf_hdl = hcap->hca_port_info[port.hp_port - 1].port_ibmf_hdl;
1956 
1957         /* find the ibmf QP to post the SIDR REQ */
1958         if ((cm_qp_entry = ibcm_find_qp(hcap, port.hp_port, ud_pkey)) ==


1960                 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: IBMF QP allocation"
1961                     " failed");
1962                 ibcm_dec_hca_acc_cnt(hcap);
1963                 return (IBT_INSUFF_RESOURCE);
1964         }
1965 
1966         if ((retval = ibcm_alloc_out_msg(ibmf_hdl, &ibmf_msg, MAD_METHOD_SEND))
1967             != IBT_SUCCESS) {
1968                 IBTF_DPRINTF_L2(cmlog, "ibcm_ud_get_dqpn: IBMF MSG allocation"
1969                     " failed");
1970                 ibcm_release_qp(cm_qp_entry);
1971                 ibcm_dec_hca_acc_cnt(hcap);
1972                 return (retval);
1973         }
1974 
1975         sidr_entry.srch_lid = port.hp_base_lid;
1976         sidr_entry.srch_gid = attr->ud_addr->av_sgid;
1977         sidr_entry.srch_grh_exists = attr->ud_addr->av_send_grh;
1978         sidr_entry.srch_mode = IBCM_ACTIVE_MODE;
1979 


1980         /* do various allocations needed here */
1981         rw_enter(&hcap->hca_sidr_list_lock, RW_WRITER);
1982 
1983         (void) ibcm_find_sidr_entry(&sidr_entry, hcap, &ud_statep,
1984             IBCM_FLAG_ADD);
1985         rw_exit(&hcap->hca_sidr_list_lock);
1986 
1987         /* Increment hca's resource count */
1988         ibcm_inc_hca_res_cnt(hcap);
1989 
1990         /* After a resource created on hca, no need to hold the acc cnt */
1991         ibcm_dec_hca_acc_cnt(hcap);
1992 


1993         /* Initialize some ud_statep fields */
1994         ud_statep->ud_stored_msg = ibmf_msg;
1995         ud_statep->ud_svc_id = attr->ud_sid;
1996         ud_statep->ud_pkt_life_time =
1997             ibt_ib2usec(attr->ud_pkt_lt);
1998         ud_statep->ud_stored_reply_addr.cm_qp_entry = cm_qp_entry;
1999 
2000         /* set remaining retry cnt */
2001         ud_statep->ud_remaining_retry_cnt = ud_statep->ud_max_cm_retries;
2002 
2003         /*
2004          * Get UD handler and corresponding args which is pass it back
2005          * as first argument for the handler.
2006          */
2007         ud_statep->ud_state_cm_private = attr->ud_cm_private;
2008 
2009         if (mode == IBT_BLOCKING)
2010                 ud_statep->ud_return_data = ret_args;
2011         else
2012                 ud_statep->ud_cm_handler = attr->ud_cm_handler;


2025         ud_statep->ud_stored_reply_addr.grh_hdr.ig_flow_label =
2026             attr->ud_addr->av_flow & IB_GRH_FLOW_LABEL_MASK;
2027 
2028         /* needs to be derived based on the base LID and path bits */
2029         ud_statep->ud_stored_reply_addr.rcvd_addr.ia_local_lid =
2030             port.hp_base_lid;
2031         ud_statep->ud_stored_reply_addr.rcvd_addr.ia_remote_lid =
2032             attr->ud_addr->av_dlid;
2033         ud_statep->ud_stored_reply_addr.rcvd_addr.ia_p_key = ud_pkey;
2034         ud_statep->ud_stored_reply_addr.rcvd_addr.ia_q_key = IB_GSI_QKEY;
2035         ud_statep->ud_stored_reply_addr.rcvd_addr.ia_service_level =
2036             attr->ud_addr->av_srvl;
2037 
2038         /*
2039          * This may be enchanced later, to use a remote qno based on past
2040          * redirect rej mad responses. This would be the place to specify
2041          * appropriate remote qno
2042          */
2043         ud_statep->ud_stored_reply_addr.rcvd_addr.ia_remote_qno = 1;
2044 


2045         /* Initialize the SIDR REQ message fields */
2046         sidr_req_msgp =
2047             (ibcm_sidr_req_msg_t *)IBCM_OUT_MSGP(ud_statep->ud_stored_msg);
2048 
2049         sidr_req_msgp->sidr_req_request_id = h2b32(ud_statep->ud_req_id);
2050         sidr_req_msgp->sidr_req_service_id = h2b64(attr->ud_sid);
2051         sidr_req_msgp->sidr_req_pkey = h2b16(ud_pkey);
2052         IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->AttributeID =
2053             h2b16(IBCM_INCOMING_SIDR_REQ + IBCM_ATTR_BASE_ID);
2054 
2055         if ((attr->ud_priv_data != NULL) && (attr->ud_priv_data_len > 0)) {
2056                 bcopy(attr->ud_priv_data, sidr_req_msgp->sidr_req_private_data,
2057                     min(attr->ud_priv_data_len, IBT_SIDR_REQ_PRIV_DATA_SZ));
2058         }
2059 
2060         /* Send out the SIDR REQ message */
2061         ud_statep->ud_state = IBCM_STATE_SIDR_REQ_SENT;
2062         ud_statep->ud_timer_stored_state = IBCM_STATE_SIDR_REQ_SENT;
2063         IBCM_UD_REF_CNT_INCR(ud_statep); /* for non-blocking SIDR REQ post */
2064         ud_statep->ud_timer_value = ibt_ib2usec(ibcm_max_sidr_rep_proctime) +
2065             (ud_statep->ud_pkt_life_time * 2);
2066 
2067         IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->TransactionID =
2068             h2b64(ibcm_generate_tranid(IBCM_INCOMING_SIDR_REQ,
2069             ud_statep->ud_req_id, 0));
2070 
2071         IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: timer_value in HZ = %x",
2072             ud_statep->ud_timer_value);
2073 



2074         ibcm_post_ud_mad(ud_statep, ud_statep->ud_stored_msg,
2075             ibcm_post_sidr_req_complete, ud_statep);
2076 
2077         mutex_enter(&ud_statep->ud_state_mutex);
2078 
2079         /* Wait for SIDR_REP */
2080         if (mode == IBT_BLOCKING) {
2081                 IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: blocking");
2082 
2083                 while (ud_statep->ud_blocking_done != B_TRUE) {
2084                         cv_wait(&ud_statep->ud_block_client_cv,
2085                             &ud_statep->ud_state_mutex);
2086                 }
2087 
2088                 IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: finished blocking");
2089 
2090                 if (ret_args->ud_status == IBT_CM_SREP_QPN_VALID) {
2091                         IBTF_DPRINTF_L4(cmlog, "ibcm_ud_get_dqpn: DQPN = %x, "
2092                             "status = %x, QKey = %x", ret_args->ud_dqpn,
2093                             ret_args->ud_status, ret_args->ud_qkey);


2148             attr->ud_addr);
2149         if (retval != IBT_SUCCESS) {
2150                 IBTF_DPRINTF_L2(cmlog, "ibt_request_ud_dest: "
2151                     "Address Handle Modification failed: %d", retval);
2152                 return (retval);
2153         }
2154 
2155         if (mode == IBT_NONBLOCKING) {
2156                 /*
2157                  * In NON-BLOCKING mode, and we need to update the destination
2158                  * handle with the DQPN and QKey that are obtained from
2159                  * SIDR REP, hook-up our own handler, so that we can catch
2160                  * the event, and we ourselves call the actual client's
2161                  * ud_cm_handler, in our handler.
2162                  */
2163 
2164                 /* Allocate memory for local handler's private data. */
2165                 local_handler_priv =
2166                     kmem_alloc(sizeof (*local_handler_priv), KM_SLEEP);
2167 


2168                 local_handler_priv->actual_cm_handler = attr->ud_cm_handler;
2169                 local_handler_priv->actual_cm_private = attr->ud_cm_private;
2170                 local_handler_priv->dest_hdl = ud_destp;
2171 


2172                 attr->ud_cm_handler = ibcm_local_cm_handler;
2173                 attr->ud_cm_private = local_handler_priv;
2174         }
2175 
2176         /* In order to get DQPN and Destination QKey, perform SIDR */
2177         retval = ibcm_ud_get_dqpn(attr, mode, ud_ret_args);
2178         if (retval != IBT_SUCCESS) {
2179                 IBTF_DPRINTF_L2(cmlog, "ibt_request_ud_dest: "
2180                     "Failed to get DQPN: %d", retval);
2181 
2182                 /* Free memory allocated for local handler's private data. */
2183                 if (local_handler_priv != NULL)
2184                         kmem_free(local_handler_priv,
2185                             sizeof (*local_handler_priv));
2186                 return (retval);
2187         }
2188 
2189         /*
2190          * Fill in the dqpn and dqkey as obtained from ud_ret_args,
2191          * values will be valid only on BLOCKING mode.


2276         statep = (ibcm_state_data_t *)cm_session_id;
2277 
2278         if (statep == NULL) {
2279                 IBTF_DPRINTF_L2(cmlog, "ibt_cm_delay: statep NULL");
2280                 return (IBT_INVALID_PARAM);
2281         }
2282 
2283         IBTF_DPRINTF_L4(cmlog, "ibt_cm_delay: statep %p", statep);
2284 
2285         /* Allocate an ibmf msg for mra, if not allocated yet */
2286         if (statep->mra_msg == NULL) {
2287                 if ((status = ibcm_alloc_out_msg(
2288                     statep->stored_reply_addr.ibmf_hdl, &statep->mra_msg,
2289                     MAD_METHOD_SEND)) != IBT_SUCCESS) {
2290                         IBTF_DPRINTF_L2(cmlog, "ibt_cm_delay: chan 0x%p"
2291                             "IBMF MSG allocation failed", statep->channel);
2292                         return (status);
2293                 }
2294         }
2295 


2296         mra_msgp = (ibcm_mra_msg_t *)IBCM_OUT_MSGP(statep->mra_msg);
2297         mra_msgp->mra_local_comm_id = h2b32(statep->local_comid);
2298         mra_msgp->mra_remote_comm_id = h2b32(statep->remote_comid);
2299 
2300         /* fill in rest of MRA's fields - Message MRAed and Service Timeout */
2301         if (flags == IBT_CM_DELAY_REQ) {
2302                 msg_typ = IBT_CM_MRA_TYPE_REQ;
2303         } else if (flags == IBT_CM_DELAY_REP) {
2304                 msg_typ = IBT_CM_MRA_TYPE_REP;
2305         } else if (flags == IBT_CM_DELAY_LAP) {
2306                 msg_typ = IBT_CM_MRA_TYPE_LAP;
2307         }
2308 
2309         mra_msgp->mra_message_type_plus = msg_typ << 6;
2310         mra_msgp->mra_service_timeout_plus = ibt_usec2ib(service_time) << 3;
2311 
2312         len = min(len, IBT_MRA_PRIV_DATA_SZ);
2313         if (priv_data && (len > 0))
2314                 bcopy(priv_data, mra_msgp->mra_private_data, len);
2315 
2316         IBCM_OUT_HDRP(statep->mra_msg)->AttributeID =
2317             h2b16(IBCM_INCOMING_MRA + IBCM_ATTR_BASE_ID);
2318 


2319         mutex_enter(&statep->state_mutex);
2320 
2321         if ((statep->mode == IBCM_ACTIVE_MODE) &&
2322             (statep->state == IBCM_STATE_REP_RCVD)) {
2323                 statep->state = IBCM_STATE_MRA_REP_SENT;
2324         } else if (statep->mode == IBCM_PASSIVE_MODE) {
2325                 if (statep->state == IBCM_STATE_REQ_RCVD) {
2326                         statep->state = IBCM_STATE_MRA_SENT;
2327                 } else if (statep->ap_state == IBCM_AP_STATE_LAP_RCVD) {
2328                         statep->ap_state = IBCM_AP_STATE_MRA_LAP_RCVD;
2329                 } else {
2330                         IBTF_DPRINTF_L2(cmlog, "ibt_cm_delay: invalid state "
2331                             "/ap_state/mode %x, %x, %x", statep->state,
2332                             statep->ap_state, statep->mode);
2333                         mutex_exit(&statep->state_mutex);
2334                         return (IBT_CHAN_STATE_INVALID);
2335                 }
2336         } else {
2337                 IBTF_DPRINTF_L2(cmlog, "ibt_cm_delay: invalid state "
2338                     "/ap_state/mode %x, %x, %x", statep->state,


2392  *                      in the range.
2393  *
2394  * ibt_register_service() returns:
2395  *      IBT_SUCCESS             - added a service successfully.
2396  *      IBT_INVALID_PARAM       - invalid input parameter.
2397  *      IBT_CM_FAILURE          - failed to add the service.
2398  *      IBT_CM_SERVICE_EXISTS   - service already exists.
2399  *      IBT_INSUFF_KERNEL_RESOURCE - ran out of local service ids (should
2400  *                                   never happen).
2401  */
2402 ibt_status_t
2403 ibt_register_service(ibt_clnt_hdl_t ibt_hdl, ibt_srv_desc_t *srv,
2404     ib_svc_id_t sid, int num_sids, ibt_srv_hdl_t *srv_hdl, ib_svc_id_t *ret_sid)
2405 {
2406         ibcm_svc_info_t         *svcinfop;
2407 
2408         IBTF_DPRINTF_L2(cmlog, "ibt_register_service(%p (%s), %p, 0x%llX, %d)",
2409             ibt_hdl, ibtl_cm_get_clnt_name(ibt_hdl), srv, (longlong_t)sid,
2410             num_sids);
2411 


2412         *srv_hdl = NULL;
2413 
2414         if (num_sids <= 0) {
2415                 IBTF_DPRINTF_L2(cmlog, "ibt_register_service: "
2416                     "Invalid number of service-ids specified (%d)", num_sids);
2417                 return (IBT_INVALID_PARAM);
2418         }
2419 
2420         if (sid == 0) {
2421                 if (ret_sid == NULL)
2422                         return (IBT_INVALID_PARAM);
2423                 sid = ibcm_alloc_local_sids(num_sids);
2424                 if (sid == 0)
2425                         return (IBT_INSUFF_KERNEL_RESOURCE);
2426 
2427         /* Make sure that the ServiceId specified is not of LOCAL AGN type. */
2428         } else if ((sid & IB_SID_AGN_MASK) == IB_SID_AGN_LOCAL) {
2429                 IBTF_DPRINTF_L2(cmlog, "ibt_register_service: "
2430                     "Invalid non-LOCAL SID specified: 0x%llX",
2431                     (longlong_t)sid);


2441         }
2442 
2443         /*
2444          * 'sid' and 'num_sids' are filled in ibcm_create_svc_entry()
2445          */
2446         svcinfop->svc_flags = srv->sd_flags;
2447         svcinfop->svc_rc_handler = srv->sd_handler;
2448         svcinfop->svc_ud_handler = srv->sd_ud_handler;
2449 
2450         if (ret_sid != NULL)
2451                 *ret_sid = sid;
2452 
2453         *srv_hdl = svcinfop;
2454 
2455         ibtl_cm_change_service_cnt(ibt_hdl, num_sids);
2456 
2457         /* If this message isn't seen, then ibt_register_service failed. */
2458         IBTF_DPRINTF_L2(cmlog, "ibt_register_service: done (%p, %llX)",
2459             svcinfop, sid);
2460 


2461         return (IBT_SUCCESS);
2462 }
2463 
2464 
2465 static ibt_status_t
2466 ibcm_write_service_record(ibmf_saa_handle_t saa_handle,
2467     sa_service_record_t *srv_recp, ibmf_saa_access_type_t saa_type)
2468 {
2469         int     rval;
2470         int     retry;
2471 
2472         ibcm_sa_access_enter();
2473         for (retry = 0; retry < ibcm_max_sa_retries; retry++) {
2474                 rval = ibmf_saa_update_service_record(
2475                     saa_handle, srv_recp, saa_type, 0);
2476                 if (rval != IBMF_TRANS_TIMEOUT) {
2477                         break;
2478                 }
2479                 IBTF_DPRINTF_L2(cmlog, "ibcm_write_service_record: "
2480                     "ibmf_saa_update_service_record timed out"


2552                                 mutex_exit(&ibcm_svc_info_lock);
2553                                 IBTF_DPRINTF_L3(cmlog, "ibcm_rem_stale_srec: "
2554                                     "This is not Stale, it's an active record");
2555                                 continue;
2556                         }
2557                         mutex_exit(&ibcm_svc_info_lock);
2558 
2559                         IBTF_DPRINTF_L2(cmlog, "ibcm_rem_stale_srec: "
2560                             "Removing Stale Rec: %s, %llX",
2561                             srv_resp->ServiceName, srv_resp->ServiceID);
2562 
2563                         IBCM_DUMP_SERVICE_REC(srv_resp);
2564 
2565                         /*
2566                          * Remove the Service Record Entry from SA.
2567                          *
2568                          * Get ServiceID info from Response Buf, other
2569                          * attributes are already filled-in.
2570                          */
2571 


2572                         srec->ServiceID = srv_resp->ServiceID;
2573 


2574                         (void) ibcm_write_service_record(saa_handle, srec,
2575                             IBMF_SAA_DELETE);
2576                 }
2577 
2578                 /* Deallocate the memory for results_p. */
2579                 kmem_free(results_p, length);
2580         }
2581 }
2582 
2583 
2584 
2585 /*
2586  * ibt_bind_service()
2587  *      Register a service with the IBCM
2588  *
2589  * INPUTS:
2590  *      srv_hdl         The service id handle returned to the client
2591  *                      on an ibt_service_register() call.
2592  *
2593  *      gid             The GID to which to bind the service.


2616  */
2617 ibt_status_t
2618 ibt_bind_service(ibt_srv_hdl_t srv_hdl, ib_gid_t gid, ibt_srv_bind_t *srv_bind,
2619     void *cm_private, ibt_sbind_hdl_t *sb_hdl_p)
2620 {
2621         ibt_status_t            status;
2622         ibtl_cm_hca_port_t      port;
2623         ibcm_svc_bind_t         *sbindp, *sbp;
2624         ibcm_hca_info_t         *hcap;
2625         ib_svc_id_t             sid, start_sid, end_sid;
2626         ibmf_saa_handle_t       saa_handle;
2627         sa_service_record_t     srv_rec;
2628         uint16_t                pkey_ix;
2629 
2630         if (sb_hdl_p != NULL)
2631                 *sb_hdl_p = NULL;       /* return value for error cases */
2632 
2633         IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: srv_hdl %p, gid (%llX:%llX)",
2634             srv_hdl, (longlong_t)gid.gid_prefix, (longlong_t)gid.gid_guid);
2635 


2636         /* Call ibtl_cm_get_hca_port to get the port number and the HCA GUID. */
2637         if ((status = ibtl_cm_get_hca_port(gid, 0, &port)) != IBT_SUCCESS) {
2638                 IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: "
2639                     "ibtl_cm_get_hca_port failed: %d", status);
2640                 return (status);
2641         }
2642         IBTF_DPRINTF_L4(cmlog, "ibt_bind_service: Port:%d HCA GUID:%llX",
2643             port.hp_port, port.hp_hca_guid);
2644 
2645         hcap = ibcm_find_hca_entry(port.hp_hca_guid);
2646         if (hcap == NULL) {
2647                 IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: NO HCA found");
2648                 return (IBT_HCA_BUSY_DETACHING);
2649         }
2650         IBTF_DPRINTF_L4(cmlog, "ibt_bind_service: hcap = %p", hcap);
2651 
2652         if (srv_bind != NULL) {
2653                 saa_handle = ibcm_get_saa_handle(hcap, port.hp_port);
2654                 if (saa_handle == NULL) {
2655                         IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: "


2809                                         }
2810                                         mutex_exit(&ibcm_svc_info_lock);
2811                                         ibcm_dec_hca_acc_cnt(hcap);
2812 
2813                                         kmem_free(sbindp, sizeof (*sbindp));
2814                                 }
2815                                 return (status);
2816                         }
2817                 }
2818         }
2819         ibcm_inc_hca_svc_cnt(hcap);
2820         ibcm_dec_hca_acc_cnt(hcap);
2821 
2822         /* If this message isn't seen then ibt_bind_service failed */
2823         IBTF_DPRINTF_L2(cmlog, "ibt_bind_service: DONE (%p, %llX:%llX)",
2824             srv_hdl, gid.gid_prefix, gid.gid_guid);
2825 
2826         if (sb_hdl_p != NULL)
2827                 *sb_hdl_p = sbindp;
2828 


2829         return (IBT_SUCCESS);
2830 }
2831 
2832 ibt_status_t
2833 ibt_unbind_service(ibt_srv_hdl_t srv_hdl, ibt_sbind_hdl_t sbindp)
2834 {
2835         ib_svc_id_t     sid, end_sid;
2836         ibt_status_t    rval;
2837         ibcm_hca_info_t *hcap;
2838         ibcm_svc_bind_t *sbp, **sbpp;
2839 
2840         IBTF_DPRINTF_L2(cmlog, "ibt_unbind_service(%p, %p)",
2841             srv_hdl, sbindp);
2842 
2843         hcap = ibcm_find_hca_entry(sbindp->sbind_hcaguid);
2844 
2845         /* If there is a service on hca, respective hcap cannot go away */
2846         ASSERT(hcap != NULL);
2847 
2848         mutex_enter(&ibcm_svc_info_lock);


2981 {
2982         ibcm_svc_info_t         *svcp;
2983         ibcm_svc_lookup_t       svc;
2984 
2985         IBTF_DPRINTF_L2(cmlog, "ibt_deregister_service(%p (%s), %p)",
2986             ibt_hdl, ibtl_cm_get_clnt_name(ibt_hdl), srv_hdl);
2987 
2988         mutex_enter(&ibcm_svc_info_lock);
2989 
2990         if (srv_hdl->svc_bind_list != NULL) {
2991                 IBTF_DPRINTF_L2(cmlog, "ibt_deregister_service:"
2992                     " srv_hdl %p still has bindings", srv_hdl);
2993                 mutex_exit(&ibcm_svc_info_lock);
2994                 return (IBT_CM_SERVICE_BUSY);
2995         }
2996         svc.sid = srv_hdl->svc_id;
2997         svc.num_sids = 1;
2998         IBTF_DPRINTF_L3(cmlog, "ibt_deregister_service: SID 0x%llX, numsids %d",
2999             srv_hdl->svc_id, srv_hdl->svc_num_sids);
3000 



3001         svcp = avl_find(&ibcm_svc_avl_tree, &svc, NULL);
3002         if (svcp != srv_hdl) {
3003                 mutex_exit(&ibcm_svc_info_lock);
3004                 IBTF_DPRINTF_L2(cmlog, "ibt_deregister_service(): "
3005                     "srv_hdl %p not found", srv_hdl);
3006                 return (IBT_INVALID_PARAM);
3007         }
3008         avl_remove(&ibcm_svc_avl_tree, svcp);
3009 
3010         /* wait for active REQ/SREQ handling to be done */
3011         svcp->svc_to_delete = 1;
3012         while (svcp->svc_ref_cnt != 0)
3013                 cv_wait(&ibcm_svc_info_cv, &ibcm_svc_info_lock);
3014 
3015         mutex_exit(&ibcm_svc_info_lock);
3016 
3017         if ((srv_hdl->svc_id & IB_SID_AGN_MASK) == IB_SID_AGN_LOCAL)
3018                 ibcm_free_local_sids(srv_hdl->svc_id, srv_hdl->svc_num_sids);
3019 
3020         ibtl_cm_change_service_cnt(ibt_hdl, -srv_hdl->svc_num_sids);


3923         /* wait until client's CM handler returns DEFER status back to CM */
3924 
3925         while (statep->clnt_proceed == IBCM_BLOCK) {
3926                 IBTF_DPRINTF_L5(cmlog, "ibt_cm_proceed : chan 0x%p blocked for "
3927                     "return of client's cm handler", statep->channel);
3928                 cv_wait(&statep->block_client_cv, &statep->state_mutex);
3929         }
3930 
3931         if (statep->clnt_proceed == IBCM_FAIL) {
3932                 mutex_exit(&statep->state_mutex);
3933                 IBTF_DPRINTF_L2(cmlog, "ibt_cm_proceed : chan 0x%p Failed as "
3934                     "client returned non-DEFER status from cm handler",
3935                     statep->channel);
3936                 return (IBT_CHAN_STATE_INVALID);
3937         }
3938 
3939         ASSERT(statep->clnt_proceed == IBCM_UNBLOCK);
3940         statep->clnt_proceed = IBCM_FAIL;
3941         mutex_exit(&statep->state_mutex);
3942 


3943         /* the state machine processing is done in a separate thread */
3944 
3945         /* proceed_targs is freed in ibcm_proceed_via_taskq */
3946         proceed_targs = kmem_alloc(sizeof (ibcm_proceed_targs_t),
3947             KM_SLEEP);
3948 
3949         proceed_targs->event  = event;
3950         proceed_targs->status = status;
3951         proceed_targs->priv_data_len = priv_data_len;
3952 
3953         bcopy(priv_data, proceed_targs->priv_data, priv_data_len);
3954 
3955         proceed_targs->tst.rc.statep = statep;
3956         bcopy(cm_event_data, &proceed_targs->tst.rc.rc_cm_event_data,
3957             sizeof (ibt_cm_proceed_reply_t));
3958 


3959         (void) taskq_dispatch(ibcm_taskq, ibcm_proceed_via_taskq,
3960             proceed_targs, TQ_SLEEP);
3961 
3962         return (IBT_SUCCESS);
3963 }
3964 
3965 /*
3966  * Function:
3967  *      ibcm_proceed_via_taskq
3968  *
3969  * Called from taskq, dispatched by ibt_cm_proceed
3970  * Completes the cm state processing for ibt_cm_proceed
3971  */
3972 void
3973 ibcm_proceed_via_taskq(void *targs)
3974 {
3975         ibcm_proceed_targs_t    *proceed_targs = (ibcm_proceed_targs_t *)targs;
3976         ibcm_state_data_t *statep = proceed_targs->tst.rc.statep;
3977         ibt_cm_reason_t reject_reason;
3978         uint8_t arej_len;


4084         /* wait until client's CM handler returns DEFER status back to CM */
4085 
4086         while (ud_statep->ud_clnt_proceed == IBCM_BLOCK) {
4087                 IBTF_DPRINTF_L5(cmlog, "ibt_cm_ud_proceed : Blocked for return"
4088                     " of client's ud cm handler");
4089                 cv_wait(&ud_statep->ud_block_client_cv,
4090                     &ud_statep->ud_state_mutex);
4091         }
4092 
4093         if (ud_statep->ud_clnt_proceed == IBCM_FAIL) {
4094                 mutex_exit(&ud_statep->ud_state_mutex);
4095                 IBTF_DPRINTF_L2(cmlog, "ibt_cm_ud_proceed : Failed as client "
4096                     "returned non-DEFER status from cm handler");
4097                 return (IBT_INVALID_PARAM);
4098         }
4099 
4100         ASSERT(ud_statep->ud_clnt_proceed == IBCM_UNBLOCK);
4101         ud_statep->ud_clnt_proceed = IBCM_FAIL;
4102         mutex_exit(&ud_statep->ud_state_mutex);
4103 


4104         /* the state machine processing is done in a separate thread */
4105 
4106         /* proceed_targs is freed in ibcm_proceed_via_taskq */
4107         proceed_targs = kmem_zalloc(sizeof (ibcm_proceed_targs_t),
4108             KM_SLEEP);
4109 
4110         proceed_targs->status = status;
4111         proceed_targs->priv_data_len = priv_data_len;
4112 
4113         bcopy(priv_data, proceed_targs->priv_data, priv_data_len);
4114 
4115         if (status == IBT_CM_ACCEPT) {
4116                 proceed_targs->tst.ud.ud_qkey =
4117                     qp_attr.qp_info.qp_transport.ud.ud_qkey;
4118                 proceed_targs->tst.ud.ud_qpn = qp_attr.qp_qpn;
4119         }
4120 
4121         proceed_targs->tst.ud.ud_statep = ud_statep;
4122 
4123         /* copy redirect info based on status */
4124         if (status == IBT_CM_REDIRECT)
4125                 bcopy(redirect_infop, &proceed_targs->tst.ud.ud_redirect_info,
4126                     sizeof (ibt_redirect_info_t));
4127 


4128         (void) taskq_dispatch(ibcm_taskq, ibcm_ud_proceed_via_taskq,
4129             proceed_targs, TQ_SLEEP);
4130 
4131         return (IBT_SUCCESS);
4132 }
4133 
4134 /*
4135  * Function:
4136  *      ibcm_ud_proceed_via_taskq
4137  *
4138  * Called from taskq, dispatched by ibt_cm_ud_proceed
4139  * Completes the cm state processing for ibt_cm_ud_proceed
4140  */
4141 void
4142 ibcm_ud_proceed_via_taskq(void *targs)
4143 {
4144         ibcm_proceed_targs_t    *proceed_targs = (ibcm_proceed_targs_t *)targs;
4145         ibcm_ud_state_data_t    *ud_statep = proceed_targs->tst.ud.ud_statep;
4146         ibcm_ud_clnt_reply_info_t ud_clnt_info;
4147         ibt_sidr_status_t       sidr_status;


4348                 ibcm_lapr_exit();
4349                 return (IBT_CHAN_STATE_INVALID);
4350         } else {
4351                 /* Set to LAP Sent state */
4352                 statep->ap_state = IBCM_AP_STATE_LAP_SENT;
4353                 statep->ap_done = B_FALSE;
4354                 statep->remaining_retry_cnt = statep->max_cm_retries;
4355                 statep->timer_stored_state = statep->state;
4356                 statep->timer_stored_ap_state = statep->ap_state;
4357                 IBCM_REF_CNT_INCR(statep); /* for ibcm_post_lap_complete */
4358         }
4359 
4360         mutex_exit(&statep->state_mutex);
4361 
4362         /* No more failure returns below */
4363 
4364         /* Allocate MAD for LAP */
4365         IBTF_DPRINTF_L5(cmlog, "ibt_set_alt_path:"
4366             " statep's mad addr = 0x%p", IBCM_OUT_HDRP(statep->lapr_msg));
4367 


4368         lap_msgp = (ibcm_lap_msg_t *)IBCM_OUT_MSGP(statep->lapr_msg);
4369 
4370         lap_msgp->lap_alt_l_port_lid = h2b16(alternate_slid);
4371         lap_msgp->lap_alt_r_port_lid =
4372             h2b16(alt_path->ap_alt_cep_path.cep_adds_vect.av_dlid);
4373 
4374         /* Fill in remote port gid */
4375         lap_msgp->lap_alt_r_port_gid.gid_prefix =
4376             h2b64(alt_path->ap_alt_cep_path.cep_adds_vect.av_dgid.gid_prefix);
4377         lap_msgp->lap_alt_r_port_gid.gid_guid =
4378             h2b64(alt_path->ap_alt_cep_path.cep_adds_vect.av_dgid.gid_guid);
4379 
4380         /* Fill in local port gid */
4381         lap_msgp->lap_alt_l_port_gid.gid_prefix =
4382             h2b64(alt_path->ap_alt_cep_path.cep_adds_vect.av_sgid.gid_prefix);
4383         lap_msgp->lap_alt_l_port_gid.gid_guid =
4384             h2b64(alt_path->ap_alt_cep_path.cep_adds_vect.av_sgid.gid_guid);
4385 
4386         alt_grh = alt_path->ap_alt_cep_path.cep_adds_vect.av_send_grh;
4387 


4399             alt_path->ap_alt_cep_path.cep_adds_vect.av_srvl << 4 |
4400             ((alt_grh == B_FALSE) ? 0x8 : 0);
4401 
4402         lap_msgp->lap_alt_local_acktime_plus = ibt_usec2ib(
4403             (2 * statep->rc_alt_pkt_lt) +
4404             ibt_ib2usec(hcap->hca_ack_delay)) << 3;
4405 
4406         lap_msgp->lap_local_comm_id = h2b32(statep->local_comid);
4407         lap_msgp->lap_remote_comm_id = h2b32(statep->remote_comid);
4408 
4409         lap_msgp->lap_remote_qpn_eecn_plus =
4410             h2b32((statep->remote_qpn << 8) |
4411             ibt_usec2ib(ibcm_remote_response_time) << 3);
4412 
4413         len = min(priv_data_len, IBT_LAP_PRIV_DATA_SZ);
4414         if ((len > 0) && priv_data) {
4415                 bcopy(priv_data, lap_msgp->lap_private_data, len);
4416         }
4417 
4418         /* only rc_alt_pkt_lt and ap_return_data fields are initialized */


4419         statep->rc_alt_pkt_lt = ibt_ib2usec(alt_path->ap_alt_pkt_lt);
4420 
4421         /* return_data is filled up in the state machine code */
4422         statep->ap_return_data = ret_args;
4423 


4424         IBCM_OUT_HDRP(statep->lapr_msg)->AttributeID =
4425             h2b16(IBCM_INCOMING_LAP + IBCM_ATTR_BASE_ID);
4426 
4427         IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID =
4428             h2b64(ibcm_generate_tranid(IBCM_INCOMING_LAP, statep->local_comid,
4429             0));
4430         IBTF_DPRINTF_L3(cmlog, "ibt_set_alt_path: statep %p, tid %llx",
4431             statep, IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID);
4432 


4433         /* Send LAP */
4434         ibcm_post_rc_mad(statep, statep->lapr_msg, ibcm_post_lap_complete,
4435             statep);
4436 
4437         mutex_enter(&statep->state_mutex);
4438 
4439         if (mode == IBT_BLOCKING) {
4440                 IBTF_DPRINTF_L4(cmlog, "ibt_set_alt_path: blocking");
4441 
4442                 /* wait for APR */
4443                 while (statep->ap_done != B_TRUE) {
4444                         cv_wait(&statep->block_client_cv,
4445                             &statep->state_mutex);
4446                 }
4447 
4448                 IBTF_DPRINTF_L4(cmlog, "ibt_set_alt_path: done blocking");
4449 
4450                 /*
4451                  * In the case that ibt_set_alt_path fails,
4452                  * change retval to IBT_CM_FAILURE


4563             cm_reply_addr->grh_hdr.ig_flow_label,
4564             cm_reply_addr->grh_hdr.ig_tclass,
4565             cm_reply_addr->grh_hdr.ig_hop_limit);
4566 }
4567 
4568 #endif
4569 
4570 /* For MCG List search */
4571 typedef struct ibcm_mcg_list_s {
4572         struct ibcm_mcg_list_s  *ml_next;
4573         ib_gid_t                ml_sgid;
4574         ib_gid_t                ml_mgid;
4575         ib_pkey_t               ml_pkey;
4576         ib_qkey_t               ml_qkey;
4577         uint_t                  ml_refcnt;
4578         uint8_t                 ml_jstate;
4579 } ibcm_mcg_list_t;
4580 
4581 ibcm_mcg_list_t *ibcm_mcglist = NULL;
4582 



4583 typedef struct ibcm_join_mcg_tqarg_s {
4584         ib_gid_t                rgid;
4585         ibt_mcg_attr_t          mcg_attr;
4586         ibt_mcg_info_t          *mcg_infop;
4587         ibt_mcg_handler_t       func;
4588         void                    *arg;
4589 } ibcm_join_mcg_tqarg_t;
4590 


4591 void
4592 ibcm_add_incr_mcg_entry(sa_mcmember_record_t *mcg_req,
4593     sa_mcmember_record_t *mcg_resp)
4594 {
4595         ibcm_mcg_list_t *new = NULL;
4596         ibcm_mcg_list_t *head = NULL;
4597 
4598         IBTF_DPRINTF_L3(cmlog, "ibcm_add_incr_mcg_entry: MGID %llX:%llX"
4599             "\n SGID %llX:%llX, JState %X)", mcg_req->MGID.gid_prefix,
4600             mcg_req->MGID.gid_guid, mcg_req->PortGID.gid_prefix,
4601             mcg_req->PortGID.gid_guid, mcg_req->JoinState);
4602 
4603         mutex_enter(&ibcm_mcglist_lock);
4604         head = ibcm_mcglist;
4605 
4606         while (head != NULL) {
4607                 if ((head->ml_mgid.gid_guid == mcg_resp->MGID.gid_guid) &&
4608                     (head->ml_mgid.gid_prefix == mcg_resp->MGID.gid_prefix) &&
4609                     (head->ml_sgid.gid_guid == mcg_resp->PortGID.gid_guid)) {
4610                         /* Increment the count */


4767                 IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: Request GID is required");
4768                 return (IBT_INVALID_PARAM);
4769         }
4770 
4771         if ((mcg_attr->mc_pkey == IB_PKEY_INVALID_LIMITED) ||
4772             (mcg_attr->mc_pkey == IB_PKEY_INVALID_FULL)) {
4773                 IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: Invalid P_Key specified");
4774                 return (IBT_INVALID_PARAM);
4775         }
4776 
4777         if (mcg_attr->mc_join_state == 0) {
4778                 IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: JoinState not specified");
4779                 return (IBT_INVALID_PARAM);
4780         }
4781 
4782         if (mcg_info_p == NULL) {
4783                 IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: mcg_info_p is NULL");
4784                 return (IBT_INVALID_PARAM);
4785         }
4786 


4787         mcg_tq = kmem_alloc(sizeof (ibcm_join_mcg_tqarg_t), flag);
4788         if (mcg_tq == NULL) {
4789                 IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: "
4790                     "Unable to allocate memory for local usage.");
4791                 return (IBT_INSUFF_KERNEL_RESOURCE);
4792         }
4793 
4794         mcg_tq->rgid = rgid;
4795         bcopy(mcg_attr, &mcg_tq->mcg_attr, sizeof (ibt_mcg_attr_t));
4796         mcg_tq->mcg_infop = mcg_info_p;
4797         mcg_tq->func = func;
4798         mcg_tq->arg = arg;
4799 


4800         if (func != NULL) {     /* Non-Blocking */
4801                 IBTF_DPRINTF_L3(cmlog, "ibt_join_mcg: Non-Blocking Call");
4802                 if (taskq_dispatch(ibcm_taskq, ibcm_process_async_join_mcg,
4803                     mcg_tq, TQ_NOSLEEP) == 0) {
4804                         IBTF_DPRINTF_L2(cmlog, "ibt_join_mcg: Failed to "
4805                             "Dispatch the TaskQ");
4806                         kmem_free(mcg_tq, sizeof (ibcm_join_mcg_tqarg_t));
4807                         return (IBT_INSUFF_KERNEL_RESOURCE);
4808                 } else
4809                         return (IBT_SUCCESS);
4810         } else {                /* Blocking */
4811                 return (ibcm_process_join_mcg(mcg_tq));
4812         }
4813 }
4814 
4815 static void
4816 ibcm_process_async_join_mcg(void *tq_arg)
4817 {
4818         (void) ibcm_process_join_mcg(tq_arg);
4819 }


5716                             SA_NODEINFO_COMPMASK_NODELID, &res_p, &len);
5717                         if (retval == IBT_NODE_RECORDS_NOT_FOUND) {
5718                                 IBTF_DPRINTF_L2(cmlog, "ibt_gid_to_node_info: "
5719                                     "failed (%d) to get Node records", retval);
5720                                 continue;
5721                         } else if (retval != IBT_SUCCESS) {
5722                                 IBTF_DPRINTF_L2(cmlog, "ibt_gid_to_node_info: "
5723                                     "failed (%d) to get Node records", retval);
5724                                 ibcm_dec_hca_acc_cnt(hcap);
5725                                 goto gid_to_ni_exit;
5726                         }
5727 
5728                         num_rec = len/sizeof (sa_node_record_t);
5729                         nr_resp = (sa_node_record_t *)(uchar_t *)res_p;
5730 
5731                         /* Validate the returned number of records. */
5732                         if ((nr_resp != NULL) && (num_rec > 0)) {
5733 
5734                                 IBCM_DUMP_NODE_REC(nr_resp);
5735 



5736                                 node_info_p->n_sys_img_guid =
5737                                     nr_resp->NodeInfo.SystemImageGUID;
5738                                 node_info_p->n_node_guid =
5739                                     nr_resp->NodeInfo.NodeGUID;
5740                                 node_info_p->n_port_guid =
5741                                     nr_resp->NodeInfo.PortGUID;
5742                                 node_info_p->n_dev_id =
5743                                     nr_resp->NodeInfo.DeviceID;
5744                                 node_info_p->n_revision =
5745                                     nr_resp->NodeInfo.Revision;
5746                                 node_info_p->n_vendor_id =
5747                                     nr_resp->NodeInfo.VendorID;
5748                                 node_info_p->n_num_ports =
5749                                     nr_resp->NodeInfo.NumPorts;
5750                                 node_info_p->n_port_num =
5751                                     nr_resp->NodeInfo.LocalPortNum;
5752                                 node_info_p->n_node_type =
5753                                     nr_resp->NodeInfo.NodeType;
5754                                 (void) strncpy(node_info_p->n_description,
5755                                     (char *)&nr_resp->NodeDescription, 64);
5756 



5757                                 /*
5758                                  * Deallocate the memory allocated by SA for
5759                                  * 'nr_resp'.
5760                                  */
5761                                 ibcm_dec_hca_acc_cnt(hcap);
5762                                 kmem_free(nr_resp, len);
5763                                 retval = IBT_SUCCESS;
5764 
5765                                 goto gid_to_ni_exit;
5766                         } else {
5767                                 retval = IBT_NODE_RECORDS_NOT_FOUND;
5768                                 IBTF_DPRINTF_L3(cmlog, "ibt_gid_to_node_info: "
5769                                     "Node Records NOT found - PortGUID %016llX",
5770                                     gid.gid_guid);
5771                         }
5772                 }
5773                 ibcm_dec_hca_acc_cnt(hcap);
5774 
5775                 if (local_node == B_TRUE)
5776                         break;


5908                             SA_NODEINFO_COMPMASK_NODELID, &res_p, &len);
5909                         if (retval == IBT_NODE_RECORDS_NOT_FOUND) {
5910                                 IBTF_DPRINTF_L2(cmlog, "ibt_lid_to_node_info: "
5911                                     "failed (%d) to get Node records", retval);
5912                                 continue;
5913                         } else if (retval != IBT_SUCCESS) {
5914                                 IBTF_DPRINTF_L2(cmlog, "ibt_lid_to_node_info: "
5915                                     "failed (%d) to get Node records", retval);
5916                                 ibcm_dec_hca_acc_cnt(hcap);
5917                                 goto lid_to_ni_exit;
5918                         }
5919 
5920                         num_rec = len/sizeof (sa_node_record_t);
5921                         nr_resp = (sa_node_record_t *)(uchar_t *)res_p;
5922 
5923                         /* Validate the returned number of records. */
5924                         if ((nr_resp != NULL) && (num_rec > 0)) {
5925 
5926                                 IBCM_DUMP_NODE_REC(nr_resp);
5927 



5928                                 node_info_p->n_sys_img_guid =
5929                                     nr_resp->NodeInfo.SystemImageGUID;
5930                                 node_info_p->n_node_guid =
5931                                     nr_resp->NodeInfo.NodeGUID;
5932                                 node_info_p->n_port_guid =
5933                                     nr_resp->NodeInfo.PortGUID;
5934                                 node_info_p->n_dev_id =
5935                                     nr_resp->NodeInfo.DeviceID;
5936                                 node_info_p->n_revision =
5937                                     nr_resp->NodeInfo.Revision;
5938                                 node_info_p->n_vendor_id =
5939                                     nr_resp->NodeInfo.VendorID;
5940                                 node_info_p->n_num_ports =
5941                                     nr_resp->NodeInfo.NumPorts;
5942                                 node_info_p->n_port_num =
5943                                     nr_resp->NodeInfo.LocalPortNum;
5944                                 node_info_p->n_node_type =
5945                                     nr_resp->NodeInfo.NodeType;
5946                                 (void) strncpy(node_info_p->n_description,
5947                                     (char *)&nr_resp->NodeDescription, 64);
5948 



5949                                 /*
5950                                  * Deallocate the memory allocated by SA for
5951                                  * 'nr_resp'.
5952                                  */
5953                                 ibcm_dec_hca_acc_cnt(hcap);
5954                                 kmem_free(nr_resp, len);
5955                                 retval = IBT_SUCCESS;
5956 
5957                                 goto lid_to_ni_exit;
5958                         } else {
5959                                 retval = IBT_NODE_RECORDS_NOT_FOUND;
5960                                 IBTF_DPRINTF_L3(cmlog, "ibt_lid_to_node_info: "
5961                                     "Node Records NOT found - LID 0x%lX",
5962                                     lid);
5963                         }
5964                 }
5965                 ibcm_dec_hca_acc_cnt(hcap);
5966         }
5967 
5968 lid_to_ni_exit:


6447                 *src_info_p = s_ip;
6448                 *entries_p = count;
6449 
6450                 j = 0;
6451                 for (i = 0, ipp = ibds.ibcm_arp_ip; i < ibds.ibcm_arp_ibd_cnt;
6452                     i++, ipp++) {
6453                         if (ipp->ip_inet_family == AF_UNSPEC)
6454                                 continue;
6455                         if ((ipp->ip_port_gid.gid_prefix ==
6456                             sattr->sip_gid.gid_prefix) &&
6457                             (ipp->ip_port_gid.gid_guid ==
6458                             sattr->sip_gid.gid_guid)) {
6459                                 if ((sattr->sip_pkey) &&
6460                                     (ipp->ip_pkey != sattr->sip_pkey))
6461                                         continue;
6462 
6463                                 if ((sattr->sip_zoneid != ALL_ZONES) &&
6464                                     (sattr->sip_zoneid != ipp->ip_zoneid))
6465                                         continue;
6466 

6467                                 s_ip[j].ip_addr.family = ipp->ip_inet_family;

6468                                 if (s_ip[j].ip_addr.family == AF_INET) {
6469                                         bcopy(&ipp->ip_cm_sin.sin_addr,
6470                                             &s_ip[j].ip_addr.un.ip4addr,
6471                                             sizeof (in_addr_t));
6472                                 } else if (s_ip[j].ip_addr.family == AF_INET6) {
6473                                         bcopy(&ipp->ip_cm_sin6.sin6_addr,
6474                                             &s_ip[j].ip_addr.un.ip6addr,
6475                                             sizeof (in6_addr_t));
6476                                         /* TBD: scope_id */
6477                                 }
6478                                 IBCM_PRINT_IP("ibt_get_src_ip",
6479                                     &s_ip[j].ip_addr);
6480                                 j++;
6481                         }
6482                 }
6483         } else {
6484                 retval = IBT_SRC_IP_NOT_FOUND;
6485         }
6486 
6487 get_src_ip_end:


6557         }
6558 
6559         ibcm_free_ip_sid(ip_sid);
6560 
6561         return (IBT_SUCCESS);
6562 }
6563 
6564 
6565 uint8_t
6566 ibt_get_ip_protocol_num(ib_svc_id_t sid)
6567 {
6568         return ((sid & IB_SID_IPADDR_IPNUM_MASK) >> 16);
6569 }
6570 
6571 in_port_t
6572 ibt_get_ip_dst_port(ib_svc_id_t sid)
6573 {
6574         return (sid & IB_SID_IPADDR_PORTNUM_MASK);
6575 }
6576 



6577 ibt_status_t
6578 ibt_format_ip_private_data(ibt_ip_cm_info_t *ip_cm_info,
6579     ibt_priv_data_len_t priv_data_len, void *priv_data_p)
6580 {
6581         ibcm_ip_pvtdata_t       ip_data;
6582 
6583         IBTF_DPRINTF_L4(cmlog, "ibt_format_ip_private_data(%p, %d, %p)",
6584             ip_cm_info, priv_data_len, priv_data_p);
6585 
6586         if ((ip_cm_info == NULL) || (priv_data_p == NULL) ||
6587             (priv_data_len < IBT_IP_HDR_PRIV_DATA_SZ)) {
6588                 IBTF_DPRINTF_L2(cmlog, "ibt_format_ip_private_data: ERROR "
6589                     "Invalid Inputs.");
6590                 return (IBT_INVALID_PARAM);
6591         }
6592 
6593         bzero(&ip_data, sizeof (ibcm_ip_pvtdata_t));
6594         ip_data.ip_srcport = ip_cm_info->src_port; /* Source Port */
6595 
6596         IBCM_PRINT_IP("format_ip_pvt: src", &ip_cm_info->src_addr);


6646                     AF_INET;
6647                 ip_cm_infop->src_addr.un.ip4addr = ip_data.ip_srcv4;
6648                 ip_cm_infop->dst_addr.un.ip4addr = ip_data.ip_dstv4;
6649         } else if (ip_data.ip_ipv == IBT_CM_IP_IPV_V6) {
6650                 /* Copy IPv6 Addr */
6651                 ip_cm_infop->src_addr.family = ip_cm_infop->dst_addr.family =
6652                     AF_INET6;
6653                 bcopy(&ip_data.ip_srcv6, &ip_cm_infop->src_addr.un.ip6addr,
6654                     sizeof (in6_addr_t));
6655                 bcopy(&ip_data.ip_dstv6, &ip_cm_infop->dst_addr.un.ip6addr,
6656                     sizeof (in6_addr_t));
6657         } else {
6658                 IBTF_DPRINTF_L2(cmlog, "ibt_get_ip_data: ERROR: IP Addr needs"
6659                     " to be either AF_INET or AF_INET6 family.");
6660                 return (IBT_INVALID_PARAM);
6661         }
6662         IBCM_PRINT_IP("ibt_get_ip_data: src", &ip_cm_infop->src_addr);
6663         IBCM_PRINT_IP("ibt_get_ip_data: dst", &ip_cm_infop->dst_addr);
6664 
6665         return (IBT_SUCCESS);









































































6666 }