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;
|