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


  74         ib_qpn_t                        *qpn;
  75         hermon_qphdl_t                  *qphdl;
  76         ibt_mr_attr_t                   mr_attr;
  77         hermon_mr_options_t             mr_op;
  78         hermon_srqhdl_t                 srq;
  79         hermon_pdhdl_t                  pd;
  80         hermon_cqhdl_t                  sq_cq, rq_cq;
  81         hermon_mrhdl_t                  mr;
  82         uint64_t                        value, qp_desc_off;
  83         uint64_t                        *thewqe, thewqesz;
  84         uint32_t                        *sq_buf, *rq_buf;
  85         uint32_t                        log_qp_sq_size, log_qp_rq_size;
  86         uint32_t                        sq_size, rq_size;
  87         uint32_t                        sq_depth, rq_depth;
  88         uint32_t                        sq_wqe_size, rq_wqe_size, wqesz_shift;
  89         uint32_t                        max_sgl, max_recv_sgl, uarpg;
  90         uint_t                          qp_is_umap;
  91         uint_t                          qp_srq_en, i, j;
  92         int                             status, flag;
  93 
  94         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*attr_p, *queuesz_p))
  95 
  96         /*
  97          * Extract the necessary info from the hermon_qp_info_t structure
  98          */
  99         attr_p    = qpinfo->qpi_attrp;
 100         type      = qpinfo->qpi_type;
 101         ibt_qphdl = qpinfo->qpi_ibt_qphdl;
 102         queuesz_p = qpinfo->qpi_queueszp;
 103         qpn       = qpinfo->qpi_qpn;
 104         qphdl     = &qpinfo->qpi_qphdl;
 105         alloc_flags = attr_p->qp_alloc_flags;
 106 
 107         /*
 108          * Verify correctness of alloc_flags.
 109          *
 110          * 1. FEXCH and RSS are only allocated via qp_range.
 111          */
 112         if (alloc_flags & (IBT_QP_USES_FEXCH | IBT_QP_USES_RSS)) {
 113                 return (IBT_INVALID_PARAM);
 114         }
 115         rsrc_type = HERMON_QPC;


 255          * the reference count (CQ and PD).
 256          */
 257         status = hermon_rsrc_alloc(state, rsrc_type, 1, sleepflag, &qpc);
 258         if (status != DDI_SUCCESS) {
 259                 status = IBT_INSUFF_RESOURCE;
 260                 goto qpalloc_fail3;
 261         }
 262 
 263         /*
 264          * Allocate the software structure for tracking the queue pair
 265          * (i.e. the Hermon Queue Pair handle).  If we fail here, we must
 266          * undo the reference counts and the previous resource allocation.
 267          */
 268         status = hermon_rsrc_alloc(state, HERMON_QPHDL, 1, sleepflag, &rsrc);
 269         if (status != DDI_SUCCESS) {
 270                 status = IBT_INSUFF_RESOURCE;
 271                 goto qpalloc_fail4;
 272         }
 273         qp = (hermon_qphdl_t)rsrc->hr_addr;
 274         bzero(qp, sizeof (struct hermon_sw_qp_s));
 275         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*qp))
 276 
 277         qp->qp_alloc_flags = alloc_flags;
 278 
 279         /*
 280          * Calculate the QP number from QPC index.  This routine handles
 281          * all of the operations necessary to keep track of used, unused,
 282          * and released QP numbers.
 283          */
 284         if (type == IBT_UD_RQP) {
 285                 qp->qp_qpnum = qpc->hr_indx;
 286                 qp->qp_ring = qp->qp_qpnum << 8;
 287                 qp->qp_qpn_hdl = NULL;
 288         } else {
 289                 status = hermon_qp_create_qpn(state, qp, qpc);
 290                 if (status != DDI_SUCCESS) {
 291                         status = IBT_INSUFF_RESOURCE;
 292                         goto qpalloc_fail5;
 293                 }
 294         }
 295 


 869          */
 870         status = hermon_special_qp_rsrc_alloc(state, type, port, &qpc);
 871         if (status != DDI_SUCCESS) {
 872                 goto spec_qpalloc_fail3;
 873         }
 874 
 875         /*
 876          * Allocate the software structure for tracking the special queue
 877          * pair (i.e. the Hermon Queue Pair handle).  If we fail here, we
 878          * must undo the reference counts and the previous resource allocation.
 879          */
 880         status = hermon_rsrc_alloc(state, HERMON_QPHDL, 1, sleepflag, &rsrc);
 881         if (status != DDI_SUCCESS) {
 882                 status = IBT_INSUFF_RESOURCE;
 883                 goto spec_qpalloc_fail4;
 884         }
 885         qp = (hermon_qphdl_t)rsrc->hr_addr;
 886 
 887         bzero(qp, sizeof (struct hermon_sw_qp_s));
 888 
 889         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*qp))
 890         qp->qp_alloc_flags = attr_p->qp_alloc_flags;
 891 
 892         /*
 893          * Actual QP number is a combination of the index of the QPC and
 894          * the port number.  This is because the special QP contexts must
 895          * be allocated two-at-a-time.
 896          */
 897         qp->qp_qpnum = qpc->hr_indx + port;
 898         qp->qp_ring = qp->qp_qpnum << 8;
 899 
 900         uarpg = state->hs_kernel_uar_index; /* must be for spec qp */
 901         /*
 902          * Allocate the doorbell record.  Hermon uses only one for the RQ so
 903          * alloc a qp doorbell, using uarpg (above) as the uar index
 904          */
 905 
 906         status = hermon_dbr_alloc(state, uarpg, &qp->qp_rq_dbr_acchdl,
 907             &qp->qp_rq_vdbr, &qp->qp_rq_pdbr, &qp->qp_rdbr_mapoffset);
 908         if (status != DDI_SUCCESS) {
 909                 status = IBT_INSUFF_RESOURCE;


1235         ibt_chan_sizes_t                *queuesz_p;
1236         ibt_mr_attr_t                   mr_attr;
1237         hermon_mr_options_t             mr_op;
1238         hermon_srqhdl_t                 srq;
1239         hermon_pdhdl_t                  pd;
1240         hermon_cqhdl_t                  sq_cq, rq_cq;
1241         hermon_mrhdl_t                  mr;
1242         uint64_t                        qp_desc_off;
1243         uint64_t                        *thewqe, thewqesz;
1244         uint32_t                        *sq_buf, *rq_buf;
1245         uint32_t                        log_qp_sq_size, log_qp_rq_size;
1246         uint32_t                        sq_size, rq_size;
1247         uint32_t                        sq_depth, rq_depth;
1248         uint32_t                        sq_wqe_size, rq_wqe_size, wqesz_shift;
1249         uint32_t                        max_sgl, max_recv_sgl, uarpg;
1250         uint_t                          qp_srq_en, i, j;
1251         int                             ii;     /* loop counter for range */
1252         int                             status, flag;
1253         uint_t                          serv_type;
1254 
1255         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*attr_p, *queuesz_p))
1256 
1257         /*
1258          * Extract the necessary info from the hermon_qp_info_t structure
1259          */
1260         attr_p    = qpinfo->qpi_attrp;
1261         type      = qpinfo->qpi_type;
1262         queuesz_p = qpinfo->qpi_queueszp;
1263 
1264         if (attr_p->qp_alloc_flags & IBT_QP_USES_RSS) {
1265                 if (log2 > state->hs_ibtfinfo.hca_attr->hca_rss_max_log2_table)
1266                         return (IBT_INSUFF_RESOURCE);
1267                 rsrc_type = HERMON_QPC;
1268                 serv_type = HERMON_QP_UD;
1269         } else if (attr_p->qp_alloc_flags & IBT_QP_USES_FEXCH) {
1270                 if (log2 > state->hs_ibtfinfo.hca_attr->hca_fexch_max_log2_qp)
1271                         return (IBT_INSUFF_RESOURCE);
1272                 switch (attr_p->qp_fc.fc_hca_port) {
1273                 case 1:
1274                         rsrc_type = HERMON_QPC_FEXCH_PORT1;
1275                         break;
1276                 case 2:


1401                 goto qpalloc_fail1;
1402         }
1403         status = hermon_cq_refcnt_inc(rq_cq, HERMON_CQ_IS_NORMAL);
1404         if (status != DDI_SUCCESS) {
1405                 status = IBT_CQ_HDL_INVALID;
1406                 goto qpalloc_fail2;
1407         }
1408 
1409         /*
1410          * Allocate the software structure for tracking the queue pair
1411          * (i.e. the Hermon Queue Pair handle).  If we fail here, we must
1412          * undo the reference counts and the previous resource allocation.
1413          */
1414         status = hermon_rsrc_alloc(state, HERMON_QPHDL, 1, sleepflag, &rsrc);
1415         if (status != DDI_SUCCESS) {
1416                 status = IBT_INSUFF_RESOURCE;
1417                 goto qpalloc_fail4;
1418         }
1419         qp = (hermon_qphdl_t)rsrc->hr_addr;
1420         bzero(qp, sizeof (struct hermon_sw_qp_s));
1421         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*qp))
1422         qp->qp_alloc_flags = attr_p->qp_alloc_flags;
1423 
1424         /*
1425          * Calculate the QP number from QPC index.  This routine handles
1426          * all of the operations necessary to keep track of used, unused,
1427          * and released QP numbers.
1428          */
1429         qp->qp_qpnum = qpc->hr_indx + ii;
1430         qp->qp_ring = qp->qp_qpnum << 8;
1431         qp->qp_qpn_hdl = NULL;
1432 
1433         /*
1434          * Allocate the doorbell record.  Hermon just needs one for the RQ,
1435          * if the QP is not associated with an SRQ, and use uarpg (above) as
1436          * the uar index
1437          */
1438 
1439         if (!qp_srq_en) {
1440                 status = hermon_dbr_alloc(state, uarpg, &qp->qp_rq_dbr_acchdl,
1441                     &qp->qp_rq_vdbr, &qp->qp_rq_pdbr, &qp->qp_rdbr_mapoffset);


1973         if (qpc == NULL) {
1974                 hermon_icm_set_num_to_hdl(state, HERMON_QPC,
1975                     qp->qp_qpnum, NULL);
1976         } else if (qp->qp_is_special) {
1977                 hermon_icm_set_num_to_hdl(state, HERMON_QPC,
1978                     qpc->hr_indx + port, NULL);
1979         } else {
1980                 hermon_icm_set_num_to_hdl(state, HERMON_QPC,
1981                     qpc->hr_indx, NULL);
1982         }
1983 
1984         /*
1985          * Drop the QP lock
1986          *    At this point the lock is no longer necessary.  We cannot
1987          *    protect from multiple simultaneous calls to free the same QP.
1988          *    In addition, since the QP lock is contained in the QP "software
1989          *    handle" resource, which we will free (see below), it is
1990          *    important that we have no further references to that memory.
1991          */
1992         mutex_exit(&qp->qp_lock);
1993         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*qp))
1994 
1995         /*
1996          * Free the QP resources
1997          *    Start by deregistering and freeing the memory for work queues.
1998          *    Next free any previously allocated context information
1999          *    (depending on QP type)
2000          *    Finally, decrement the necessary reference counts.
2001          * If this fails for any reason, then it is an indication that
2002          * something (either in HW or SW) has gone seriously wrong.  So we
2003          * print a warning message and return.
2004          */
2005         status = hermon_mr_deregister(state, &mr, HERMON_MR_DEREG_ALL,
2006             sleepflag);
2007         if (status != DDI_SUCCESS) {
2008                 HERMON_WARNING(state, "failed to deregister QP memory");
2009                 status = ibc_get_ci_failure(0);
2010                 goto qpfree_fail;
2011         }
2012 
2013         /* Free the memory for the QP */


2212         /*
2213          * Fill in the additional QP info based on the QP's transport type.
2214          */
2215         if (qp->qp_type == IBT_UD_RQP) {
2216 
2217                 /* Fill in the UD-specific info */
2218                 ud = &attr_p->qp_info.qp_transport.ud;
2219                 ud->ud_qkey  = (ib_qkey_t)qpc->qkey;
2220                 ud->ud_sq_psn        = qpc->next_snd_psn;
2221                 ud->ud_pkey_ix       = qpc->pri_addr_path.pkey_indx;
2222                 /* port+1 for port 1/2 */
2223                 ud->ud_port  =
2224                     (uint8_t)(((qpc->pri_addr_path.sched_q >> 6) & 0x01) + 1);
2225 
2226                 attr_p->qp_info.qp_trans = IBT_UD_SRV;
2227 
2228                 if (qp->qp_serv_type == HERMON_QP_FEXCH) {
2229                         ibt_pmr_desc_t *pmr;
2230                         uint64_t heart_beat;
2231 
2232                         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*pmr))
2233                         pmr = &attr_p->qp_query_fexch.fq_uni_mem_desc;
2234                         pmr->pmd_iova = 0;
2235                         pmr->pmd_lkey = pmr->pmd_rkey =
2236                             hermon_fcoib_qpn_to_mkey(state, qp->qp_qpnum);
2237                         pmr->pmd_phys_buf_list_sz =
2238                             state->hs_fcoib.hfc_mtts_per_mpt;
2239                         pmr->pmd_sync_required = 0;
2240 
2241                         pmr = &attr_p->qp_query_fexch.fq_bi_mem_desc;
2242                         pmr->pmd_iova = 0;
2243                         pmr->pmd_lkey = 0;
2244                         pmr->pmd_rkey = 0;
2245                         pmr->pmd_phys_buf_list_sz = 0;
2246                         pmr->pmd_sync_required = 0;
2247 
2248                         attr_p->qp_query_fexch.fq_flags =
2249                             ((hermon_get_heart_beat_rq_cmd_post(state,
2250                             qp->qp_qpnum, &heart_beat) == HERMON_CMD_SUCCESS) &&
2251                             (heart_beat == 0)) ? IBT_FEXCH_HEART_BEAT_OK :
2252                             IBT_FEXCH_NO_FLAGS;


2414          * no matching entry is found, then allocate, initialize, and
2415          * add an entry to the AVL tree.
2416          * If a matching entry is found, then increment its QPN counter
2417          * and reference counter.
2418          */
2419         query.qpn_indx = qpc->hr_indx;
2420         mutex_enter(&state->hs_qpn_avl_lock);
2421         entry = (hermon_qpn_entry_t *)avl_find(&state->hs_qpn_avl,
2422             &query, &where);
2423         if (entry == NULL) {
2424                 /*
2425                  * Allocate and initialize a QPN entry, then insert
2426                  * it into the AVL tree.
2427                  */
2428                 entry = (hermon_qpn_entry_t *)kmem_zalloc(
2429                     sizeof (hermon_qpn_entry_t), KM_NOSLEEP);
2430                 if (entry == NULL) {
2431                         mutex_exit(&state->hs_qpn_avl_lock);
2432                         return (DDI_FAILURE);
2433                 }
2434                 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*entry))
2435 
2436                 entry->qpn_indx         = qpc->hr_indx;
2437                 entry->qpn_refcnt  = 0;
2438                 entry->qpn_counter = 0;
2439 
2440                 avl_insert(&state->hs_qpn_avl, entry, where);
2441         }
2442 
2443         /*
2444          * Make the AVL tree entry point to the QP context resource that
2445          * it will be responsible for tracking
2446          */
2447         entry->qpn_qpc = qpc;
2448 
2449         /*
2450          * Setup the QP handle to point to the AVL tree entry.  Then
2451          * generate the new QP number from the entry's QPN counter value
2452          * and the hardware's QP context table index.
2453          */
2454         qp->qp_qpn_hdl       = entry;




  74         ib_qpn_t                        *qpn;
  75         hermon_qphdl_t                  *qphdl;
  76         ibt_mr_attr_t                   mr_attr;
  77         hermon_mr_options_t             mr_op;
  78         hermon_srqhdl_t                 srq;
  79         hermon_pdhdl_t                  pd;
  80         hermon_cqhdl_t                  sq_cq, rq_cq;
  81         hermon_mrhdl_t                  mr;
  82         uint64_t                        value, qp_desc_off;
  83         uint64_t                        *thewqe, thewqesz;
  84         uint32_t                        *sq_buf, *rq_buf;
  85         uint32_t                        log_qp_sq_size, log_qp_rq_size;
  86         uint32_t                        sq_size, rq_size;
  87         uint32_t                        sq_depth, rq_depth;
  88         uint32_t                        sq_wqe_size, rq_wqe_size, wqesz_shift;
  89         uint32_t                        max_sgl, max_recv_sgl, uarpg;
  90         uint_t                          qp_is_umap;
  91         uint_t                          qp_srq_en, i, j;
  92         int                             status, flag;
  93 


  94         /*
  95          * Extract the necessary info from the hermon_qp_info_t structure
  96          */
  97         attr_p    = qpinfo->qpi_attrp;
  98         type      = qpinfo->qpi_type;
  99         ibt_qphdl = qpinfo->qpi_ibt_qphdl;
 100         queuesz_p = qpinfo->qpi_queueszp;
 101         qpn       = qpinfo->qpi_qpn;
 102         qphdl     = &qpinfo->qpi_qphdl;
 103         alloc_flags = attr_p->qp_alloc_flags;
 104 
 105         /*
 106          * Verify correctness of alloc_flags.
 107          *
 108          * 1. FEXCH and RSS are only allocated via qp_range.
 109          */
 110         if (alloc_flags & (IBT_QP_USES_FEXCH | IBT_QP_USES_RSS)) {
 111                 return (IBT_INVALID_PARAM);
 112         }
 113         rsrc_type = HERMON_QPC;


 253          * the reference count (CQ and PD).
 254          */
 255         status = hermon_rsrc_alloc(state, rsrc_type, 1, sleepflag, &qpc);
 256         if (status != DDI_SUCCESS) {
 257                 status = IBT_INSUFF_RESOURCE;
 258                 goto qpalloc_fail3;
 259         }
 260 
 261         /*
 262          * Allocate the software structure for tracking the queue pair
 263          * (i.e. the Hermon Queue Pair handle).  If we fail here, we must
 264          * undo the reference counts and the previous resource allocation.
 265          */
 266         status = hermon_rsrc_alloc(state, HERMON_QPHDL, 1, sleepflag, &rsrc);
 267         if (status != DDI_SUCCESS) {
 268                 status = IBT_INSUFF_RESOURCE;
 269                 goto qpalloc_fail4;
 270         }
 271         qp = (hermon_qphdl_t)rsrc->hr_addr;
 272         bzero(qp, sizeof (struct hermon_sw_qp_s));

 273 
 274         qp->qp_alloc_flags = alloc_flags;
 275 
 276         /*
 277          * Calculate the QP number from QPC index.  This routine handles
 278          * all of the operations necessary to keep track of used, unused,
 279          * and released QP numbers.
 280          */
 281         if (type == IBT_UD_RQP) {
 282                 qp->qp_qpnum = qpc->hr_indx;
 283                 qp->qp_ring = qp->qp_qpnum << 8;
 284                 qp->qp_qpn_hdl = NULL;
 285         } else {
 286                 status = hermon_qp_create_qpn(state, qp, qpc);
 287                 if (status != DDI_SUCCESS) {
 288                         status = IBT_INSUFF_RESOURCE;
 289                         goto qpalloc_fail5;
 290                 }
 291         }
 292 


 866          */
 867         status = hermon_special_qp_rsrc_alloc(state, type, port, &qpc);
 868         if (status != DDI_SUCCESS) {
 869                 goto spec_qpalloc_fail3;
 870         }
 871 
 872         /*
 873          * Allocate the software structure for tracking the special queue
 874          * pair (i.e. the Hermon Queue Pair handle).  If we fail here, we
 875          * must undo the reference counts and the previous resource allocation.
 876          */
 877         status = hermon_rsrc_alloc(state, HERMON_QPHDL, 1, sleepflag, &rsrc);
 878         if (status != DDI_SUCCESS) {
 879                 status = IBT_INSUFF_RESOURCE;
 880                 goto spec_qpalloc_fail4;
 881         }
 882         qp = (hermon_qphdl_t)rsrc->hr_addr;
 883 
 884         bzero(qp, sizeof (struct hermon_sw_qp_s));
 885 

 886         qp->qp_alloc_flags = attr_p->qp_alloc_flags;
 887 
 888         /*
 889          * Actual QP number is a combination of the index of the QPC and
 890          * the port number.  This is because the special QP contexts must
 891          * be allocated two-at-a-time.
 892          */
 893         qp->qp_qpnum = qpc->hr_indx + port;
 894         qp->qp_ring = qp->qp_qpnum << 8;
 895 
 896         uarpg = state->hs_kernel_uar_index; /* must be for spec qp */
 897         /*
 898          * Allocate the doorbell record.  Hermon uses only one for the RQ so
 899          * alloc a qp doorbell, using uarpg (above) as the uar index
 900          */
 901 
 902         status = hermon_dbr_alloc(state, uarpg, &qp->qp_rq_dbr_acchdl,
 903             &qp->qp_rq_vdbr, &qp->qp_rq_pdbr, &qp->qp_rdbr_mapoffset);
 904         if (status != DDI_SUCCESS) {
 905                 status = IBT_INSUFF_RESOURCE;


1231         ibt_chan_sizes_t                *queuesz_p;
1232         ibt_mr_attr_t                   mr_attr;
1233         hermon_mr_options_t             mr_op;
1234         hermon_srqhdl_t                 srq;
1235         hermon_pdhdl_t                  pd;
1236         hermon_cqhdl_t                  sq_cq, rq_cq;
1237         hermon_mrhdl_t                  mr;
1238         uint64_t                        qp_desc_off;
1239         uint64_t                        *thewqe, thewqesz;
1240         uint32_t                        *sq_buf, *rq_buf;
1241         uint32_t                        log_qp_sq_size, log_qp_rq_size;
1242         uint32_t                        sq_size, rq_size;
1243         uint32_t                        sq_depth, rq_depth;
1244         uint32_t                        sq_wqe_size, rq_wqe_size, wqesz_shift;
1245         uint32_t                        max_sgl, max_recv_sgl, uarpg;
1246         uint_t                          qp_srq_en, i, j;
1247         int                             ii;     /* loop counter for range */
1248         int                             status, flag;
1249         uint_t                          serv_type;
1250 


1251         /*
1252          * Extract the necessary info from the hermon_qp_info_t structure
1253          */
1254         attr_p    = qpinfo->qpi_attrp;
1255         type      = qpinfo->qpi_type;
1256         queuesz_p = qpinfo->qpi_queueszp;
1257 
1258         if (attr_p->qp_alloc_flags & IBT_QP_USES_RSS) {
1259                 if (log2 > state->hs_ibtfinfo.hca_attr->hca_rss_max_log2_table)
1260                         return (IBT_INSUFF_RESOURCE);
1261                 rsrc_type = HERMON_QPC;
1262                 serv_type = HERMON_QP_UD;
1263         } else if (attr_p->qp_alloc_flags & IBT_QP_USES_FEXCH) {
1264                 if (log2 > state->hs_ibtfinfo.hca_attr->hca_fexch_max_log2_qp)
1265                         return (IBT_INSUFF_RESOURCE);
1266                 switch (attr_p->qp_fc.fc_hca_port) {
1267                 case 1:
1268                         rsrc_type = HERMON_QPC_FEXCH_PORT1;
1269                         break;
1270                 case 2:


1395                 goto qpalloc_fail1;
1396         }
1397         status = hermon_cq_refcnt_inc(rq_cq, HERMON_CQ_IS_NORMAL);
1398         if (status != DDI_SUCCESS) {
1399                 status = IBT_CQ_HDL_INVALID;
1400                 goto qpalloc_fail2;
1401         }
1402 
1403         /*
1404          * Allocate the software structure for tracking the queue pair
1405          * (i.e. the Hermon Queue Pair handle).  If we fail here, we must
1406          * undo the reference counts and the previous resource allocation.
1407          */
1408         status = hermon_rsrc_alloc(state, HERMON_QPHDL, 1, sleepflag, &rsrc);
1409         if (status != DDI_SUCCESS) {
1410                 status = IBT_INSUFF_RESOURCE;
1411                 goto qpalloc_fail4;
1412         }
1413         qp = (hermon_qphdl_t)rsrc->hr_addr;
1414         bzero(qp, sizeof (struct hermon_sw_qp_s));

1415         qp->qp_alloc_flags = attr_p->qp_alloc_flags;
1416 
1417         /*
1418          * Calculate the QP number from QPC index.  This routine handles
1419          * all of the operations necessary to keep track of used, unused,
1420          * and released QP numbers.
1421          */
1422         qp->qp_qpnum = qpc->hr_indx + ii;
1423         qp->qp_ring = qp->qp_qpnum << 8;
1424         qp->qp_qpn_hdl = NULL;
1425 
1426         /*
1427          * Allocate the doorbell record.  Hermon just needs one for the RQ,
1428          * if the QP is not associated with an SRQ, and use uarpg (above) as
1429          * the uar index
1430          */
1431 
1432         if (!qp_srq_en) {
1433                 status = hermon_dbr_alloc(state, uarpg, &qp->qp_rq_dbr_acchdl,
1434                     &qp->qp_rq_vdbr, &qp->qp_rq_pdbr, &qp->qp_rdbr_mapoffset);


1966         if (qpc == NULL) {
1967                 hermon_icm_set_num_to_hdl(state, HERMON_QPC,
1968                     qp->qp_qpnum, NULL);
1969         } else if (qp->qp_is_special) {
1970                 hermon_icm_set_num_to_hdl(state, HERMON_QPC,
1971                     qpc->hr_indx + port, NULL);
1972         } else {
1973                 hermon_icm_set_num_to_hdl(state, HERMON_QPC,
1974                     qpc->hr_indx, NULL);
1975         }
1976 
1977         /*
1978          * Drop the QP lock
1979          *    At this point the lock is no longer necessary.  We cannot
1980          *    protect from multiple simultaneous calls to free the same QP.
1981          *    In addition, since the QP lock is contained in the QP "software
1982          *    handle" resource, which we will free (see below), it is
1983          *    important that we have no further references to that memory.
1984          */
1985         mutex_exit(&qp->qp_lock);

1986 
1987         /*
1988          * Free the QP resources
1989          *    Start by deregistering and freeing the memory for work queues.
1990          *    Next free any previously allocated context information
1991          *    (depending on QP type)
1992          *    Finally, decrement the necessary reference counts.
1993          * If this fails for any reason, then it is an indication that
1994          * something (either in HW or SW) has gone seriously wrong.  So we
1995          * print a warning message and return.
1996          */
1997         status = hermon_mr_deregister(state, &mr, HERMON_MR_DEREG_ALL,
1998             sleepflag);
1999         if (status != DDI_SUCCESS) {
2000                 HERMON_WARNING(state, "failed to deregister QP memory");
2001                 status = ibc_get_ci_failure(0);
2002                 goto qpfree_fail;
2003         }
2004 
2005         /* Free the memory for the QP */


2204         /*
2205          * Fill in the additional QP info based on the QP's transport type.
2206          */
2207         if (qp->qp_type == IBT_UD_RQP) {
2208 
2209                 /* Fill in the UD-specific info */
2210                 ud = &attr_p->qp_info.qp_transport.ud;
2211                 ud->ud_qkey  = (ib_qkey_t)qpc->qkey;
2212                 ud->ud_sq_psn        = qpc->next_snd_psn;
2213                 ud->ud_pkey_ix       = qpc->pri_addr_path.pkey_indx;
2214                 /* port+1 for port 1/2 */
2215                 ud->ud_port  =
2216                     (uint8_t)(((qpc->pri_addr_path.sched_q >> 6) & 0x01) + 1);
2217 
2218                 attr_p->qp_info.qp_trans = IBT_UD_SRV;
2219 
2220                 if (qp->qp_serv_type == HERMON_QP_FEXCH) {
2221                         ibt_pmr_desc_t *pmr;
2222                         uint64_t heart_beat;
2223 

2224                         pmr = &attr_p->qp_query_fexch.fq_uni_mem_desc;
2225                         pmr->pmd_iova = 0;
2226                         pmr->pmd_lkey = pmr->pmd_rkey =
2227                             hermon_fcoib_qpn_to_mkey(state, qp->qp_qpnum);
2228                         pmr->pmd_phys_buf_list_sz =
2229                             state->hs_fcoib.hfc_mtts_per_mpt;
2230                         pmr->pmd_sync_required = 0;
2231 
2232                         pmr = &attr_p->qp_query_fexch.fq_bi_mem_desc;
2233                         pmr->pmd_iova = 0;
2234                         pmr->pmd_lkey = 0;
2235                         pmr->pmd_rkey = 0;
2236                         pmr->pmd_phys_buf_list_sz = 0;
2237                         pmr->pmd_sync_required = 0;
2238 
2239                         attr_p->qp_query_fexch.fq_flags =
2240                             ((hermon_get_heart_beat_rq_cmd_post(state,
2241                             qp->qp_qpnum, &heart_beat) == HERMON_CMD_SUCCESS) &&
2242                             (heart_beat == 0)) ? IBT_FEXCH_HEART_BEAT_OK :
2243                             IBT_FEXCH_NO_FLAGS;


2405          * no matching entry is found, then allocate, initialize, and
2406          * add an entry to the AVL tree.
2407          * If a matching entry is found, then increment its QPN counter
2408          * and reference counter.
2409          */
2410         query.qpn_indx = qpc->hr_indx;
2411         mutex_enter(&state->hs_qpn_avl_lock);
2412         entry = (hermon_qpn_entry_t *)avl_find(&state->hs_qpn_avl,
2413             &query, &where);
2414         if (entry == NULL) {
2415                 /*
2416                  * Allocate and initialize a QPN entry, then insert
2417                  * it into the AVL tree.
2418                  */
2419                 entry = (hermon_qpn_entry_t *)kmem_zalloc(
2420                     sizeof (hermon_qpn_entry_t), KM_NOSLEEP);
2421                 if (entry == NULL) {
2422                         mutex_exit(&state->hs_qpn_avl_lock);
2423                         return (DDI_FAILURE);
2424                 }

2425 
2426                 entry->qpn_indx         = qpc->hr_indx;
2427                 entry->qpn_refcnt  = 0;
2428                 entry->qpn_counter = 0;
2429 
2430                 avl_insert(&state->hs_qpn_avl, entry, where);
2431         }
2432 
2433         /*
2434          * Make the AVL tree entry point to the QP context resource that
2435          * it will be responsible for tracking
2436          */
2437         entry->qpn_qpc = qpc;
2438 
2439         /*
2440          * Setup the QP handle to point to the AVL tree entry.  Then
2441          * generate the new QP number from the entry's QPN counter value
2442          * and the hardware's QP context table index.
2443          */
2444         qp->qp_qpn_hdl       = entry;