1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 
  25 #include <sys/ib/ibtl/impl/ibtl.h>
  26 
  27 /*
  28  * ibtl_srq.c
  29  *      These routines implement (most of) the verbs related to
  30  *      Shared Receive Queues.
  31  */
  32 
  33 /*
  34  * Globals
  35  */
  36 
  37 static char ibtf_srq[] = "ibtl_srq";
  38 
  39 /*
  40  * This file contains code for the TI SRQ calls
  41  */
  42 
  43 /*
  44  *
  45  * ibt_alloc_srq() - Allocate a completion queue
  46  */
  47 ibt_status_t
  48 ibt_alloc_srq(ibt_hca_hdl_t hca_hdl, ibt_srq_flags_t flags, ibt_pd_hdl_t pd,
  49     ibt_srq_sizes_t *srq_sizes, ibt_srq_hdl_t *ibt_srq_p,
  50     ibt_srq_sizes_t *real_sizes_p)
  51 {
  52         ibt_status_t            status;
  53         ibt_srq_hdl_t           ibt_srq;
  54 
  55         IBTF_DPRINTF_L3(ibtf_srq, "ibt_alloc_srq(%p, %p)",
  56             hca_hdl, srq_sizes);
  57 
  58         ibt_srq = kmem_zalloc(sizeof (struct ibtl_srq_s), KM_SLEEP);
  59         *ibt_srq_p = ibt_srq;
  60 
  61         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibt_srq->srq_ibc_srq_hdl))
  62         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibt_srq->srq_hca))
  63         /*
  64          * Set the following values before creating CI SRQ, to avoid race
  65          * conditions on async callback.
  66          */
  67         ibt_srq->srq_hca = hca_hdl;
  68 
  69         status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_alloc_srq(
  70             IBTL_HCA2CIHCA(hca_hdl), flags, ibt_srq, pd, srq_sizes,
  71             &ibt_srq->srq_ibc_srq_hdl, real_sizes_p);
  72 
  73         if (status != IBT_SUCCESS) {
  74                 IBTF_DPRINTF_L2(ibtf_srq, "ibt_alloc_srq: "
  75                     "CI SRQ handle allocation failed: status = %d", status);
  76                 kmem_free(ibt_srq, sizeof (struct ibtl_srq_s));
  77                 *ibt_srq_p = NULL;
  78                 return (status);
  79         }
  80 
  81         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibt_srq->srq_ibc_srq_hdl))
  82         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibt_srq->srq_hca))
  83 
  84         /* Update the srq resource count */
  85         atomic_inc_32(&hca_hdl->ha_srq_cnt);
  86 
  87         return (IBT_SUCCESS);
  88 }
  89 
  90 
  91 /*
  92  * ibt_free_srq() - Free a shared receive queue
  93  *
  94  */
  95 ibt_status_t
  96 ibt_free_srq(ibt_srq_hdl_t ibt_srq)
  97 {
  98         ibt_status_t    status;
  99         ibtl_hca_t      *ibt_hca = ibt_srq->srq_hca;
 100 
 101         IBTF_DPRINTF_L3(ibtf_srq, "ibt_free_srq(%p)", ibt_srq);
 102 
 103         status = ((IBTL_SRQ2CIHCAOPS_P(ibt_srq))->ibc_free_srq)
 104             (IBTL_SRQ2CIHCA(ibt_srq), ibt_srq->srq_ibc_srq_hdl);
 105 
 106         if (status != IBT_SUCCESS) {
 107                 IBTF_DPRINTF_L2(ibtf_srq, "ibt_free_srq: "
 108                     "CI SRQ handle de-allocation failed: status = %d", status);
 109                 return (status);
 110         }
 111 
 112         ibtl_free_srq_async_check(ibt_srq);
 113 
 114         /* Update the srq resource count */
 115         atomic_dec_32(&ibt_hca->ha_srq_cnt);
 116 
 117         return (status);
 118 }
 119 
 120 
 121 /*
 122  * ibt_query_srq() - Returns the size of the srq
 123  */
 124 ibt_status_t
 125 ibt_query_srq(ibt_srq_hdl_t ibt_srq, ibt_pd_hdl_t *pd_p,
 126     ibt_srq_sizes_t *sizes_p, uint_t *limit)
 127 {
 128         IBTF_DPRINTF_L3(ibtf_srq, "ibt_query_srq(%p)", ibt_srq);
 129 
 130         return (IBTL_SRQ2CIHCAOPS_P(ibt_srq)->ibc_query_srq(
 131             IBTL_SRQ2CIHCA(ibt_srq), ibt_srq->srq_ibc_srq_hdl, pd_p,
 132             sizes_p, limit));
 133 }
 134 
 135 
 136 /*
 137  *  ibt_resize_srq() - Change the size of a srq.
 138  */
 139 ibt_status_t
 140 ibt_modify_srq(ibt_srq_hdl_t ibt_srq, ibt_srq_modify_flags_t flags,
 141     uint_t size, uint_t limit, uint_t *real_size_p)
 142 {
 143         IBTF_DPRINTF_L3(ibtf_srq, "ibt_modify_srq(%p, %d, %d, %d)",
 144             ibt_srq, flags, size, limit);
 145 
 146         return (IBTL_SRQ2CIHCAOPS_P(ibt_srq)->ibc_modify_srq(
 147             IBTL_SRQ2CIHCA(ibt_srq), ibt_srq->srq_ibc_srq_hdl,
 148             flags, size, limit, real_size_p));
 149 }
 150 
 151 
 152 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibtl_srq_s::srq_clnt_private))
 153 
 154 /*
 155  * ibt_set_srq_private - Sets the private data on a given SRQ
 156  *
 157  *      ibt_srq          The ibt_srq_hdl_t of the allocated SRQ.
 158  *      clnt_private    The client private data.
 159  */
 160 void
 161 ibt_set_srq_private(ibt_srq_hdl_t ibt_srq, void *clnt_private)
 162 {
 163         ibt_srq->srq_clnt_private = clnt_private;
 164 }
 165 
 166 
 167 /*
 168  * ibt_get_srq_private - Retrieves the private data for a given SRQ
 169  *
 170  *      ibt_srq          The ibt_srq_hdl_t of the allocated SRQ.
 171  */
 172 void *
 173 ibt_get_srq_private(ibt_srq_hdl_t ibt_srq)
 174 {
 175         return (ibt_srq->srq_clnt_private);
 176 }
 177 
 178 /*
 179  * Function:
 180  *      ibt_post_srq
 181  * Input:
 182  *      srq     - SRQ.
 183  *      wr_list - Address of array[size] of work requests.
 184  *      size    - Number of work requests.
 185  * Output:
 186  *      posted  - Address to return the number of work requests
 187  *                successfully posted.  May be NULL.
 188  * Description:
 189  *      Post one or more receive work requests to the SRQ.
 190  */
 191 
 192 ibt_status_t
 193 ibt_post_srq(ibt_srq_hdl_t srq, ibt_recv_wr_t *wr_list, uint_t size,
 194     uint_t *posted)
 195 {
 196         IBTF_DPRINTF_L4(ibtf_srq, "ibt_post_srq(%p, %p, %d)",
 197             srq, wr_list, size);
 198 
 199         return (IBTL_SRQ2CIHCAOPS_P(srq)->ibc_post_srq(IBTL_SRQ2CIHCA(srq),
 200             srq->srq_ibc_srq_hdl, wr_list, size, posted));
 201 }