Print this page
5255 uts shouldn't open-code ISP2


  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 /*
  23  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*
  27  * hermon_srq.c
  28  *    Hermon Shared Receive Queue Processing Routines
  29  *
  30  *    Implements all the routines necessary for allocating, freeing, querying,
  31  *    modifying and posting shared receive queues.
  32  */
  33 

  34 #include <sys/types.h>
  35 #include <sys/conf.h>
  36 #include <sys/ddi.h>
  37 #include <sys/sunddi.h>
  38 #include <sys/modctl.h>
  39 #include <sys/bitmap.h>
  40 
  41 #include <sys/ib/adapters/hermon/hermon.h>
  42 
  43 static void hermon_srq_sgl_to_logwqesz(hermon_state_t *state, uint_t num_sgl,
  44     hermon_qp_wq_type_t wq_type, uint_t *logwqesz, uint_t *max_sgl);
  45 
  46 /*
  47  * hermon_srq_alloc()
  48  *    Context: Can be called only from user or kernel context.
  49  */
  50 int
  51 hermon_srq_alloc(hermon_state_t *state, hermon_srq_info_t *srqinfo,
  52     uint_t sleepflag)
  53 {


 157         /*
 158          * Allocate the doorbell record.  Hermon just needs one for the
 159          * SRQ, and use uarpg (above) as the uar index
 160          */
 161 
 162         status = hermon_dbr_alloc(state, uarpg, &srq->srq_wq_dbr_acchdl,
 163             &srq->srq_wq_vdbr, &srq->srq_wq_pdbr, &srq->srq_rdbr_mapoffset);
 164         if (status != DDI_SUCCESS) {
 165                 status = IBT_INSUFF_RESOURCE;
 166                 goto srqalloc_fail4;
 167         }
 168 
 169         /*
 170          * Calculate the appropriate size for the SRQ.
 171          * Note:  All Hermon SRQs must be a power-of-2 in size.  Also
 172          * they may not be any smaller than HERMON_SRQ_MIN_SIZE.  This step
 173          * is to round the requested size up to the next highest power-of-2
 174          */
 175         srq_wr_sz = max(sizes->srq_wr_sz + 1, HERMON_SRQ_MIN_SIZE);
 176         log_srq_size = highbit(srq_wr_sz);
 177         if ((srq_wr_sz & (srq_wr_sz - 1)) == 0) {
 178                 log_srq_size = log_srq_size - 1;
 179         }
 180 
 181         /*
 182          * Next we verify that the rounded-up size is valid (i.e. consistent
 183          * with the device limits and/or software-configured limits).  If not,
 184          * then obviously we have a lot of cleanup to do before returning.
 185          */
 186         if (log_srq_size > state->hs_cfg_profile->cp_log_max_srq_sz) {
 187                 status = IBT_HCA_WR_EXCEEDED;
 188                 goto srqalloc_fail4a;
 189         }
 190 
 191         /*
 192          * Next we verify that the requested number of SGL is valid (i.e.
 193          * consistent with the device limits and/or software-configured
 194          * limits).  If not, then obviously the same cleanup needs to be done.
 195          */
 196         max_sgl = state->hs_ibtfinfo.hca_attr->hca_max_srq_sgl;
 197         if (sizes->srq_sgl_sz > max_sgl) {


 606             (state->hs_cfg_profile->cp_srq_resize_enabled == 0))
 607                 return (IBT_NOT_SUPPORTED);
 608 
 609         /*
 610          * If size requested is larger than device capability, return
 611          * Insufficient Resources
 612          */
 613         max_srq_size = (1 << state->hs_cfg_profile->cp_log_max_srq_sz);
 614         if (size > max_srq_size) {
 615                 return (IBT_HCA_WR_EXCEEDED);
 616         }
 617 
 618         /*
 619          * Calculate the appropriate size for the SRQ.
 620          * Note:  All Hermon SRQs must be a power-of-2 in size.  Also
 621          * they may not be any smaller than HERMON_SRQ_MIN_SIZE.  This step
 622          * is to round the requested size up to the next highest power-of-2
 623          */
 624         size = max(size, HERMON_SRQ_MIN_SIZE);
 625         log_srq_size = highbit(size);
 626         if ((size & (size - 1)) == 0) {
 627                 log_srq_size = log_srq_size - 1;
 628         }
 629 
 630         /*
 631          * Next we verify that the rounded-up size is valid (i.e. consistent
 632          * with the device limits and/or software-configured limits).
 633          */
 634         if (log_srq_size > state->hs_cfg_profile->cp_log_max_srq_sz) {
 635                 status = IBT_HCA_WR_EXCEEDED;
 636                 goto srqmodify_fail;
 637         }
 638 
 639         /*
 640          * Allocate the memory for newly resized Shared Receive Queue.
 641          *
 642          * Note: If SRQ is not user-mappable, then it may come from either
 643          * kernel system memory or from HCA-attached local DDR memory.
 644          *
 645          * Note2: We align this queue on a pagesize boundary.  This is required
 646          * to make sure that all the resulting IB addresses will start at 0,


 957 
 958 /*
 959  * hermon_srq_sgl_to_logwqesz()
 960  *    Context: Can be called from interrupt or base context.
 961  */
 962 static void
 963 hermon_srq_sgl_to_logwqesz(hermon_state_t *state, uint_t num_sgl,
 964     hermon_qp_wq_type_t wq_type, uint_t *logwqesz, uint_t *max_sgl)
 965 {
 966         uint_t  max_size, log2, actual_sgl;
 967 
 968         switch (wq_type) {
 969         case HERMON_QP_WQ_TYPE_RECVQ:
 970                 /*
 971                  * Use requested maximum SGL to calculate max descriptor size
 972                  * (while guaranteeing that the descriptor size is a
 973                  * power-of-2 cachelines).
 974                  */
 975                 max_size = (HERMON_QP_WQE_MLX_SRQ_HDRS + (num_sgl << 4));
 976                 log2 = highbit(max_size);
 977                 if ((max_size & (max_size - 1)) == 0) {
 978                         log2 = log2 - 1;
 979                 }
 980 
 981                 /* Make sure descriptor is at least the minimum size */
 982                 log2 = max(log2, HERMON_QP_WQE_LOG_MINIMUM);
 983 
 984                 /* Calculate actual number of SGL (given WQE size) */
 985                 actual_sgl = ((1 << log2) - HERMON_QP_WQE_MLX_SRQ_HDRS) >> 4;
 986                 break;
 987 
 988         default:
 989                 HERMON_WARNING(state, "unexpected work queue type");
 990                 break;
 991         }
 992 
 993         /* Fill in the return values */
 994         *logwqesz = log2;
 995         *max_sgl  = min(state->hs_cfg_profile->cp_srq_max_sgl, actual_sgl);
 996 }


  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 /*
  23  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*
  27  * hermon_srq.c
  28  *    Hermon Shared Receive Queue Processing Routines
  29  *
  30  *    Implements all the routines necessary for allocating, freeing, querying,
  31  *    modifying and posting shared receive queues.
  32  */
  33 
  34 #include <sys/sysmacros.h>
  35 #include <sys/types.h>
  36 #include <sys/conf.h>
  37 #include <sys/ddi.h>
  38 #include <sys/sunddi.h>
  39 #include <sys/modctl.h>
  40 #include <sys/bitmap.h>
  41 
  42 #include <sys/ib/adapters/hermon/hermon.h>
  43 
  44 static void hermon_srq_sgl_to_logwqesz(hermon_state_t *state, uint_t num_sgl,
  45     hermon_qp_wq_type_t wq_type, uint_t *logwqesz, uint_t *max_sgl);
  46 
  47 /*
  48  * hermon_srq_alloc()
  49  *    Context: Can be called only from user or kernel context.
  50  */
  51 int
  52 hermon_srq_alloc(hermon_state_t *state, hermon_srq_info_t *srqinfo,
  53     uint_t sleepflag)
  54 {


 158         /*
 159          * Allocate the doorbell record.  Hermon just needs one for the
 160          * SRQ, and use uarpg (above) as the uar index
 161          */
 162 
 163         status = hermon_dbr_alloc(state, uarpg, &srq->srq_wq_dbr_acchdl,
 164             &srq->srq_wq_vdbr, &srq->srq_wq_pdbr, &srq->srq_rdbr_mapoffset);
 165         if (status != DDI_SUCCESS) {
 166                 status = IBT_INSUFF_RESOURCE;
 167                 goto srqalloc_fail4;
 168         }
 169 
 170         /*
 171          * Calculate the appropriate size for the SRQ.
 172          * Note:  All Hermon SRQs must be a power-of-2 in size.  Also
 173          * they may not be any smaller than HERMON_SRQ_MIN_SIZE.  This step
 174          * is to round the requested size up to the next highest power-of-2
 175          */
 176         srq_wr_sz = max(sizes->srq_wr_sz + 1, HERMON_SRQ_MIN_SIZE);
 177         log_srq_size = highbit(srq_wr_sz);
 178         if (ISP2(srq_wr_sz)) {
 179                 log_srq_size = log_srq_size - 1;
 180         }
 181 
 182         /*
 183          * Next we verify that the rounded-up size is valid (i.e. consistent
 184          * with the device limits and/or software-configured limits).  If not,
 185          * then obviously we have a lot of cleanup to do before returning.
 186          */
 187         if (log_srq_size > state->hs_cfg_profile->cp_log_max_srq_sz) {
 188                 status = IBT_HCA_WR_EXCEEDED;
 189                 goto srqalloc_fail4a;
 190         }
 191 
 192         /*
 193          * Next we verify that the requested number of SGL is valid (i.e.
 194          * consistent with the device limits and/or software-configured
 195          * limits).  If not, then obviously the same cleanup needs to be done.
 196          */
 197         max_sgl = state->hs_ibtfinfo.hca_attr->hca_max_srq_sgl;
 198         if (sizes->srq_sgl_sz > max_sgl) {


 607             (state->hs_cfg_profile->cp_srq_resize_enabled == 0))
 608                 return (IBT_NOT_SUPPORTED);
 609 
 610         /*
 611          * If size requested is larger than device capability, return
 612          * Insufficient Resources
 613          */
 614         max_srq_size = (1 << state->hs_cfg_profile->cp_log_max_srq_sz);
 615         if (size > max_srq_size) {
 616                 return (IBT_HCA_WR_EXCEEDED);
 617         }
 618 
 619         /*
 620          * Calculate the appropriate size for the SRQ.
 621          * Note:  All Hermon SRQs must be a power-of-2 in size.  Also
 622          * they may not be any smaller than HERMON_SRQ_MIN_SIZE.  This step
 623          * is to round the requested size up to the next highest power-of-2
 624          */
 625         size = max(size, HERMON_SRQ_MIN_SIZE);
 626         log_srq_size = highbit(size);
 627         if (ISP2(size)) {
 628                 log_srq_size = log_srq_size - 1;
 629         }
 630 
 631         /*
 632          * Next we verify that the rounded-up size is valid (i.e. consistent
 633          * with the device limits and/or software-configured limits).
 634          */
 635         if (log_srq_size > state->hs_cfg_profile->cp_log_max_srq_sz) {
 636                 status = IBT_HCA_WR_EXCEEDED;
 637                 goto srqmodify_fail;
 638         }
 639 
 640         /*
 641          * Allocate the memory for newly resized Shared Receive Queue.
 642          *
 643          * Note: If SRQ is not user-mappable, then it may come from either
 644          * kernel system memory or from HCA-attached local DDR memory.
 645          *
 646          * Note2: We align this queue on a pagesize boundary.  This is required
 647          * to make sure that all the resulting IB addresses will start at 0,


 958 
 959 /*
 960  * hermon_srq_sgl_to_logwqesz()
 961  *    Context: Can be called from interrupt or base context.
 962  */
 963 static void
 964 hermon_srq_sgl_to_logwqesz(hermon_state_t *state, uint_t num_sgl,
 965     hermon_qp_wq_type_t wq_type, uint_t *logwqesz, uint_t *max_sgl)
 966 {
 967         uint_t  max_size, log2, actual_sgl;
 968 
 969         switch (wq_type) {
 970         case HERMON_QP_WQ_TYPE_RECVQ:
 971                 /*
 972                  * Use requested maximum SGL to calculate max descriptor size
 973                  * (while guaranteeing that the descriptor size is a
 974                  * power-of-2 cachelines).
 975                  */
 976                 max_size = (HERMON_QP_WQE_MLX_SRQ_HDRS + (num_sgl << 4));
 977                 log2 = highbit(max_size);
 978                 if (ISP2(max_size)) {
 979                         log2 = log2 - 1;
 980                 }
 981 
 982                 /* Make sure descriptor is at least the minimum size */
 983                 log2 = max(log2, HERMON_QP_WQE_LOG_MINIMUM);
 984 
 985                 /* Calculate actual number of SGL (given WQE size) */
 986                 actual_sgl = ((1 << log2) - HERMON_QP_WQE_MLX_SRQ_HDRS) >> 4;
 987                 break;
 988 
 989         default:
 990                 HERMON_WARNING(state, "unexpected work queue type");
 991                 break;
 992         }
 993 
 994         /* Fill in the return values */
 995         *logwqesz = log2;
 996         *max_sgl  = min(state->hs_cfg_profile->cp_srq_max_sgl, actual_sgl);
 997 }