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         /*
  62          * Set the following values before creating CI SRQ, to avoid race
  63          * conditions on async callback.
  64          */
  65         ibt_srq->srq_hca = hca_hdl;
  66 
  67         status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_alloc_srq(
  68             IBTL_HCA2CIHCA(hca_hdl), flags, ibt_srq, pd, srq_sizes,
  69             &ibt_srq->srq_ibc_srq_hdl, real_sizes_p);
  70 
  71         if (status != IBT_SUCCESS) {
  72                 IBTF_DPRINTF_L2(ibtf_srq, "ibt_alloc_srq: "
  73                     "CI SRQ handle allocation failed: status = %d", status);
  74                 kmem_free(ibt_srq, sizeof (struct ibtl_srq_s));
  75                 *ibt_srq_p = NULL;
  76                 return (status);
  77         }
  78 
  79         /* Update the srq resource count */
  80         atomic_inc_32(&hca_hdl->ha_srq_cnt);
  81 
  82         return (IBT_SUCCESS);
  83 }
  84 
  85 
  86 /*
  87  * ibt_free_srq() - Free a shared receive queue
  88  *
  89  */
  90 ibt_status_t
  91 ibt_free_srq(ibt_srq_hdl_t ibt_srq)
  92 {
  93         ibt_status_t    status;
  94         ibtl_hca_t      *ibt_hca = ibt_srq->srq_hca;
  95 
  96         IBTF_DPRINTF_L3(ibtf_srq, "ibt_free_srq(%p)", ibt_srq);
  97 
  98         status = ((IBTL_SRQ2CIHCAOPS_P(ibt_srq))->ibc_free_srq)
  99             (IBTL_SRQ2CIHCA(ibt_srq), ibt_srq->srq_ibc_srq_hdl);
 100 
 101         if (status != IBT_SUCCESS) {
 102                 IBTF_DPRINTF_L2(ibtf_srq, "ibt_free_srq: "
 103                     "CI SRQ handle de-allocation failed: status = %d", status);
 104                 return (status);
 105         }
 106 
 107         ibtl_free_srq_async_check(ibt_srq);
 108 
 109         /* Update the srq resource count */
 110         atomic_dec_32(&ibt_hca->ha_srq_cnt);
 111 
 112         return (status);
 113 }
 114 
 115 
 116 /*
 117  * ibt_query_srq() - Returns the size of the srq
 118  */
 119 ibt_status_t
 120 ibt_query_srq(ibt_srq_hdl_t ibt_srq, ibt_pd_hdl_t *pd_p,
 121     ibt_srq_sizes_t *sizes_p, uint_t *limit)
 122 {
 123         IBTF_DPRINTF_L3(ibtf_srq, "ibt_query_srq(%p)", ibt_srq);
 124 
 125         return (IBTL_SRQ2CIHCAOPS_P(ibt_srq)->ibc_query_srq(
 126             IBTL_SRQ2CIHCA(ibt_srq), ibt_srq->srq_ibc_srq_hdl, pd_p,
 127             sizes_p, limit));
 128 }
 129 
 130 
 131 /*
 132  *  ibt_resize_srq() - Change the size of a srq.
 133  */
 134 ibt_status_t
 135 ibt_modify_srq(ibt_srq_hdl_t ibt_srq, ibt_srq_modify_flags_t flags,
 136     uint_t size, uint_t limit, uint_t *real_size_p)
 137 {
 138         IBTF_DPRINTF_L3(ibtf_srq, "ibt_modify_srq(%p, %d, %d, %d)",
 139             ibt_srq, flags, size, limit);
 140 
 141         return (IBTL_SRQ2CIHCAOPS_P(ibt_srq)->ibc_modify_srq(
 142             IBTL_SRQ2CIHCA(ibt_srq), ibt_srq->srq_ibc_srq_hdl,
 143             flags, size, limit, real_size_p));
 144 }
 145 
 146 
 147 /*
 148  * ibt_set_srq_private - Sets the private data on a given SRQ
 149  *
 150  *      ibt_srq          The ibt_srq_hdl_t of the allocated SRQ.
 151  *      clnt_private    The client private data.
 152  */
 153 void
 154 ibt_set_srq_private(ibt_srq_hdl_t ibt_srq, void *clnt_private)
 155 {
 156         ibt_srq->srq_clnt_private = clnt_private;
 157 }
 158 
 159 
 160 /*
 161  * ibt_get_srq_private - Retrieves the private data for a given SRQ
 162  *
 163  *      ibt_srq          The ibt_srq_hdl_t of the allocated SRQ.
 164  */
 165 void *
 166 ibt_get_srq_private(ibt_srq_hdl_t ibt_srq)
 167 {
 168         return (ibt_srq->srq_clnt_private);
 169 }
 170 
 171 /*
 172  * Function:
 173  *      ibt_post_srq
 174  * Input:
 175  *      srq     - SRQ.
 176  *      wr_list - Address of array[size] of work requests.
 177  *      size    - Number of work requests.
 178  * Output:
 179  *      posted  - Address to return the number of work requests
 180  *                successfully posted.  May be NULL.
 181  * Description:
 182  *      Post one or more receive work requests to the SRQ.
 183  */
 184 
 185 ibt_status_t
 186 ibt_post_srq(ibt_srq_hdl_t srq, ibt_recv_wr_t *wr_list, uint_t size,
 187     uint_t *posted)
 188 {
 189         IBTF_DPRINTF_L4(ibtf_srq, "ibt_post_srq(%p, %p, %d)",
 190             srq, wr_list, size);
 191 
 192         return (IBTL_SRQ2CIHCAOPS_P(srq)->ibc_post_srq(IBTL_SRQ2CIHCA(srq),
 193             srq->srq_ibc_srq_hdl, wr_list, size, posted));
 194 }