19e39c5baSBill Taylor /*
29e39c5baSBill Taylor * CDDL HEADER START
39e39c5baSBill Taylor *
49e39c5baSBill Taylor * The contents of this file are subject to the terms of the
59e39c5baSBill Taylor * Common Development and Distribution License (the "License").
69e39c5baSBill Taylor * You may not use this file except in compliance with the License.
79e39c5baSBill Taylor *
89e39c5baSBill Taylor * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99e39c5baSBill Taylor * or http://www.opensolaris.org/os/licensing.
109e39c5baSBill Taylor * See the License for the specific language governing permissions
119e39c5baSBill Taylor * and limitations under the License.
129e39c5baSBill Taylor *
139e39c5baSBill Taylor * When distributing Covered Code, include this CDDL HEADER in each
149e39c5baSBill Taylor * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159e39c5baSBill Taylor * If applicable, add the following below this CDDL HEADER, with the
169e39c5baSBill Taylor * fields enclosed by brackets "[]" replaced with your own identifying
179e39c5baSBill Taylor * information: Portions Copyright [yyyy] [name of copyright owner]
189e39c5baSBill Taylor *
199e39c5baSBill Taylor * CDDL HEADER END
209e39c5baSBill Taylor */
219e39c5baSBill Taylor
229e39c5baSBill Taylor /*
2317a2b317SBill Taylor * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
249e39c5baSBill Taylor */
259e39c5baSBill Taylor
269e39c5baSBill Taylor /*
279e39c5baSBill Taylor * hermon_rsrc.c
289e39c5baSBill Taylor * Hermon Resource Management Routines
299e39c5baSBill Taylor *
309e39c5baSBill Taylor * Implements all the routines necessary for setup, teardown, and
319e39c5baSBill Taylor * alloc/free of all Hermon resources, including those that are managed
329e39c5baSBill Taylor * by Hermon hardware or which live in Hermon's direct attached DDR memory.
339e39c5baSBill Taylor */
349e39c5baSBill Taylor
35*de710d24SJosef 'Jeff' Sipek #include <sys/sysmacros.h>
369e39c5baSBill Taylor #include <sys/types.h>
379e39c5baSBill Taylor #include <sys/conf.h>
389e39c5baSBill Taylor #include <sys/ddi.h>
399e39c5baSBill Taylor #include <sys/sunddi.h>
409e39c5baSBill Taylor #include <sys/modctl.h>
419e39c5baSBill Taylor #include <sys/vmem.h>
429e39c5baSBill Taylor #include <sys/bitmap.h>
439e39c5baSBill Taylor
449e39c5baSBill Taylor #include <sys/ib/adapters/hermon/hermon.h>
459e39c5baSBill Taylor
469e39c5baSBill Taylor int hermon_rsrc_verbose = 0;
479e39c5baSBill Taylor
489e39c5baSBill Taylor /*
499e39c5baSBill Taylor * The following routines are used for initializing and destroying
509e39c5baSBill Taylor * the resource pools used by the Hermon resource allocation routines.
519e39c5baSBill Taylor * They consist of four classes of object:
529e39c5baSBill Taylor *
539e39c5baSBill Taylor * Mailboxes: The "In" and "Out" mailbox types are used by the Hermon
549e39c5baSBill Taylor * command interface routines. Mailboxes are used to pass information
559e39c5baSBill Taylor * back and forth to the Hermon firmware. Either type of mailbox may
569e39c5baSBill Taylor * be allocated from Hermon's direct attached DDR memory or from system
579e39c5baSBill Taylor * memory (although currently all "In" mailboxes are in DDR and all "out"
589e39c5baSBill Taylor * mailboxes come from system memory.
599e39c5baSBill Taylor *
609e39c5baSBill Taylor * HW entry objects: These objects represent resources required by the Hermon
619e39c5baSBill Taylor * hardware. These objects include things like Queue Pair contexts (QPC),
629e39c5baSBill Taylor * Completion Queue contexts (CQC), Event Queue contexts (EQC), RDB (for
639e39c5baSBill Taylor * supporting RDMA Read/Atomic), Multicast Group entries (MCG), Memory
649e39c5baSBill Taylor * Protection Table entries (MPT), Memory Translation Table entries (MTT).
659e39c5baSBill Taylor *
669e39c5baSBill Taylor * What these objects all have in common is that they are each required
679e39c5baSBill Taylor * to come from ICM memory, they are always allocated from tables, and
689e39c5baSBill Taylor * they are not to be directly accessed (read or written) by driver
699e39c5baSBill Taylor * software (Mellanox FMR access to MPT is an exception).
709e39c5baSBill Taylor * The other notable exceptions are the UAR pages (UAR_PG) which are
719e39c5baSBill Taylor * allocated from the UAR address space rather than DDR, and the UD
729e39c5baSBill Taylor * address vectors (UDAV) which are similar to the common object types
739e39c5baSBill Taylor * with the major difference being that UDAVs _are_ directly read and
749e39c5baSBill Taylor * written by driver software.
759e39c5baSBill Taylor *
769e39c5baSBill Taylor * SW handle objects: These objects represent resources required by Hermon
779e39c5baSBill Taylor * driver software. They are primarily software tracking structures,
789e39c5baSBill Taylor * which are allocated from system memory (using kmem_cache). Several of
799e39c5baSBill Taylor * the objects have both a "constructor" and "destructor" method
809e39c5baSBill Taylor * associated with them (see below).
819e39c5baSBill Taylor *
829e39c5baSBill Taylor * Protection Domain (PD) handle objects: These objects are very much like
839e39c5baSBill Taylor * a SW handle object with the notable difference that all PD handle
849e39c5baSBill Taylor * objects have an actual Protection Domain number (PD) associated with
859e39c5baSBill Taylor * them (and the PD number is allocated/managed through a separate
869e39c5baSBill Taylor * vmem_arena specifically set aside for this purpose.
879e39c5baSBill Taylor */
889e39c5baSBill Taylor
899e39c5baSBill Taylor static int hermon_rsrc_mbox_init(hermon_state_t *state,
909e39c5baSBill Taylor hermon_rsrc_mbox_info_t *info);
919e39c5baSBill Taylor static void hermon_rsrc_mbox_fini(hermon_state_t *state,
929e39c5baSBill Taylor hermon_rsrc_mbox_info_t *info);
939e39c5baSBill Taylor
949e39c5baSBill Taylor static int hermon_rsrc_sw_handles_init(hermon_state_t *state,
959e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t *info);
969e39c5baSBill Taylor static void hermon_rsrc_sw_handles_fini(hermon_state_t *state,
979e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t *info);
989e39c5baSBill Taylor
999e39c5baSBill Taylor static int hermon_rsrc_pd_handles_init(hermon_state_t *state,
1009e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t *info);
1019e39c5baSBill Taylor static void hermon_rsrc_pd_handles_fini(hermon_state_t *state,
1029e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t *info);
1039e39c5baSBill Taylor
1049e39c5baSBill Taylor /*
1059e39c5baSBill Taylor * The following routines are used for allocating and freeing the specific
1069e39c5baSBill Taylor * types of objects described above from their associated resource pools.
1079e39c5baSBill Taylor */
1089e39c5baSBill Taylor static int hermon_rsrc_mbox_alloc(hermon_rsrc_pool_info_t *pool_info,
1099e39c5baSBill Taylor uint_t num, hermon_rsrc_t *hdl);
11017a2b317SBill Taylor static void hermon_rsrc_mbox_free(hermon_rsrc_t *hdl);
1119e39c5baSBill Taylor
1129e39c5baSBill Taylor static int hermon_rsrc_hw_entry_alloc(hermon_rsrc_pool_info_t *pool_info,
11317a2b317SBill Taylor uint_t num, uint_t num_align, uint_t sleepflag, hermon_rsrc_t *hdl);
1149e39c5baSBill Taylor static void hermon_rsrc_hw_entry_free(hermon_rsrc_pool_info_t *pool_info,
1159e39c5baSBill Taylor hermon_rsrc_t *hdl);
11617a2b317SBill Taylor static int hermon_rsrc_hw_entry_reserve(hermon_rsrc_pool_info_t *pool_info,
11717a2b317SBill Taylor uint_t num, uint_t num_align, uint_t sleepflag, hermon_rsrc_t *hdl);
1189e39c5baSBill Taylor
1199e39c5baSBill Taylor static int hermon_rsrc_hw_entry_icm_confirm(hermon_rsrc_pool_info_t *pool_info,
12017a2b317SBill Taylor uint_t num, hermon_rsrc_t *hdl, int num_to_hdl);
1219e39c5baSBill Taylor static int hermon_rsrc_hw_entry_icm_free(hermon_rsrc_pool_info_t *pool_info,
12217a2b317SBill Taylor hermon_rsrc_t *hdl, int num_to_hdl);
1239e39c5baSBill Taylor
1249e39c5baSBill Taylor static int hermon_rsrc_swhdl_alloc(hermon_rsrc_pool_info_t *pool_info,
1259e39c5baSBill Taylor uint_t sleepflag, hermon_rsrc_t *hdl);
1269e39c5baSBill Taylor static void hermon_rsrc_swhdl_free(hermon_rsrc_pool_info_t *pool_info,
1279e39c5baSBill Taylor hermon_rsrc_t *hdl);
1289e39c5baSBill Taylor
1299e39c5baSBill Taylor static int hermon_rsrc_pdhdl_alloc(hermon_rsrc_pool_info_t *pool_info,
1309e39c5baSBill Taylor uint_t sleepflag, hermon_rsrc_t *hdl);
1319e39c5baSBill Taylor static void hermon_rsrc_pdhdl_free(hermon_rsrc_pool_info_t *pool_info,
1329e39c5baSBill Taylor hermon_rsrc_t *hdl);
1339e39c5baSBill Taylor
13417a2b317SBill Taylor static int hermon_rsrc_fexch_alloc(hermon_state_t *state,
13517a2b317SBill Taylor hermon_rsrc_type_t rsrc, uint_t num, uint_t sleepflag, hermon_rsrc_t *hdl);
13617a2b317SBill Taylor static void hermon_rsrc_fexch_free(hermon_state_t *state, hermon_rsrc_t *hdl);
13717a2b317SBill Taylor static int hermon_rsrc_rfci_alloc(hermon_state_t *state,
13817a2b317SBill Taylor hermon_rsrc_type_t rsrc, uint_t num, uint_t sleepflag, hermon_rsrc_t *hdl);
13917a2b317SBill Taylor static void hermon_rsrc_rfci_free(hermon_state_t *state, hermon_rsrc_t *hdl);
14017a2b317SBill Taylor
1419e39c5baSBill Taylor /*
1429e39c5baSBill Taylor * The following routines are the constructors and destructors for several
1439e39c5baSBill Taylor * of the SW handle type objects. For certain types of SW handles objects
1449e39c5baSBill Taylor * (all of which are implemented using kmem_cache), we need to do some
1459e39c5baSBill Taylor * special field initialization (specifically, mutex_init/destroy). These
1469e39c5baSBill Taylor * routines enable that init and teardown.
1479e39c5baSBill Taylor */
1489e39c5baSBill Taylor static int hermon_rsrc_pdhdl_constructor(void *pd, void *priv, int flags);
1499e39c5baSBill Taylor static void hermon_rsrc_pdhdl_destructor(void *pd, void *state);
1509e39c5baSBill Taylor static int hermon_rsrc_cqhdl_constructor(void *cq, void *priv, int flags);
1519e39c5baSBill Taylor static void hermon_rsrc_cqhdl_destructor(void *cq, void *state);
1529e39c5baSBill Taylor static int hermon_rsrc_qphdl_constructor(void *cq, void *priv, int flags);
1539e39c5baSBill Taylor static void hermon_rsrc_qphdl_destructor(void *cq, void *state);
1549e39c5baSBill Taylor static int hermon_rsrc_srqhdl_constructor(void *srq, void *priv, int flags);
1559e39c5baSBill Taylor static void hermon_rsrc_srqhdl_destructor(void *srq, void *state);
1569e39c5baSBill Taylor static int hermon_rsrc_refcnt_constructor(void *rc, void *priv, int flags);
1579e39c5baSBill Taylor static void hermon_rsrc_refcnt_destructor(void *rc, void *state);
1589e39c5baSBill Taylor static int hermon_rsrc_ahhdl_constructor(void *ah, void *priv, int flags);
1599e39c5baSBill Taylor static void hermon_rsrc_ahhdl_destructor(void *ah, void *state);
1609e39c5baSBill Taylor static int hermon_rsrc_mrhdl_constructor(void *mr, void *priv, int flags);
1619e39c5baSBill Taylor static void hermon_rsrc_mrhdl_destructor(void *mr, void *state);
1629e39c5baSBill Taylor
1639e39c5baSBill Taylor /*
1649e39c5baSBill Taylor * Special routine to calculate and return the size of a MCG object based
1659e39c5baSBill Taylor * on current driver configuration (specifically, the number of QP per MCG
1669e39c5baSBill Taylor * that has been configured.
1679e39c5baSBill Taylor */
1689e39c5baSBill Taylor static int hermon_rsrc_mcg_entry_get_size(hermon_state_t *state,
1699e39c5baSBill Taylor uint_t *mcg_size_shift);
1709e39c5baSBill Taylor
1719e39c5baSBill Taylor
1729e39c5baSBill Taylor /*
1739e39c5baSBill Taylor * hermon_rsrc_alloc()
1749e39c5baSBill Taylor *
1759e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
1769e39c5baSBill Taylor * The "sleepflag" parameter is used by all object allocators to
1779e39c5baSBill Taylor * determine whether to SLEEP for resources or not.
1789e39c5baSBill Taylor */
1799e39c5baSBill Taylor int
hermon_rsrc_alloc(hermon_state_t * state,hermon_rsrc_type_t rsrc,uint_t num,uint_t sleepflag,hermon_rsrc_t ** hdl)1809e39c5baSBill Taylor hermon_rsrc_alloc(hermon_state_t *state, hermon_rsrc_type_t rsrc, uint_t num,
1819e39c5baSBill Taylor uint_t sleepflag, hermon_rsrc_t **hdl)
1829e39c5baSBill Taylor {
1839e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool;
1849e39c5baSBill Taylor hermon_rsrc_t *tmp_rsrc_hdl;
1859e39c5baSBill Taylor int flag, status = DDI_FAILURE;
1869e39c5baSBill Taylor
1879e39c5baSBill Taylor ASSERT(state != NULL);
1889e39c5baSBill Taylor ASSERT(hdl != NULL);
1899e39c5baSBill Taylor
1909e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[rsrc];
1919e39c5baSBill Taylor ASSERT(rsrc_pool != NULL);
1929e39c5baSBill Taylor
1939e39c5baSBill Taylor /*
1949e39c5baSBill Taylor * Allocate space for the object used to track the resource handle
1959e39c5baSBill Taylor */
1969e39c5baSBill Taylor flag = (sleepflag == HERMON_SLEEP) ? KM_SLEEP : KM_NOSLEEP;
19717a2b317SBill Taylor tmp_rsrc_hdl = kmem_cache_alloc(state->hs_rsrc_cache, flag);
1989e39c5baSBill Taylor if (tmp_rsrc_hdl == NULL) {
1999e39c5baSBill Taylor return (DDI_FAILURE);
2009e39c5baSBill Taylor }
2019e39c5baSBill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*tmp_rsrc_hdl))
2029e39c5baSBill Taylor
2039e39c5baSBill Taylor /*
2049e39c5baSBill Taylor * Set rsrc_hdl type. This is later used by the hermon_rsrc_free call
2059e39c5baSBill Taylor * to know what type of resource is being freed.
2069e39c5baSBill Taylor */
2079e39c5baSBill Taylor tmp_rsrc_hdl->rsrc_type = rsrc;
2089e39c5baSBill Taylor
2099e39c5baSBill Taylor /*
2109e39c5baSBill Taylor * Depending on resource type, call the appropriate alloc routine
2119e39c5baSBill Taylor */
21217a2b317SBill Taylor switch (rsrc) {
2139e39c5baSBill Taylor case HERMON_IN_MBOX:
2149e39c5baSBill Taylor case HERMON_OUT_MBOX:
2159e39c5baSBill Taylor case HERMON_INTR_IN_MBOX:
2169e39c5baSBill Taylor case HERMON_INTR_OUT_MBOX:
2179e39c5baSBill Taylor status = hermon_rsrc_mbox_alloc(rsrc_pool, num, tmp_rsrc_hdl);
2189e39c5baSBill Taylor break;
2199e39c5baSBill Taylor
22017a2b317SBill Taylor case HERMON_DMPT:
22117a2b317SBill Taylor /* Allocate "num" (contiguous/aligned for FEXCH) DMPTs */
2229e39c5baSBill Taylor case HERMON_QPC:
22317a2b317SBill Taylor /* Allocate "num" (contiguous/aligned for RSS) QPCs */
224c7facc54SBill Taylor status = hermon_rsrc_hw_entry_alloc(rsrc_pool, num, num,
2259e39c5baSBill Taylor sleepflag, tmp_rsrc_hdl);
2269e39c5baSBill Taylor break;
2279e39c5baSBill Taylor
22817a2b317SBill Taylor case HERMON_QPC_FEXCH_PORT1:
22917a2b317SBill Taylor case HERMON_QPC_FEXCH_PORT2:
23017a2b317SBill Taylor /* Allocate "num" contiguous/aligned QPCs for FEXCH */
23117a2b317SBill Taylor status = hermon_rsrc_fexch_alloc(state, rsrc, num,
23217a2b317SBill Taylor sleepflag, tmp_rsrc_hdl);
2339e39c5baSBill Taylor break;
2349e39c5baSBill Taylor
23517a2b317SBill Taylor case HERMON_QPC_RFCI_PORT1:
23617a2b317SBill Taylor case HERMON_QPC_RFCI_PORT2:
23717a2b317SBill Taylor /* Allocate "num" contiguous/aligned QPCs for RFCI */
23817a2b317SBill Taylor status = hermon_rsrc_rfci_alloc(state, rsrc, num,
2399e39c5baSBill Taylor sleepflag, tmp_rsrc_hdl);
2409e39c5baSBill Taylor break;
2419e39c5baSBill Taylor
2429e39c5baSBill Taylor case HERMON_MTT:
24317a2b317SBill Taylor case HERMON_CQC:
24417a2b317SBill Taylor case HERMON_SRQC:
24517a2b317SBill Taylor case HERMON_EQC:
24617a2b317SBill Taylor case HERMON_MCG:
2479e39c5baSBill Taylor case HERMON_UARPG:
24817a2b317SBill Taylor /* Allocate "num" unaligned resources */
2499e39c5baSBill Taylor status = hermon_rsrc_hw_entry_alloc(rsrc_pool, num, 1,
25017a2b317SBill Taylor sleepflag, tmp_rsrc_hdl);
2519e39c5baSBill Taylor break;
2529e39c5baSBill Taylor
2539e39c5baSBill Taylor case HERMON_MRHDL:
2549e39c5baSBill Taylor case HERMON_EQHDL:
2559e39c5baSBill Taylor case HERMON_CQHDL:
2569e39c5baSBill Taylor case HERMON_SRQHDL:
2579e39c5baSBill Taylor case HERMON_AHHDL:
2589e39c5baSBill Taylor case HERMON_QPHDL:
2599e39c5baSBill Taylor case HERMON_REFCNT:
2609e39c5baSBill Taylor status = hermon_rsrc_swhdl_alloc(rsrc_pool, sleepflag,
2619e39c5baSBill Taylor tmp_rsrc_hdl);
2629e39c5baSBill Taylor break;
2639e39c5baSBill Taylor
2649e39c5baSBill Taylor case HERMON_PDHDL:
2659e39c5baSBill Taylor status = hermon_rsrc_pdhdl_alloc(rsrc_pool, sleepflag,
2669e39c5baSBill Taylor tmp_rsrc_hdl);
2679e39c5baSBill Taylor break;
2689e39c5baSBill Taylor
2699e39c5baSBill Taylor case HERMON_RDB: /* handled during HERMON_QPC */
2709e39c5baSBill Taylor case HERMON_ALTC: /* handled during HERMON_QPC */
2719e39c5baSBill Taylor case HERMON_AUXC: /* handled during HERMON_QPC */
2729e39c5baSBill Taylor case HERMON_CMPT_QPC: /* handled during HERMON_QPC */
2739e39c5baSBill Taylor case HERMON_CMPT_SRQC: /* handled during HERMON_SRQC */
2749e39c5baSBill Taylor case HERMON_CMPT_CQC: /* handled during HERMON_CPC */
2759e39c5baSBill Taylor case HERMON_CMPT_EQC: /* handled during HERMON_EPC */
2769e39c5baSBill Taylor default:
2779e39c5baSBill Taylor HERMON_WARNING(state, "unexpected resource type in alloc ");
2789e39c5baSBill Taylor cmn_err(CE_WARN, "Resource type %x \n", rsrc_pool->rsrc_type);
2799e39c5baSBill Taylor break;
2809e39c5baSBill Taylor }
2819e39c5baSBill Taylor
2829e39c5baSBill Taylor /*
2839e39c5baSBill Taylor * If the resource allocation failed, then free the special resource
2849e39c5baSBill Taylor * tracking structure and return failure. Otherwise return the
2859e39c5baSBill Taylor * handle for the resource tracking structure.
2869e39c5baSBill Taylor */
2879e39c5baSBill Taylor if (status != DDI_SUCCESS) {
2889e39c5baSBill Taylor kmem_cache_free(state->hs_rsrc_cache, tmp_rsrc_hdl);
2899e39c5baSBill Taylor return (DDI_FAILURE);
2909e39c5baSBill Taylor } else {
2919e39c5baSBill Taylor *hdl = tmp_rsrc_hdl;
2929e39c5baSBill Taylor return (DDI_SUCCESS);
2939e39c5baSBill Taylor }
2949e39c5baSBill Taylor }
2959e39c5baSBill Taylor
2969e39c5baSBill Taylor
29717a2b317SBill Taylor /*
29817a2b317SBill Taylor * hermon_rsrc_reserve()
29917a2b317SBill Taylor *
30017a2b317SBill Taylor * Context: Can only be called from attach.
30117a2b317SBill Taylor * The "sleepflag" parameter is used by all object allocators to
30217a2b317SBill Taylor * determine whether to SLEEP for resources or not.
30317a2b317SBill Taylor */
30417a2b317SBill Taylor int
hermon_rsrc_reserve(hermon_state_t * state,hermon_rsrc_type_t rsrc,uint_t num,uint_t sleepflag,hermon_rsrc_t ** hdl)30517a2b317SBill Taylor hermon_rsrc_reserve(hermon_state_t *state, hermon_rsrc_type_t rsrc, uint_t num,
30617a2b317SBill Taylor uint_t sleepflag, hermon_rsrc_t **hdl)
30717a2b317SBill Taylor {
30817a2b317SBill Taylor hermon_rsrc_pool_info_t *rsrc_pool;
30917a2b317SBill Taylor hermon_rsrc_t *tmp_rsrc_hdl;
31017a2b317SBill Taylor int flag, status = DDI_FAILURE;
31117a2b317SBill Taylor
31217a2b317SBill Taylor ASSERT(state != NULL);
31317a2b317SBill Taylor ASSERT(hdl != NULL);
31417a2b317SBill Taylor
31517a2b317SBill Taylor rsrc_pool = &state->hs_rsrc_hdl[rsrc];
31617a2b317SBill Taylor ASSERT(rsrc_pool != NULL);
31717a2b317SBill Taylor
31817a2b317SBill Taylor /*
31917a2b317SBill Taylor * Allocate space for the object used to track the resource handle
32017a2b317SBill Taylor */
32117a2b317SBill Taylor flag = (sleepflag == HERMON_SLEEP) ? KM_SLEEP : KM_NOSLEEP;
32217a2b317SBill Taylor tmp_rsrc_hdl = kmem_cache_alloc(state->hs_rsrc_cache, flag);
32317a2b317SBill Taylor if (tmp_rsrc_hdl == NULL) {
32417a2b317SBill Taylor return (DDI_FAILURE);
32517a2b317SBill Taylor }
32617a2b317SBill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*tmp_rsrc_hdl))
32717a2b317SBill Taylor
32817a2b317SBill Taylor /*
32917a2b317SBill Taylor * Set rsrc_hdl type. This is later used by the hermon_rsrc_free call
33017a2b317SBill Taylor * to know what type of resource is being freed.
33117a2b317SBill Taylor */
33217a2b317SBill Taylor tmp_rsrc_hdl->rsrc_type = rsrc;
33317a2b317SBill Taylor
33417a2b317SBill Taylor switch (rsrc) {
33517a2b317SBill Taylor case HERMON_QPC:
33617a2b317SBill Taylor case HERMON_DMPT:
33717a2b317SBill Taylor case HERMON_MTT:
33817a2b317SBill Taylor /*
33917a2b317SBill Taylor * Reserve num resources, naturally aligned (N * num).
34017a2b317SBill Taylor */
34117a2b317SBill Taylor status = hermon_rsrc_hw_entry_reserve(rsrc_pool, num, num,
34217a2b317SBill Taylor sleepflag, tmp_rsrc_hdl);
34317a2b317SBill Taylor break;
34417a2b317SBill Taylor
34517a2b317SBill Taylor default:
34617a2b317SBill Taylor HERMON_WARNING(state, "unexpected resource type in reserve ");
34717a2b317SBill Taylor cmn_err(CE_WARN, "Resource type %x \n", rsrc);
34817a2b317SBill Taylor break;
34917a2b317SBill Taylor }
35017a2b317SBill Taylor
35117a2b317SBill Taylor /*
35217a2b317SBill Taylor * If the resource allocation failed, then free the special resource
35317a2b317SBill Taylor * tracking structure and return failure. Otherwise return the
35417a2b317SBill Taylor * handle for the resource tracking structure.
35517a2b317SBill Taylor */
35617a2b317SBill Taylor if (status != DDI_SUCCESS) {
35717a2b317SBill Taylor kmem_cache_free(state->hs_rsrc_cache, tmp_rsrc_hdl);
35817a2b317SBill Taylor return (DDI_FAILURE);
35917a2b317SBill Taylor } else {
36017a2b317SBill Taylor *hdl = tmp_rsrc_hdl;
36117a2b317SBill Taylor return (DDI_SUCCESS);
36217a2b317SBill Taylor }
36317a2b317SBill Taylor }
36417a2b317SBill Taylor
36517a2b317SBill Taylor
36617a2b317SBill Taylor /*
36717a2b317SBill Taylor * hermon_rsrc_fexch_alloc()
36817a2b317SBill Taylor *
36917a2b317SBill Taylor * Context: Can only be called from base context.
37017a2b317SBill Taylor * The "sleepflag" parameter is used by all object allocators to
37117a2b317SBill Taylor * determine whether to SLEEP for resources or not.
37217a2b317SBill Taylor */
37317a2b317SBill Taylor static int
hermon_rsrc_fexch_alloc(hermon_state_t * state,hermon_rsrc_type_t rsrc,uint_t num,uint_t sleepflag,hermon_rsrc_t * hdl)37417a2b317SBill Taylor hermon_rsrc_fexch_alloc(hermon_state_t *state, hermon_rsrc_type_t rsrc,
37517a2b317SBill Taylor uint_t num, uint_t sleepflag, hermon_rsrc_t *hdl)
37617a2b317SBill Taylor {
37717a2b317SBill Taylor hermon_fcoib_t *fcoib;
37817a2b317SBill Taylor void *addr;
37917a2b317SBill Taylor uint32_t fexch_qpn_base;
38017a2b317SBill Taylor hermon_rsrc_pool_info_t *qpc_pool, *mpt_pool, *mtt_pool;
38117a2b317SBill Taylor int flag, status;
38217a2b317SBill Taylor hermon_rsrc_t mpt_hdl; /* temporary, just for icm_confirm */
38317a2b317SBill Taylor hermon_rsrc_t mtt_hdl; /* temporary, just for icm_confirm */
38417a2b317SBill Taylor uint_t portm1; /* hca_port_number - 1 */
38517a2b317SBill Taylor uint_t nummtt;
38617a2b317SBill Taylor vmem_t *vmp;
38717a2b317SBill Taylor
38817a2b317SBill Taylor ASSERT(state != NULL);
38917a2b317SBill Taylor ASSERT(hdl != NULL);
39017a2b317SBill Taylor
39117a2b317SBill Taylor if ((state->hs_ibtfinfo.hca_attr->hca_flags2 & IBT_HCA2_FC) == 0)
39217a2b317SBill Taylor return (DDI_FAILURE);
39317a2b317SBill Taylor
39417a2b317SBill Taylor portm1 = rsrc - HERMON_QPC_FEXCH_PORT1;
39517a2b317SBill Taylor fcoib = &state->hs_fcoib;
39617a2b317SBill Taylor flag = (sleepflag == HERMON_SLEEP) ? VM_SLEEP : VM_NOSLEEP;
39717a2b317SBill Taylor
39817a2b317SBill Taylor /* Allocate from the FEXCH QP range */
39917a2b317SBill Taylor vmp = fcoib->hfc_fexch_vmemp[portm1];
40017a2b317SBill Taylor addr = vmem_xalloc(vmp, num, num, 0, 0, NULL, NULL, flag | VM_FIRSTFIT);
40117a2b317SBill Taylor if (addr == NULL) {
40217a2b317SBill Taylor return (DDI_FAILURE);
40317a2b317SBill Taylor }
40417a2b317SBill Taylor fexch_qpn_base = (uint32_t)((uintptr_t)addr -
40517a2b317SBill Taylor fcoib->hfc_vmemstart + fcoib->hfc_fexch_base[portm1]);
40617a2b317SBill Taylor
40717a2b317SBill Taylor /* ICM confirm for the FEXCH QP range */
40817a2b317SBill Taylor qpc_pool = &state->hs_rsrc_hdl[HERMON_QPC];
40917a2b317SBill Taylor hdl->hr_len = num << qpc_pool->rsrc_shift;
41017a2b317SBill Taylor hdl->hr_addr = addr; /* used only for vmem_xfree */
41117a2b317SBill Taylor hdl->hr_indx = fexch_qpn_base;
41217a2b317SBill Taylor
41317a2b317SBill Taylor status = hermon_rsrc_hw_entry_icm_confirm(qpc_pool, num, hdl, 1);
41417a2b317SBill Taylor if (status != DDI_SUCCESS) {
41517a2b317SBill Taylor vmem_xfree(vmp, addr, num);
41617a2b317SBill Taylor return (DDI_FAILURE);
41717a2b317SBill Taylor }
41817a2b317SBill Taylor
41917a2b317SBill Taylor /* ICM confirm for the Primary MKEYs (client side only) */
42017a2b317SBill Taylor mpt_pool = &state->hs_rsrc_hdl[HERMON_DMPT];
42117a2b317SBill Taylor mpt_hdl.hr_len = num << mpt_pool->rsrc_shift;
42217a2b317SBill Taylor mpt_hdl.hr_addr = NULL;
42317a2b317SBill Taylor mpt_hdl.hr_indx = fcoib->hfc_mpt_base[portm1] +
42417a2b317SBill Taylor (fexch_qpn_base - fcoib->hfc_fexch_base[portm1]);
42517a2b317SBill Taylor
42617a2b317SBill Taylor status = hermon_rsrc_hw_entry_icm_confirm(mpt_pool, num, &mpt_hdl, 0);
42717a2b317SBill Taylor if (status != DDI_SUCCESS) {
42817a2b317SBill Taylor status = hermon_rsrc_hw_entry_icm_free(qpc_pool, hdl, 1);
42917a2b317SBill Taylor vmem_xfree(vmp, addr, num);
43017a2b317SBill Taylor return (DDI_FAILURE);
43117a2b317SBill Taylor }
43217a2b317SBill Taylor
43317a2b317SBill Taylor /* ICM confirm for the MTTs of the Primary MKEYs (client side only) */
43417a2b317SBill Taylor nummtt = fcoib->hfc_mtts_per_mpt;
43517a2b317SBill Taylor num *= nummtt;
43617a2b317SBill Taylor mtt_pool = &state->hs_rsrc_hdl[HERMON_MTT];
43717a2b317SBill Taylor mtt_hdl.hr_len = num << mtt_pool->rsrc_shift;
43817a2b317SBill Taylor mtt_hdl.hr_addr = NULL;
43917a2b317SBill Taylor mtt_hdl.hr_indx = fcoib->hfc_mtt_base[portm1] +
44017a2b317SBill Taylor (fexch_qpn_base - fcoib->hfc_fexch_base[portm1]) *
44117a2b317SBill Taylor nummtt;
44217a2b317SBill Taylor
44317a2b317SBill Taylor status = hermon_rsrc_hw_entry_icm_confirm(mtt_pool, num, &mtt_hdl, 0);
44417a2b317SBill Taylor if (status != DDI_SUCCESS) {
44517a2b317SBill Taylor vmem_xfree(vmp, addr, num);
44617a2b317SBill Taylor return (DDI_FAILURE);
44717a2b317SBill Taylor }
44817a2b317SBill Taylor return (DDI_SUCCESS);
44917a2b317SBill Taylor }
45017a2b317SBill Taylor
45117a2b317SBill Taylor static void
hermon_rsrc_fexch_free(hermon_state_t * state,hermon_rsrc_t * hdl)45217a2b317SBill Taylor hermon_rsrc_fexch_free(hermon_state_t *state, hermon_rsrc_t *hdl)
45317a2b317SBill Taylor {
45417a2b317SBill Taylor hermon_fcoib_t *fcoib;
45517a2b317SBill Taylor uint_t portm1; /* hca_port_number - 1 */
45617a2b317SBill Taylor
45717a2b317SBill Taylor ASSERT(state != NULL);
45817a2b317SBill Taylor ASSERT(hdl != NULL);
45917a2b317SBill Taylor
46017a2b317SBill Taylor portm1 = hdl->rsrc_type - HERMON_QPC_FEXCH_PORT1;
46117a2b317SBill Taylor fcoib = &state->hs_fcoib;
46217a2b317SBill Taylor vmem_xfree(fcoib->hfc_fexch_vmemp[portm1], hdl->hr_addr,
46317a2b317SBill Taylor hdl->hr_len >> state->hs_rsrc_hdl[HERMON_QPC].rsrc_shift);
46417a2b317SBill Taylor }
46517a2b317SBill Taylor
46617a2b317SBill Taylor /*
46717a2b317SBill Taylor * hermon_rsrc_rfci_alloc()
46817a2b317SBill Taylor *
46917a2b317SBill Taylor * Context: Can only be called from base context.
47017a2b317SBill Taylor * The "sleepflag" parameter is used by all object allocators to
47117a2b317SBill Taylor * determine whether to SLEEP for resources or not.
47217a2b317SBill Taylor */
47317a2b317SBill Taylor static int
hermon_rsrc_rfci_alloc(hermon_state_t * state,hermon_rsrc_type_t rsrc,uint_t num,uint_t sleepflag,hermon_rsrc_t * hdl)47417a2b317SBill Taylor hermon_rsrc_rfci_alloc(hermon_state_t *state, hermon_rsrc_type_t rsrc,
47517a2b317SBill Taylor uint_t num, uint_t sleepflag, hermon_rsrc_t *hdl)
47617a2b317SBill Taylor {
47717a2b317SBill Taylor hermon_fcoib_t *fcoib;
47817a2b317SBill Taylor void *addr;
47917a2b317SBill Taylor uint32_t rfci_qpn_base;
48017a2b317SBill Taylor hermon_rsrc_pool_info_t *qpc_pool;
48117a2b317SBill Taylor int flag, status;
48217a2b317SBill Taylor uint_t portm1; /* hca_port_number - 1 */
48317a2b317SBill Taylor vmem_t *vmp;
48417a2b317SBill Taylor
48517a2b317SBill Taylor ASSERT(state != NULL);
48617a2b317SBill Taylor ASSERT(hdl != NULL);
48717a2b317SBill Taylor
48817a2b317SBill Taylor if ((state->hs_ibtfinfo.hca_attr->hca_flags2 & IBT_HCA2_FC) == 0)
48917a2b317SBill Taylor return (DDI_FAILURE);
49017a2b317SBill Taylor
49117a2b317SBill Taylor portm1 = rsrc - HERMON_QPC_RFCI_PORT1;
49217a2b317SBill Taylor fcoib = &state->hs_fcoib;
49317a2b317SBill Taylor flag = (sleepflag == HERMON_SLEEP) ? VM_SLEEP : VM_NOSLEEP;
49417a2b317SBill Taylor
49517a2b317SBill Taylor /* Allocate from the RFCI QP range */
49617a2b317SBill Taylor vmp = fcoib->hfc_rfci_vmemp[portm1];
49717a2b317SBill Taylor addr = vmem_xalloc(vmp, num, num, 0, 0, NULL, NULL, flag | VM_FIRSTFIT);
49817a2b317SBill Taylor if (addr == NULL) {
49917a2b317SBill Taylor return (DDI_FAILURE);
50017a2b317SBill Taylor }
50117a2b317SBill Taylor rfci_qpn_base = (uint32_t)((uintptr_t)addr -
50217a2b317SBill Taylor fcoib->hfc_vmemstart + fcoib->hfc_rfci_base[portm1]);
50317a2b317SBill Taylor
50417a2b317SBill Taylor /* ICM confirm for the RFCI QP */
50517a2b317SBill Taylor qpc_pool = &state->hs_rsrc_hdl[HERMON_QPC];
50617a2b317SBill Taylor hdl->hr_len = num << qpc_pool->rsrc_shift;
50717a2b317SBill Taylor hdl->hr_addr = addr; /* used only for vmem_xfree */
50817a2b317SBill Taylor hdl->hr_indx = rfci_qpn_base;
50917a2b317SBill Taylor
51017a2b317SBill Taylor status = hermon_rsrc_hw_entry_icm_confirm(qpc_pool, num, hdl, 1);
51117a2b317SBill Taylor if (status != DDI_SUCCESS) {
51217a2b317SBill Taylor vmem_xfree(vmp, addr, num);
51317a2b317SBill Taylor return (DDI_FAILURE);
51417a2b317SBill Taylor }
51517a2b317SBill Taylor return (DDI_SUCCESS);
51617a2b317SBill Taylor }
51717a2b317SBill Taylor
51817a2b317SBill Taylor static void
hermon_rsrc_rfci_free(hermon_state_t * state,hermon_rsrc_t * hdl)51917a2b317SBill Taylor hermon_rsrc_rfci_free(hermon_state_t *state, hermon_rsrc_t *hdl)
52017a2b317SBill Taylor {
52117a2b317SBill Taylor hermon_fcoib_t *fcoib;
52217a2b317SBill Taylor uint_t portm1; /* hca_port_number - 1 */
52317a2b317SBill Taylor
52417a2b317SBill Taylor ASSERT(state != NULL);
52517a2b317SBill Taylor ASSERT(hdl != NULL);
52617a2b317SBill Taylor
52717a2b317SBill Taylor portm1 = hdl->rsrc_type - HERMON_QPC_RFCI_PORT1;
52817a2b317SBill Taylor fcoib = &state->hs_fcoib;
52917a2b317SBill Taylor vmem_xfree(fcoib->hfc_rfci_vmemp[portm1], hdl->hr_addr,
53017a2b317SBill Taylor hdl->hr_len >> state->hs_rsrc_hdl[HERMON_QPC].rsrc_shift);
53117a2b317SBill Taylor }
53217a2b317SBill Taylor
53317a2b317SBill Taylor
5349e39c5baSBill Taylor /*
5359e39c5baSBill Taylor * hermon_rsrc_free()
5369e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
5379e39c5baSBill Taylor */
5389e39c5baSBill Taylor void
hermon_rsrc_free(hermon_state_t * state,hermon_rsrc_t ** hdl)5399e39c5baSBill Taylor hermon_rsrc_free(hermon_state_t *state, hermon_rsrc_t **hdl)
5409e39c5baSBill Taylor {
5419e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool;
5429e39c5baSBill Taylor
5439e39c5baSBill Taylor ASSERT(state != NULL);
5449e39c5baSBill Taylor ASSERT(hdl != NULL);
5459e39c5baSBill Taylor
5469e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[(*hdl)->rsrc_type];
5479e39c5baSBill Taylor ASSERT(rsrc_pool != NULL);
5489e39c5baSBill Taylor
5499e39c5baSBill Taylor /*
5509e39c5baSBill Taylor * Depending on resource type, call the appropriate free routine
5519e39c5baSBill Taylor */
5529e39c5baSBill Taylor switch (rsrc_pool->rsrc_type) {
5539e39c5baSBill Taylor case HERMON_IN_MBOX:
5549e39c5baSBill Taylor case HERMON_OUT_MBOX:
5559e39c5baSBill Taylor case HERMON_INTR_IN_MBOX:
5569e39c5baSBill Taylor case HERMON_INTR_OUT_MBOX:
55717a2b317SBill Taylor hermon_rsrc_mbox_free(*hdl);
55817a2b317SBill Taylor break;
55917a2b317SBill Taylor
56017a2b317SBill Taylor case HERMON_QPC_FEXCH_PORT1:
56117a2b317SBill Taylor case HERMON_QPC_FEXCH_PORT2:
56217a2b317SBill Taylor hermon_rsrc_fexch_free(state, *hdl);
56317a2b317SBill Taylor break;
56417a2b317SBill Taylor
56517a2b317SBill Taylor case HERMON_QPC_RFCI_PORT1:
56617a2b317SBill Taylor case HERMON_QPC_RFCI_PORT2:
56717a2b317SBill Taylor hermon_rsrc_rfci_free(state, *hdl);
5689e39c5baSBill Taylor break;
5699e39c5baSBill Taylor
5709e39c5baSBill Taylor case HERMON_QPC:
5719e39c5baSBill Taylor case HERMON_CQC:
5729e39c5baSBill Taylor case HERMON_SRQC:
5739e39c5baSBill Taylor case HERMON_EQC:
5749e39c5baSBill Taylor case HERMON_DMPT:
5759e39c5baSBill Taylor case HERMON_MCG:
5769e39c5baSBill Taylor case HERMON_MTT:
5779e39c5baSBill Taylor case HERMON_UARPG:
5789e39c5baSBill Taylor hermon_rsrc_hw_entry_free(rsrc_pool, *hdl);
5799e39c5baSBill Taylor break;
5809e39c5baSBill Taylor
5819e39c5baSBill Taylor case HERMON_MRHDL:
5829e39c5baSBill Taylor case HERMON_EQHDL:
5839e39c5baSBill Taylor case HERMON_CQHDL:
5849e39c5baSBill Taylor case HERMON_SRQHDL:
5859e39c5baSBill Taylor case HERMON_AHHDL:
5869e39c5baSBill Taylor case HERMON_QPHDL:
5879e39c5baSBill Taylor case HERMON_REFCNT:
5889e39c5baSBill Taylor hermon_rsrc_swhdl_free(rsrc_pool, *hdl);
5899e39c5baSBill Taylor break;
5909e39c5baSBill Taylor
5919e39c5baSBill Taylor case HERMON_PDHDL:
5929e39c5baSBill Taylor hermon_rsrc_pdhdl_free(rsrc_pool, *hdl);
5939e39c5baSBill Taylor break;
5949e39c5baSBill Taylor
5959e39c5baSBill Taylor case HERMON_RDB:
5969e39c5baSBill Taylor case HERMON_ALTC:
5979e39c5baSBill Taylor case HERMON_AUXC:
5989e39c5baSBill Taylor case HERMON_CMPT_QPC:
5999e39c5baSBill Taylor case HERMON_CMPT_SRQC:
6009e39c5baSBill Taylor case HERMON_CMPT_CQC:
6019e39c5baSBill Taylor case HERMON_CMPT_EQC:
6029e39c5baSBill Taylor default:
60317a2b317SBill Taylor cmn_err(CE_CONT, "!rsrc_type = 0x%x\n", rsrc_pool->rsrc_type);
6049e39c5baSBill Taylor break;
6059e39c5baSBill Taylor }
6069e39c5baSBill Taylor
6079e39c5baSBill Taylor /*
6089e39c5baSBill Taylor * Free the special resource tracking structure, set the handle to
6099e39c5baSBill Taylor * NULL, and return.
6109e39c5baSBill Taylor */
6119e39c5baSBill Taylor kmem_cache_free(state->hs_rsrc_cache, *hdl);
6129e39c5baSBill Taylor *hdl = NULL;
6139e39c5baSBill Taylor }
6149e39c5baSBill Taylor
6159e39c5baSBill Taylor
6169e39c5baSBill Taylor /*
6179e39c5baSBill Taylor * hermon_rsrc_init_phase1()
6189e39c5baSBill Taylor *
6199e39c5baSBill Taylor * Completes the first phase of Hermon resource/configuration init.
6209e39c5baSBill Taylor * This involves creating the kmem_cache for the "hermon_rsrc_t"
6219e39c5baSBill Taylor * structs, allocating the space for the resource pool handles,
6229e39c5baSBill Taylor * and setting up the "Out" mailboxes.
6239e39c5baSBill Taylor *
6249e39c5baSBill Taylor * When this function completes, the Hermon driver is ready to
6259e39c5baSBill Taylor * post the following commands which return information only in the
6269e39c5baSBill Taylor * "Out" mailbox: QUERY_DDR, QUERY_FW, QUERY_DEV_LIM, and QUERY_ADAPTER
6279e39c5baSBill Taylor * If any of these commands are to be posted at this time, they must be
6289e39c5baSBill Taylor * done so only when "spinning" (as the outstanding command list and
6299e39c5baSBill Taylor * EQ setup code has not yet run)
6309e39c5baSBill Taylor *
6319e39c5baSBill Taylor * Context: Only called from attach() path context
6329e39c5baSBill Taylor */
6339e39c5baSBill Taylor int
hermon_rsrc_init_phase1(hermon_state_t * state)6349e39c5baSBill Taylor hermon_rsrc_init_phase1(hermon_state_t *state)
6359e39c5baSBill Taylor {
6369e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool;
6379e39c5baSBill Taylor hermon_rsrc_mbox_info_t mbox_info;
6389e39c5baSBill Taylor hermon_rsrc_cleanup_level_t cleanup;
6399e39c5baSBill Taylor hermon_cfg_profile_t *cfgprof;
6409e39c5baSBill Taylor uint64_t num, size;
6419e39c5baSBill Taylor int status;
6429e39c5baSBill Taylor char *rsrc_name;
6439e39c5baSBill Taylor
6449e39c5baSBill Taylor ASSERT(state != NULL);
6459e39c5baSBill Taylor
6469e39c5baSBill Taylor /* This is where Phase 1 of resource initialization begins */
6479e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL0;
6489e39c5baSBill Taylor
6499e39c5baSBill Taylor /* Build kmem cache name from Hermon instance */
65017a2b317SBill Taylor rsrc_name = kmem_zalloc(HERMON_RSRC_NAME_MAXLEN, KM_SLEEP);
6519e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_RSRC_CACHE);
6529e39c5baSBill Taylor
6539e39c5baSBill Taylor /*
6549e39c5baSBill Taylor * Create the kmem_cache for "hermon_rsrc_t" structures
6559e39c5baSBill Taylor * (kmem_cache_create will SLEEP until successful)
6569e39c5baSBill Taylor */
6579e39c5baSBill Taylor state->hs_rsrc_cache = kmem_cache_create(rsrc_name,
6589e39c5baSBill Taylor sizeof (hermon_rsrc_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
6599e39c5baSBill Taylor
6609e39c5baSBill Taylor /*
6619e39c5baSBill Taylor * Allocate an array of hermon_rsrc_pool_info_t's (used in all
6629e39c5baSBill Taylor * subsequent resource allocations)
6639e39c5baSBill Taylor */
6649e39c5baSBill Taylor state->hs_rsrc_hdl = kmem_zalloc(HERMON_NUM_RESOURCES *
6659e39c5baSBill Taylor sizeof (hermon_rsrc_pool_info_t), KM_SLEEP);
6669e39c5baSBill Taylor
6679e39c5baSBill Taylor /* Pull in the configuration profile */
6689e39c5baSBill Taylor cfgprof = state->hs_cfg_profile;
6699e39c5baSBill Taylor
6709e39c5baSBill Taylor /* Initialize the resource pool for "out" mailboxes */
6719e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_outmbox);
6729e39c5baSBill Taylor size = ((uint64_t)1 << cfgprof->cp_log_outmbox_size);
6739e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[HERMON_OUT_MBOX];
6749e39c5baSBill Taylor rsrc_pool->rsrc_loc = HERMON_IN_SYSMEM;
6759e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (size * num);
6769e39c5baSBill Taylor rsrc_pool->rsrc_shift = cfgprof->cp_log_outmbox_size;
6779e39c5baSBill Taylor rsrc_pool->rsrc_quantum = (uint_t)size;
6789e39c5baSBill Taylor rsrc_pool->rsrc_align = HERMON_MBOX_ALIGN;
6799e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
6809e39c5baSBill Taylor mbox_info.mbi_num = num;
6819e39c5baSBill Taylor mbox_info.mbi_size = size;
6829e39c5baSBill Taylor mbox_info.mbi_rsrcpool = rsrc_pool;
6839e39c5baSBill Taylor status = hermon_rsrc_mbox_init(state, &mbox_info);
6849e39c5baSBill Taylor if (status != DDI_SUCCESS) {
6859e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup);
6869e39c5baSBill Taylor status = DDI_FAILURE;
6879e39c5baSBill Taylor goto rsrcinitp1_fail;
6889e39c5baSBill Taylor }
6899e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL1;
6909e39c5baSBill Taylor
6919e39c5baSBill Taylor /* Initialize the mailbox list */
6929e39c5baSBill Taylor status = hermon_outmbox_list_init(state);
6939e39c5baSBill Taylor if (status != DDI_SUCCESS) {
6949e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup);
6959e39c5baSBill Taylor status = DDI_FAILURE;
6969e39c5baSBill Taylor goto rsrcinitp1_fail;
6979e39c5baSBill Taylor }
6989e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL2;
6999e39c5baSBill Taylor
7009e39c5baSBill Taylor /* Initialize the resource pool for "interrupt out" mailboxes */
7019e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_intr_outmbox);
7029e39c5baSBill Taylor size = ((uint64_t)1 << cfgprof->cp_log_outmbox_size);
7039e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[HERMON_INTR_OUT_MBOX];
7049e39c5baSBill Taylor rsrc_pool->rsrc_loc = HERMON_IN_SYSMEM;
7059e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (size * num);
7069e39c5baSBill Taylor rsrc_pool->rsrc_shift = cfgprof->cp_log_outmbox_size;
7079e39c5baSBill Taylor rsrc_pool->rsrc_quantum = (uint_t)size;
7089e39c5baSBill Taylor rsrc_pool->rsrc_align = HERMON_MBOX_ALIGN;
7099e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
7109e39c5baSBill Taylor mbox_info.mbi_num = num;
7119e39c5baSBill Taylor mbox_info.mbi_size = size;
7129e39c5baSBill Taylor mbox_info.mbi_rsrcpool = rsrc_pool;
7139e39c5baSBill Taylor status = hermon_rsrc_mbox_init(state, &mbox_info);
7149e39c5baSBill Taylor if (status != DDI_SUCCESS) {
7159e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup);
7169e39c5baSBill Taylor status = DDI_FAILURE;
7179e39c5baSBill Taylor goto rsrcinitp1_fail;
7189e39c5baSBill Taylor }
7199e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL3;
7209e39c5baSBill Taylor
7219e39c5baSBill Taylor /* Initialize the mailbox list */
7229e39c5baSBill Taylor status = hermon_intr_outmbox_list_init(state);
7239e39c5baSBill Taylor if (status != DDI_SUCCESS) {
7249e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup);
7259e39c5baSBill Taylor status = DDI_FAILURE;
7269e39c5baSBill Taylor goto rsrcinitp1_fail;
7279e39c5baSBill Taylor }
7289e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL4;
7299e39c5baSBill Taylor
7309e39c5baSBill Taylor /* Initialize the resource pool for "in" mailboxes */
7319e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_inmbox);
7329e39c5baSBill Taylor size = ((uint64_t)1 << cfgprof->cp_log_inmbox_size);
7339e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[HERMON_IN_MBOX];
7349e39c5baSBill Taylor rsrc_pool->rsrc_loc = HERMON_IN_SYSMEM;
7359e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (size * num);
7369e39c5baSBill Taylor rsrc_pool->rsrc_shift = cfgprof->cp_log_inmbox_size;
7379e39c5baSBill Taylor rsrc_pool->rsrc_quantum = (uint_t)size;
7389e39c5baSBill Taylor rsrc_pool->rsrc_align = HERMON_MBOX_ALIGN;
7399e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
7409e39c5baSBill Taylor mbox_info.mbi_num = num;
7419e39c5baSBill Taylor mbox_info.mbi_size = size;
7429e39c5baSBill Taylor mbox_info.mbi_rsrcpool = rsrc_pool;
7439e39c5baSBill Taylor status = hermon_rsrc_mbox_init(state, &mbox_info);
7449e39c5baSBill Taylor if (status != DDI_SUCCESS) {
7459e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup);
7469e39c5baSBill Taylor status = DDI_FAILURE;
7479e39c5baSBill Taylor goto rsrcinitp1_fail;
7489e39c5baSBill Taylor }
7499e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL5;
7509e39c5baSBill Taylor
7519e39c5baSBill Taylor /* Initialize the mailbox list */
7529e39c5baSBill Taylor status = hermon_inmbox_list_init(state);
7539e39c5baSBill Taylor if (status != DDI_SUCCESS) {
7549e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup);
7559e39c5baSBill Taylor status = DDI_FAILURE;
7569e39c5baSBill Taylor goto rsrcinitp1_fail;
7579e39c5baSBill Taylor }
7589e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL6;
7599e39c5baSBill Taylor
7609e39c5baSBill Taylor /* Initialize the resource pool for "interrupt in" mailboxes */
7619e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_intr_inmbox);
7629e39c5baSBill Taylor size = ((uint64_t)1 << cfgprof->cp_log_inmbox_size);
7639e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[HERMON_INTR_IN_MBOX];
7649e39c5baSBill Taylor rsrc_pool->rsrc_loc = HERMON_IN_SYSMEM;
7659e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (size * num);
7669e39c5baSBill Taylor rsrc_pool->rsrc_shift = cfgprof->cp_log_inmbox_size;
7679e39c5baSBill Taylor rsrc_pool->rsrc_quantum = (uint_t)size;
7689e39c5baSBill Taylor rsrc_pool->rsrc_align = HERMON_MBOX_ALIGN;
7699e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
7709e39c5baSBill Taylor mbox_info.mbi_num = num;
7719e39c5baSBill Taylor mbox_info.mbi_size = size;
7729e39c5baSBill Taylor mbox_info.mbi_rsrcpool = rsrc_pool;
7739e39c5baSBill Taylor status = hermon_rsrc_mbox_init(state, &mbox_info);
7749e39c5baSBill Taylor if (status != DDI_SUCCESS) {
7759e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup);
7769e39c5baSBill Taylor status = DDI_FAILURE;
7779e39c5baSBill Taylor goto rsrcinitp1_fail;
7789e39c5baSBill Taylor }
7799e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL7;
7809e39c5baSBill Taylor
7819e39c5baSBill Taylor /* Initialize the mailbox list */
7829e39c5baSBill Taylor status = hermon_intr_inmbox_list_init(state);
7839e39c5baSBill Taylor if (status != DDI_SUCCESS) {
7849e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup);
7859e39c5baSBill Taylor status = DDI_FAILURE;
7869e39c5baSBill Taylor goto rsrcinitp1_fail;
7879e39c5baSBill Taylor }
7889e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_PHASE1_COMPLETE;
7899e39c5baSBill Taylor kmem_free(rsrc_name, HERMON_RSRC_NAME_MAXLEN);
7909e39c5baSBill Taylor return (DDI_SUCCESS);
7919e39c5baSBill Taylor
7929e39c5baSBill Taylor rsrcinitp1_fail:
7939e39c5baSBill Taylor kmem_free(rsrc_name, HERMON_RSRC_NAME_MAXLEN);
7949e39c5baSBill Taylor return (status);
7959e39c5baSBill Taylor }
7969e39c5baSBill Taylor
7979e39c5baSBill Taylor
7989e39c5baSBill Taylor /*
7999e39c5baSBill Taylor * hermon_rsrc_init_phase2()
8009e39c5baSBill Taylor * Context: Only called from attach() path context
8019e39c5baSBill Taylor */
8029e39c5baSBill Taylor int
hermon_rsrc_init_phase2(hermon_state_t * state)8039e39c5baSBill Taylor hermon_rsrc_init_phase2(hermon_state_t *state)
8049e39c5baSBill Taylor {
8059e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t hdl_info;
8069e39c5baSBill Taylor hermon_rsrc_hw_entry_info_t entry_info;
8079e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool;
8089e39c5baSBill Taylor hermon_rsrc_cleanup_level_t cleanup, ncleanup;
8099e39c5baSBill Taylor hermon_cfg_profile_t *cfgprof;
8109e39c5baSBill Taylor hermon_hw_querydevlim_t *devlim;
8119e39c5baSBill Taylor uint64_t num, max, num_prealloc;
8129e39c5baSBill Taylor uint_t mcg_size, mcg_size_shift;
8139e39c5baSBill Taylor int i, status;
8149e39c5baSBill Taylor char *rsrc_name;
8159e39c5baSBill Taylor
8169e39c5baSBill Taylor ASSERT(state != NULL);
8179e39c5baSBill Taylor
8189e39c5baSBill Taylor /* Phase 2 initialization begins where Phase 1 left off */
8199e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_PHASE1_COMPLETE;
8209e39c5baSBill Taylor
8219e39c5baSBill Taylor /* Allocate the ICM resource name space */
8229e39c5baSBill Taylor
8239e39c5baSBill Taylor /* Build the ICM vmem arena names from Hermon instance */
82417a2b317SBill Taylor rsrc_name = kmem_zalloc(HERMON_RSRC_NAME_MAXLEN, KM_SLEEP);
8259e39c5baSBill Taylor
8269e39c5baSBill Taylor /*
8279e39c5baSBill Taylor * Initialize the resource pools for all objects that exist in
8289e39c5baSBill Taylor * context memory (ICM). The ICM consists of context tables, each
8299e39c5baSBill Taylor * type of resource (QP, CQ, EQ, etc) having it's own context table
8309e39c5baSBill Taylor * (QPC, CQC, EQC, etc...).
8319e39c5baSBill Taylor */
8329e39c5baSBill Taylor cfgprof = state->hs_cfg_profile;
8339e39c5baSBill Taylor devlim = &state->hs_devlim;
8349e39c5baSBill Taylor
8359e39c5baSBill Taylor /*
8369e39c5baSBill Taylor * Initialize the resource pools for each of the driver resources.
8379e39c5baSBill Taylor * With a few exceptions, these resources fall into the two cateogories
8389e39c5baSBill Taylor * of either hw_entries or sw_entries.
8399e39c5baSBill Taylor */
8409e39c5baSBill Taylor
8419e39c5baSBill Taylor /*
8429e39c5baSBill Taylor * Initialize the resource pools for ICM (hardware) types first.
8439e39c5baSBill Taylor * These resources are managed through vmem arenas, which are
8449e39c5baSBill Taylor * created via the rsrc pool initialization routine. Note that,
8459e39c5baSBill Taylor * due to further calculations, the MCG resource pool is
8469e39c5baSBill Taylor * initialized seperately.
8479e39c5baSBill Taylor */
8489e39c5baSBill Taylor for (i = 0; i < HERMON_NUM_ICM_RESOURCES; i++) {
8499e39c5baSBill Taylor
8509e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[i];
8519e39c5baSBill Taylor rsrc_pool->rsrc_type = i;
85217a2b317SBill Taylor rsrc_pool->rsrc_state = state;
8539e39c5baSBill Taylor
8549e39c5baSBill Taylor /* Set the resource-specific attributes */
8559e39c5baSBill Taylor switch (i) {
8569e39c5baSBill Taylor case HERMON_MTT:
8579e39c5baSBill Taylor max = ((uint64_t)1 << devlim->log_max_mtt);
8589e39c5baSBill Taylor num_prealloc = ((uint64_t)1 << devlim->log_rsvd_mtt);
8599e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_MTT_VMEM);
8609e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL9;
8619e39c5baSBill Taylor break;
8629e39c5baSBill Taylor
8639e39c5baSBill Taylor case HERMON_DMPT:
8649e39c5baSBill Taylor max = ((uint64_t)1 << devlim->log_max_dmpt);
8659e39c5baSBill Taylor num_prealloc = ((uint64_t)1 << devlim->log_rsvd_dmpt);
8669e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_DMPT_VMEM);
8679e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL10;
8689e39c5baSBill Taylor break;
8699e39c5baSBill Taylor
8709e39c5baSBill Taylor case HERMON_QPC:
8719e39c5baSBill Taylor max = ((uint64_t)1 << devlim->log_max_qp);
8729e39c5baSBill Taylor num_prealloc = ((uint64_t)1 << devlim->log_rsvd_qp);
8739e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_QPC_VMEM);
8749e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL11;
8759e39c5baSBill Taylor break;
8769e39c5baSBill Taylor
8779e39c5baSBill Taylor case HERMON_CQC:
8789e39c5baSBill Taylor max = ((uint64_t)1 << devlim->log_max_cq);
8799e39c5baSBill Taylor num_prealloc = ((uint64_t)1 << devlim->log_rsvd_cq);
8809e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_CQC_VMEM);
8819e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL13;
8829e39c5baSBill Taylor break;
8839e39c5baSBill Taylor
8849e39c5baSBill Taylor case HERMON_SRQC:
8859e39c5baSBill Taylor max = ((uint64_t)1 << devlim->log_max_srq);
8869e39c5baSBill Taylor num_prealloc = ((uint64_t)1 << devlim->log_rsvd_srq);
8879e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_SRQC_VMEM);
8889e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL16;
8899e39c5baSBill Taylor break;
8909e39c5baSBill Taylor
8919e39c5baSBill Taylor case HERMON_EQC:
8929e39c5baSBill Taylor max = ((uint64_t)1 << devlim->log_max_eq);
89317a2b317SBill Taylor num_prealloc = state->hs_rsvd_eqs;
8949e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_EQC_VMEM);
8959e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL18;
8969e39c5baSBill Taylor break;
8979e39c5baSBill Taylor
8989e39c5baSBill Taylor case HERMON_MCG: /* handled below */
8999e39c5baSBill Taylor case HERMON_AUXC:
9009e39c5baSBill Taylor case HERMON_ALTC:
9019e39c5baSBill Taylor case HERMON_RDB:
9029e39c5baSBill Taylor case HERMON_CMPT_QPC:
9039e39c5baSBill Taylor case HERMON_CMPT_SRQC:
9049e39c5baSBill Taylor case HERMON_CMPT_CQC:
9059e39c5baSBill Taylor case HERMON_CMPT_EQC:
9069e39c5baSBill Taylor default:
9079e39c5baSBill Taylor /* We don't need to initialize this rsrc here. */
9089e39c5baSBill Taylor continue;
9099e39c5baSBill Taylor }
9109e39c5baSBill Taylor
9119e39c5baSBill Taylor /* Set the common values for all resource pools */
9129e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
9139e39c5baSBill Taylor rsrc_pool->rsrc_loc = HERMON_IN_ICM;
9149e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = state->hs_icm[i].table_size;
9159e39c5baSBill Taylor rsrc_pool->rsrc_align = state->hs_icm[i].table_size;
9169e39c5baSBill Taylor rsrc_pool->rsrc_shift = state->hs_icm[i].log_object_size;
9179e39c5baSBill Taylor rsrc_pool->rsrc_quantum = state->hs_icm[i].object_size;
9189e39c5baSBill Taylor
9199e39c5baSBill Taylor /* Now, initialize the entry_info and call the init routine */
9209e39c5baSBill Taylor entry_info.hwi_num = state->hs_icm[i].num_entries;
9219e39c5baSBill Taylor entry_info.hwi_max = max;
9229e39c5baSBill Taylor entry_info.hwi_prealloc = num_prealloc;
9239e39c5baSBill Taylor entry_info.hwi_rsrcpool = rsrc_pool;
9249e39c5baSBill Taylor entry_info.hwi_rsrcname = rsrc_name;
9259e39c5baSBill Taylor status = hermon_rsrc_hw_entries_init(state, &entry_info);
9269e39c5baSBill Taylor if (status != DDI_SUCCESS) {
9279e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup);
9289e39c5baSBill Taylor status = DDI_FAILURE;
9299e39c5baSBill Taylor goto rsrcinitp2_fail;
9309e39c5baSBill Taylor }
9319e39c5baSBill Taylor cleanup = ncleanup;
9329e39c5baSBill Taylor }
9339e39c5baSBill Taylor
9349e39c5baSBill Taylor /*
9359e39c5baSBill Taylor * Initialize the Multicast Group (MCG) entries. First, calculate
9369e39c5baSBill Taylor * (and validate) the size of the MCGs.
9379e39c5baSBill Taylor */
9389e39c5baSBill Taylor status = hermon_rsrc_mcg_entry_get_size(state, &mcg_size_shift);
9399e39c5baSBill Taylor if (status != DDI_SUCCESS) {
9409e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup);
9419e39c5baSBill Taylor status = DDI_FAILURE;
9429e39c5baSBill Taylor goto rsrcinitp2_fail;
9439e39c5baSBill Taylor }
9449e39c5baSBill Taylor mcg_size = HERMON_MCGMEM_SZ(state);
9459e39c5baSBill Taylor
9469e39c5baSBill Taylor /*
9479e39c5baSBill Taylor * Initialize the resource pool for the MCG table entries. Notice
9489e39c5baSBill Taylor * that the number of MCGs is configurable. Note also that a certain
9499e39c5baSBill Taylor * number of MCGs must be set aside for Hermon firmware use (they
9509e39c5baSBill Taylor * correspond to the number of MCGs used by the internal hash
9519e39c5baSBill Taylor * function).
9529e39c5baSBill Taylor */
9539e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_mcg);
9549e39c5baSBill Taylor max = ((uint64_t)1 << devlim->log_max_mcg);
9559e39c5baSBill Taylor num_prealloc = ((uint64_t)1 << cfgprof->cp_log_num_mcg_hash);
9569e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[HERMON_MCG];
9579e39c5baSBill Taylor rsrc_pool->rsrc_loc = HERMON_IN_ICM;
9589e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (mcg_size * num);
9599e39c5baSBill Taylor rsrc_pool->rsrc_shift = mcg_size_shift;
9609e39c5baSBill Taylor rsrc_pool->rsrc_quantum = mcg_size;
9619e39c5baSBill Taylor rsrc_pool->rsrc_align = (mcg_size * num);
9629e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
9639e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_MCG_VMEM);
9649e39c5baSBill Taylor entry_info.hwi_num = num;
9659e39c5baSBill Taylor entry_info.hwi_max = max;
9669e39c5baSBill Taylor entry_info.hwi_prealloc = num_prealloc;
9679e39c5baSBill Taylor entry_info.hwi_rsrcpool = rsrc_pool;
9689e39c5baSBill Taylor entry_info.hwi_rsrcname = rsrc_name;
9699e39c5baSBill Taylor status = hermon_rsrc_hw_entries_init(state, &entry_info);
9709e39c5baSBill Taylor if (status != DDI_SUCCESS) {
9719e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup);
9729e39c5baSBill Taylor status = DDI_FAILURE;
9739e39c5baSBill Taylor goto rsrcinitp2_fail;
9749e39c5baSBill Taylor }
9759e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL19;
9769e39c5baSBill Taylor
9779e39c5baSBill Taylor /*
9789e39c5baSBill Taylor * Initialize the full range of ICM for the AUXC resource.
9799e39c5baSBill Taylor * This is done because its size is so small, about 1 byte per QP.
9809e39c5baSBill Taylor */
9819e39c5baSBill Taylor
9829e39c5baSBill Taylor /*
9839e39c5baSBill Taylor * Initialize the Hermon command handling interfaces. This step
9849e39c5baSBill Taylor * sets up the outstanding command tracking mechanism for easy access
9859e39c5baSBill Taylor * and fast allocation (see hermon_cmd.c for more details).
9869e39c5baSBill Taylor */
9879e39c5baSBill Taylor status = hermon_outstanding_cmdlist_init(state);
9889e39c5baSBill Taylor if (status != DDI_SUCCESS) {
9899e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup);
9909e39c5baSBill Taylor status = DDI_FAILURE;
9919e39c5baSBill Taylor goto rsrcinitp2_fail;
9929e39c5baSBill Taylor }
9939e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL20;
9949e39c5baSBill Taylor
9959e39c5baSBill Taylor /* Initialize the resource pool and vmem arena for the PD handles */
9969e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[HERMON_PDHDL];
9979e39c5baSBill Taylor rsrc_pool->rsrc_loc = HERMON_IN_SYSMEM;
9989e39c5baSBill Taylor rsrc_pool->rsrc_quantum = sizeof (struct hermon_sw_pd_s);
9999e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
10009e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_PDHDL_CACHE);
10019e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_pd);
10029e39c5baSBill Taylor hdl_info.swi_max = ((uint64_t)1 << devlim->log_max_pd);
10039e39c5baSBill Taylor hdl_info.swi_rsrcpool = rsrc_pool;
10049e39c5baSBill Taylor hdl_info.swi_constructor = hermon_rsrc_pdhdl_constructor;
10059e39c5baSBill Taylor hdl_info.swi_destructor = hermon_rsrc_pdhdl_destructor;
10069e39c5baSBill Taylor hdl_info.swi_rsrcname = rsrc_name;
10079e39c5baSBill Taylor hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT;
10089e39c5baSBill Taylor status = hermon_rsrc_pd_handles_init(state, &hdl_info);
10099e39c5baSBill Taylor if (status != DDI_SUCCESS) {
10109e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup);
10119e39c5baSBill Taylor status = DDI_FAILURE;
10129e39c5baSBill Taylor goto rsrcinitp2_fail;
10139e39c5baSBill Taylor }
10149e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL21;
10159e39c5baSBill Taylor
10169e39c5baSBill Taylor /*
10179e39c5baSBill Taylor * Initialize the resource pools for the rest of the software handles.
10189e39c5baSBill Taylor * This includes MR handles, EQ handles, QP handles, etc. These
10199e39c5baSBill Taylor * objects are almost entirely managed using kmem_cache routines,
10209e39c5baSBill Taylor * and do not utilize a vmem arena.
10219e39c5baSBill Taylor */
10229e39c5baSBill Taylor for (i = HERMON_NUM_ICM_RESOURCES; i < HERMON_NUM_RESOURCES; i++) {
10239e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[i];
102417a2b317SBill Taylor rsrc_pool->rsrc_type = i;
10259e39c5baSBill Taylor
10269e39c5baSBill Taylor /* Set the resource-specific attributes */
10279e39c5baSBill Taylor switch (i) {
10289e39c5baSBill Taylor case HERMON_MRHDL:
10299e39c5baSBill Taylor rsrc_pool->rsrc_quantum =
10309e39c5baSBill Taylor sizeof (struct hermon_sw_mr_s);
10319e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_MRHDL_CACHE);
10329e39c5baSBill Taylor hdl_info.swi_num =
10339e39c5baSBill Taylor ((uint64_t)1 << cfgprof->cp_log_num_dmpt) +
10349e39c5baSBill Taylor ((uint64_t)1 << cfgprof->cp_log_num_cmpt);
10359e39c5baSBill Taylor hdl_info.swi_max =
10369e39c5baSBill Taylor ((uint64_t)1 << cfgprof->cp_log_num_dmpt) +
10379e39c5baSBill Taylor ((uint64_t)1 << cfgprof->cp_log_num_cmpt);
10389e39c5baSBill Taylor hdl_info.swi_constructor =
10399e39c5baSBill Taylor hermon_rsrc_mrhdl_constructor;
10409e39c5baSBill Taylor hdl_info.swi_destructor = hermon_rsrc_mrhdl_destructor;
10419e39c5baSBill Taylor hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT;
10429e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL22;
10439e39c5baSBill Taylor break;
10449e39c5baSBill Taylor
10459e39c5baSBill Taylor case HERMON_EQHDL:
10469e39c5baSBill Taylor rsrc_pool->rsrc_quantum =
10479e39c5baSBill Taylor sizeof (struct hermon_sw_eq_s);
10489e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_EQHDL_CACHE);
10499e39c5baSBill Taylor hdl_info.swi_num = HERMON_NUM_EQ;
10509e39c5baSBill Taylor hdl_info.swi_max = ((uint64_t)1 << devlim->log_max_eq);
10519e39c5baSBill Taylor hdl_info.swi_constructor = NULL;
10529e39c5baSBill Taylor hdl_info.swi_destructor = NULL;
10539e39c5baSBill Taylor hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT;
10549e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL23;
10559e39c5baSBill Taylor break;
10569e39c5baSBill Taylor
10579e39c5baSBill Taylor case HERMON_CQHDL:
10589e39c5baSBill Taylor rsrc_pool->rsrc_quantum =
10599e39c5baSBill Taylor sizeof (struct hermon_sw_cq_s);
10609e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_CQHDL_CACHE);
10619e39c5baSBill Taylor hdl_info.swi_num =
10629e39c5baSBill Taylor (uint64_t)1 << cfgprof->cp_log_num_cq;
10639e39c5baSBill Taylor hdl_info.swi_max = (uint64_t)1 << devlim->log_max_cq;
10649e39c5baSBill Taylor hdl_info.swi_constructor =
10659e39c5baSBill Taylor hermon_rsrc_cqhdl_constructor;
10669e39c5baSBill Taylor hdl_info.swi_destructor = hermon_rsrc_cqhdl_destructor;
106717a2b317SBill Taylor hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT;
10689e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (hermon_cqhdl_t);
10699e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL24;
10709e39c5baSBill Taylor break;
10719e39c5baSBill Taylor
10729e39c5baSBill Taylor case HERMON_SRQHDL:
10739e39c5baSBill Taylor rsrc_pool->rsrc_quantum =
10749e39c5baSBill Taylor sizeof (struct hermon_sw_srq_s);
10759e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_SRQHDL_CACHE);
10769e39c5baSBill Taylor hdl_info.swi_num =
10779e39c5baSBill Taylor (uint64_t)1 << cfgprof->cp_log_num_srq;
10789e39c5baSBill Taylor hdl_info.swi_max = (uint64_t)1 << devlim->log_max_srq;
10799e39c5baSBill Taylor hdl_info.swi_constructor =
10809e39c5baSBill Taylor hermon_rsrc_srqhdl_constructor;
10819e39c5baSBill Taylor hdl_info.swi_destructor = hermon_rsrc_srqhdl_destructor;
108217a2b317SBill Taylor hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT;
10839e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (hermon_srqhdl_t);
10849e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL25;
10859e39c5baSBill Taylor break;
10869e39c5baSBill Taylor
10879e39c5baSBill Taylor case HERMON_AHHDL:
10889e39c5baSBill Taylor rsrc_pool->rsrc_quantum =
10899e39c5baSBill Taylor sizeof (struct hermon_sw_ah_s);
10909e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_AHHDL_CACHE);
10919e39c5baSBill Taylor hdl_info.swi_num =
10929e39c5baSBill Taylor (uint64_t)1 << cfgprof->cp_log_num_ah;
10939e39c5baSBill Taylor hdl_info.swi_max = HERMON_NUM_AH;
10949e39c5baSBill Taylor hdl_info.swi_constructor =
10959e39c5baSBill Taylor hermon_rsrc_ahhdl_constructor;
10969e39c5baSBill Taylor hdl_info.swi_destructor = hermon_rsrc_ahhdl_destructor;
10979e39c5baSBill Taylor hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT;
10989e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL26;
10999e39c5baSBill Taylor break;
11009e39c5baSBill Taylor
11019e39c5baSBill Taylor case HERMON_QPHDL:
11029e39c5baSBill Taylor rsrc_pool->rsrc_quantum =
11039e39c5baSBill Taylor sizeof (struct hermon_sw_qp_s);
11049e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_QPHDL_CACHE);
11059e39c5baSBill Taylor hdl_info.swi_num =
11069e39c5baSBill Taylor (uint64_t)1 << cfgprof->cp_log_num_qp;
11079e39c5baSBill Taylor hdl_info.swi_max = (uint64_t)1 << devlim->log_max_qp;
11089e39c5baSBill Taylor hdl_info.swi_constructor =
11099e39c5baSBill Taylor hermon_rsrc_qphdl_constructor;
11109e39c5baSBill Taylor hdl_info.swi_destructor = hermon_rsrc_qphdl_destructor;
111117a2b317SBill Taylor hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT;
11129e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (hermon_qphdl_t);
11139e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL27;
11149e39c5baSBill Taylor break;
11159e39c5baSBill Taylor
11169e39c5baSBill Taylor case HERMON_REFCNT:
11179e39c5baSBill Taylor rsrc_pool->rsrc_quantum = sizeof (hermon_sw_refcnt_t);
11189e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_REFCNT_CACHE);
11199e39c5baSBill Taylor hdl_info.swi_num =
11209e39c5baSBill Taylor (uint64_t)1 << cfgprof->cp_log_num_dmpt;
11219e39c5baSBill Taylor hdl_info.swi_max = (uint64_t)1 << devlim->log_max_dmpt;
11229e39c5baSBill Taylor hdl_info.swi_constructor =
11239e39c5baSBill Taylor hermon_rsrc_refcnt_constructor;
11249e39c5baSBill Taylor hdl_info.swi_destructor = hermon_rsrc_refcnt_destructor;
11259e39c5baSBill Taylor hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT;
11269e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL28;
11279e39c5baSBill Taylor break;
11289e39c5baSBill Taylor
11299e39c5baSBill Taylor default:
11309e39c5baSBill Taylor continue;
11319e39c5baSBill Taylor }
11329e39c5baSBill Taylor
11339e39c5baSBill Taylor /* Set the common values and call the init routine */
11349e39c5baSBill Taylor rsrc_pool->rsrc_loc = HERMON_IN_SYSMEM;
11359e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
11369e39c5baSBill Taylor hdl_info.swi_rsrcpool = rsrc_pool;
11379e39c5baSBill Taylor hdl_info.swi_rsrcname = rsrc_name;
11389e39c5baSBill Taylor status = hermon_rsrc_sw_handles_init(state, &hdl_info);
11399e39c5baSBill Taylor if (status != DDI_SUCCESS) {
11409e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup);
11419e39c5baSBill Taylor status = DDI_FAILURE;
11429e39c5baSBill Taylor goto rsrcinitp2_fail;
11439e39c5baSBill Taylor }
11449e39c5baSBill Taylor cleanup = ncleanup;
11459e39c5baSBill Taylor }
11469e39c5baSBill Taylor
11479e39c5baSBill Taylor /*
11489e39c5baSBill Taylor * Initialize a resource pool for the MCG handles. Notice that for
11499e39c5baSBill Taylor * these MCG handles, we are allocating a table of structures (used to
11509e39c5baSBill Taylor * keep track of the MCG entries that are being written to hardware
11519e39c5baSBill Taylor * and to speed up multicast attach/detach operations).
11529e39c5baSBill Taylor */
11539e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_mcg);
11549e39c5baSBill Taylor hdl_info.swi_max = ((uint64_t)1 << devlim->log_max_mcg);
11559e39c5baSBill Taylor hdl_info.swi_flags = HERMON_SWHDL_TABLE_INIT;
11569e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (struct hermon_sw_mcg_list_s);
11579e39c5baSBill Taylor status = hermon_rsrc_sw_handles_init(state, &hdl_info);
11589e39c5baSBill Taylor if (status != DDI_SUCCESS) {
11599e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup);
11609e39c5baSBill Taylor status = DDI_FAILURE;
11619e39c5baSBill Taylor goto rsrcinitp2_fail;
11629e39c5baSBill Taylor }
11639e39c5baSBill Taylor state->hs_mcghdl = hdl_info.swi_table_ptr;
11649e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL29;
11659e39c5baSBill Taylor
11669e39c5baSBill Taylor /*
11679e39c5baSBill Taylor * Last, initialize the resource pool for the UAR pages, which contain
11689e39c5baSBill Taylor * the hardware's doorbell registers. Each process supported in User
11699e39c5baSBill Taylor * Mode is assigned a UAR page. Also coming from this pool are the
11709e39c5baSBill Taylor * kernel-assigned UAR page, and any hardware-reserved pages. Note
11719e39c5baSBill Taylor * that the number of UAR pages is configurable, the value must be less
11729e39c5baSBill Taylor * than the maximum value (obtained from the QUERY_DEV_LIM command) or
11739e39c5baSBill Taylor * the initialization will fail. Note also that we assign the base
11749e39c5baSBill Taylor * address of the UAR BAR to the rsrc_start parameter.
11759e39c5baSBill Taylor */
11769e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_uar);
11779e39c5baSBill Taylor max = num;
11789e39c5baSBill Taylor num_prealloc = max(devlim->num_rsvd_uar, 128);
11799e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[HERMON_UARPG];
11809e39c5baSBill Taylor rsrc_pool->rsrc_loc = HERMON_IN_UAR;
11819e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (num << PAGESHIFT);
11829e39c5baSBill Taylor rsrc_pool->rsrc_shift = PAGESHIFT;
11839e39c5baSBill Taylor rsrc_pool->rsrc_quantum = (uint_t)PAGESIZE;
11849e39c5baSBill Taylor rsrc_pool->rsrc_align = PAGESIZE;
11859e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
11869e39c5baSBill Taylor rsrc_pool->rsrc_start = (void *)state->hs_reg_uar_baseaddr;
11879e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_UAR_PAGE_VMEM_ATTCH);
11889e39c5baSBill Taylor entry_info.hwi_num = num;
11899e39c5baSBill Taylor entry_info.hwi_max = max;
11909e39c5baSBill Taylor entry_info.hwi_prealloc = num_prealloc;
11919e39c5baSBill Taylor entry_info.hwi_rsrcpool = rsrc_pool;
11929e39c5baSBill Taylor entry_info.hwi_rsrcname = rsrc_name;
11939e39c5baSBill Taylor status = hermon_rsrc_hw_entries_init(state, &entry_info);
11949e39c5baSBill Taylor if (status != DDI_SUCCESS) {
11959e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup);
11969e39c5baSBill Taylor status = DDI_FAILURE;
11979e39c5baSBill Taylor goto rsrcinitp2_fail;
11989e39c5baSBill Taylor }
11999e39c5baSBill Taylor
12009e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_ALL;
12019e39c5baSBill Taylor
12029e39c5baSBill Taylor kmem_free(rsrc_name, HERMON_RSRC_NAME_MAXLEN);
12039e39c5baSBill Taylor return (DDI_SUCCESS);
12049e39c5baSBill Taylor
12059e39c5baSBill Taylor rsrcinitp2_fail:
12069e39c5baSBill Taylor kmem_free(rsrc_name, HERMON_RSRC_NAME_MAXLEN);
12079e39c5baSBill Taylor return (status);
12089e39c5baSBill Taylor }
12099e39c5baSBill Taylor
12109e39c5baSBill Taylor
12119e39c5baSBill Taylor /*
12129e39c5baSBill Taylor * hermon_rsrc_fini()
12139e39c5baSBill Taylor * Context: Only called from attach() and/or detach() path contexts
12149e39c5baSBill Taylor */
12159e39c5baSBill Taylor void
hermon_rsrc_fini(hermon_state_t * state,hermon_rsrc_cleanup_level_t clean)12169e39c5baSBill Taylor hermon_rsrc_fini(hermon_state_t *state, hermon_rsrc_cleanup_level_t clean)
12179e39c5baSBill Taylor {
12189e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t hdl_info;
12199e39c5baSBill Taylor hermon_rsrc_hw_entry_info_t entry_info;
12209e39c5baSBill Taylor hermon_rsrc_mbox_info_t mbox_info;
12219e39c5baSBill Taylor hermon_cfg_profile_t *cfgprof;
12229e39c5baSBill Taylor
12239e39c5baSBill Taylor ASSERT(state != NULL);
12249e39c5baSBill Taylor
12259e39c5baSBill Taylor cfgprof = state->hs_cfg_profile;
12269e39c5baSBill Taylor
12279e39c5baSBill Taylor /*
12289e39c5baSBill Taylor * If init code above is shortened up (see comments), then we
12299e39c5baSBill Taylor * need to establish how to safely and simply clean up from any
12309e39c5baSBill Taylor * given failure point. Flags, maybe...
12319e39c5baSBill Taylor */
12329e39c5baSBill Taylor
12339e39c5baSBill Taylor switch (clean) {
12349e39c5baSBill Taylor /*
12359e39c5baSBill Taylor * If we add more resources that need to be cleaned up here, we should
12369e39c5baSBill Taylor * ensure that HERMON_RSRC_CLEANUP_ALL is still the first entry (i.e.
12379e39c5baSBill Taylor * corresponds to the last resource allocated).
12389e39c5baSBill Taylor */
12399e39c5baSBill Taylor
12409e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_ALL:
12419e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL31:
12429e39c5baSBill Taylor /* Cleanup the UAR page resource pool, first the dbr pages */
12439e39c5baSBill Taylor if (state->hs_kern_dbr) {
12449e39c5baSBill Taylor hermon_dbr_kern_free(state);
12459e39c5baSBill Taylor state->hs_kern_dbr = NULL;
12469e39c5baSBill Taylor }
12479e39c5baSBill Taylor
12489e39c5baSBill Taylor /* NS then, the pool itself */
12499e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_UARPG];
12509e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info);
12519e39c5baSBill Taylor
12529e39c5baSBill Taylor /* FALLTHROUGH */
12539e39c5baSBill Taylor
12549e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL30:
12559e39c5baSBill Taylor /* Cleanup the central MCG handle pointers list */
12569e39c5baSBill Taylor hdl_info.swi_rsrcpool = NULL;
12579e39c5baSBill Taylor hdl_info.swi_table_ptr = state->hs_mcghdl;
12589e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_mcg);
12599e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (struct hermon_sw_mcg_list_s);
12609e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, &hdl_info);
12619e39c5baSBill Taylor /* FALLTHROUGH */
12629e39c5baSBill Taylor
12639e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL29:
12649e39c5baSBill Taylor /* Cleanup the reference count resource pool */
12659e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_REFCNT];
12669e39c5baSBill Taylor hdl_info.swi_table_ptr = NULL;
12679e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, &hdl_info);
12689e39c5baSBill Taylor /* FALLTHROUGH */
12699e39c5baSBill Taylor
12709e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL28:
12719e39c5baSBill Taylor /* Cleanup the QP handle resource pool */
12729e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_QPHDL];
127317a2b317SBill Taylor hdl_info.swi_table_ptr = NULL;
12749e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_qp);
12759e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (hermon_qphdl_t);
12769e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, &hdl_info);
12779e39c5baSBill Taylor /* FALLTHROUGH */
12789e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL27:
12799e39c5baSBill Taylor /* Cleanup the address handle resrouce pool */
12809e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_AHHDL];
12819e39c5baSBill Taylor hdl_info.swi_table_ptr = NULL;
12829e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, &hdl_info);
12839e39c5baSBill Taylor /* FALLTHROUGH */
12849e39c5baSBill Taylor
12859e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL26:
12869e39c5baSBill Taylor /* Cleanup the SRQ handle resource pool. */
12879e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_SRQHDL];
128817a2b317SBill Taylor hdl_info.swi_table_ptr = NULL;
12899e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_srq);
12909e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (hermon_srqhdl_t);
12919e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, &hdl_info);
12929e39c5baSBill Taylor /* FALLTHROUGH */
12939e39c5baSBill Taylor
12949e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL25:
12959e39c5baSBill Taylor /* Cleanup the CQ handle resource pool */
12969e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_CQHDL];
129717a2b317SBill Taylor hdl_info.swi_table_ptr = NULL;
12989e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_cq);
12999e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (hermon_cqhdl_t);
13009e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, &hdl_info);
13019e39c5baSBill Taylor /* FALLTHROUGH */
13029e39c5baSBill Taylor
13039e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL24:
13049e39c5baSBill Taylor /* Cleanup the EQ handle resource pool */
13059e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_EQHDL];
13069e39c5baSBill Taylor hdl_info.swi_table_ptr = NULL;
13079e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, &hdl_info);
13089e39c5baSBill Taylor /* FALLTHROUGH */
13099e39c5baSBill Taylor
13109e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL23:
13119e39c5baSBill Taylor /* Cleanup the MR handle resource pool */
13129e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_MRHDL];
13139e39c5baSBill Taylor hdl_info.swi_table_ptr = NULL;
13149e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, &hdl_info);
13159e39c5baSBill Taylor /* FALLTHROUGH */
13169e39c5baSBill Taylor
13179e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL22:
13189e39c5baSBill Taylor /* Cleanup the PD handle resource pool */
13199e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_PDHDL];
13209e39c5baSBill Taylor hdl_info.swi_table_ptr = NULL;
13219e39c5baSBill Taylor hermon_rsrc_pd_handles_fini(state, &hdl_info);
13229e39c5baSBill Taylor /* FALLTHROUGH */
13239e39c5baSBill Taylor
13249e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL21:
13259e39c5baSBill Taylor /* Currently unused - FALLTHROUGH */
13269e39c5baSBill Taylor
13279e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL20:
13289e39c5baSBill Taylor /* Cleanup the outstanding command list */
13299e39c5baSBill Taylor hermon_outstanding_cmdlist_fini(state);
13309e39c5baSBill Taylor /* FALLTHROUGH */
13319e39c5baSBill Taylor
13329e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL19:
13339e39c5baSBill Taylor /* Cleanup the EQC table resource pool */
13349e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_EQC];
13359e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info);
13369e39c5baSBill Taylor /* FALLTHROUGH */
13379e39c5baSBill Taylor
13389e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL18:
13399e39c5baSBill Taylor /* Cleanup the MCG table resource pool */
13409e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_MCG];
13419e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info);
13429e39c5baSBill Taylor /* FALLTHROUGH */
13439e39c5baSBill Taylor
13449e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL17:
13459e39c5baSBill Taylor /* Currently Unused - fallthrough */
13469e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL16:
13479e39c5baSBill Taylor /* Cleanup the SRQC table resource pool */
13489e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_SRQC];
13499e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info);
13509e39c5baSBill Taylor /* FALLTHROUGH */
13519e39c5baSBill Taylor
13529e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL15:
13539e39c5baSBill Taylor /* Cleanup the AUXC table resource pool */
13549e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_AUXC];
13559e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info);
13569e39c5baSBill Taylor /* FALLTHROUGH */
13579e39c5baSBill Taylor
13589e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL14:
13599e39c5baSBill Taylor /* Cleanup the ALTCF table resource pool */
13609e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_ALTC];
13619e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info);
13629e39c5baSBill Taylor /* FALLTHROUGH */
13639e39c5baSBill Taylor
13649e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL13:
13659e39c5baSBill Taylor /* Cleanup the CQC table resource pool */
13669e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_CQC];
13679e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info);
13689e39c5baSBill Taylor /* FALLTHROUGH */
13699e39c5baSBill Taylor
13709e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL12:
13719e39c5baSBill Taylor /* Cleanup the RDB table resource pool */
13729e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_RDB];
13739e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info);
13749e39c5baSBill Taylor /* FALLTHROUGH */
13759e39c5baSBill Taylor
13769e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL11:
13779e39c5baSBill Taylor /* Cleanup the QPC table resource pool */
13789e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_QPC];
13799e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info);
13809e39c5baSBill Taylor /* FALLTHROUGH */
13819e39c5baSBill Taylor
13829e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL10EQ:
13839e39c5baSBill Taylor /* Cleanup the cMPTs for the EQs, CQs, SRQs, and QPs */
13849e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_CMPT_EQC];
13859e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info);
13869e39c5baSBill Taylor /* FALLTHROUGH */
13879e39c5baSBill Taylor
13889e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL10CQ:
13899e39c5baSBill Taylor /* Cleanup the cMPTs for the EQs, CQs, SRQs, and QPs */
13909e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_CMPT_CQC];
13919e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info);
13929e39c5baSBill Taylor /* FALLTHROUGH */
13939e39c5baSBill Taylor
13949e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL10SRQ:
13959e39c5baSBill Taylor /* Cleanup the cMPTs for the EQs, CQs, SRQs, and QPs */
13969e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_CMPT_SRQC];
13979e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info);
13989e39c5baSBill Taylor /* FALLTHROUGH */
13999e39c5baSBill Taylor
14009e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL10QP:
14019e39c5baSBill Taylor /* Cleanup the cMPTs for the EQs, CQs, SRQs, and QPs */
14029e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_CMPT_QPC];
14039e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info);
14049e39c5baSBill Taylor /* FALLTHROUGH */
14059e39c5baSBill Taylor
14069e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL10:
14079e39c5baSBill Taylor /* Cleanup the dMPT table resource pool */
14089e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_DMPT];
14099e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info);
14109e39c5baSBill Taylor /* FALLTHROUGH */
14119e39c5baSBill Taylor
14129e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL9:
14139e39c5baSBill Taylor /* Cleanup the MTT table resource pool */
14149e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_MTT];
14159e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info);
14169e39c5baSBill Taylor break;
14179e39c5baSBill Taylor
14189e39c5baSBill Taylor /*
14199e39c5baSBill Taylor * The cleanup below comes from the "Phase 1" initialization step.
14209e39c5baSBill Taylor * (see hermon_rsrc_init_phase1() above)
14219e39c5baSBill Taylor */
14229e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_PHASE1_COMPLETE:
14239e39c5baSBill Taylor /* Cleanup the "In" mailbox list */
14249e39c5baSBill Taylor hermon_intr_inmbox_list_fini(state);
14259e39c5baSBill Taylor /* FALLTHROUGH */
14269e39c5baSBill Taylor
14279e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL7:
14289e39c5baSBill Taylor /* Cleanup the interrupt "In" mailbox resource pool */
14299e39c5baSBill Taylor mbox_info.mbi_rsrcpool =
14309e39c5baSBill Taylor &state->hs_rsrc_hdl[HERMON_INTR_IN_MBOX];
14319e39c5baSBill Taylor hermon_rsrc_mbox_fini(state, &mbox_info);
14329e39c5baSBill Taylor /* FALLTHROUGH */
14339e39c5baSBill Taylor
14349e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL6:
14359e39c5baSBill Taylor /* Cleanup the "In" mailbox list */
14369e39c5baSBill Taylor hermon_inmbox_list_fini(state);
14379e39c5baSBill Taylor /* FALLTHROUGH */
14389e39c5baSBill Taylor
14399e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL5:
14409e39c5baSBill Taylor /* Cleanup the "In" mailbox resource pool */
14419e39c5baSBill Taylor mbox_info.mbi_rsrcpool = &state->hs_rsrc_hdl[HERMON_IN_MBOX];
14429e39c5baSBill Taylor hermon_rsrc_mbox_fini(state, &mbox_info);
14439e39c5baSBill Taylor /* FALLTHROUGH */
14449e39c5baSBill Taylor
14459e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL4:
14469e39c5baSBill Taylor /* Cleanup the interrupt "Out" mailbox list */
14479e39c5baSBill Taylor hermon_intr_outmbox_list_fini(state);
14489e39c5baSBill Taylor /* FALLTHROUGH */
14499e39c5baSBill Taylor
14509e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL3:
14519e39c5baSBill Taylor /* Cleanup the "Out" mailbox resource pool */
14529e39c5baSBill Taylor mbox_info.mbi_rsrcpool =
14539e39c5baSBill Taylor &state->hs_rsrc_hdl[HERMON_INTR_OUT_MBOX];
14549e39c5baSBill Taylor hermon_rsrc_mbox_fini(state, &mbox_info);
14559e39c5baSBill Taylor /* FALLTHROUGH */
14569e39c5baSBill Taylor
14579e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL2:
14589e39c5baSBill Taylor /* Cleanup the "Out" mailbox list */
14599e39c5baSBill Taylor hermon_outmbox_list_fini(state);
14609e39c5baSBill Taylor /* FALLTHROUGH */
14619e39c5baSBill Taylor
14629e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL1:
14639e39c5baSBill Taylor /* Cleanup the "Out" mailbox resource pool */
14649e39c5baSBill Taylor mbox_info.mbi_rsrcpool = &state->hs_rsrc_hdl[HERMON_OUT_MBOX];
14659e39c5baSBill Taylor hermon_rsrc_mbox_fini(state, &mbox_info);
14669e39c5baSBill Taylor /* FALLTHROUGH */
14679e39c5baSBill Taylor
14689e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL0:
14699e39c5baSBill Taylor /* Free the array of hermon_rsrc_pool_info_t's */
14709e39c5baSBill Taylor
14719e39c5baSBill Taylor kmem_free(state->hs_rsrc_hdl, HERMON_NUM_RESOURCES *
14729e39c5baSBill Taylor sizeof (hermon_rsrc_pool_info_t));
14739e39c5baSBill Taylor
14749e39c5baSBill Taylor kmem_cache_destroy(state->hs_rsrc_cache);
14759e39c5baSBill Taylor break;
14769e39c5baSBill Taylor
14779e39c5baSBill Taylor default:
14789e39c5baSBill Taylor HERMON_WARNING(state, "unexpected resource cleanup level");
14799e39c5baSBill Taylor break;
14809e39c5baSBill Taylor }
14819e39c5baSBill Taylor }
14829e39c5baSBill Taylor
14839e39c5baSBill Taylor
14849e39c5baSBill Taylor /*
14859e39c5baSBill Taylor * hermon_rsrc_mbox_init()
14869e39c5baSBill Taylor * Context: Only called from attach() path context
14879e39c5baSBill Taylor */
14889e39c5baSBill Taylor static int
hermon_rsrc_mbox_init(hermon_state_t * state,hermon_rsrc_mbox_info_t * info)14899e39c5baSBill Taylor hermon_rsrc_mbox_init(hermon_state_t *state, hermon_rsrc_mbox_info_t *info)
14909e39c5baSBill Taylor {
14919e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool;
14929e39c5baSBill Taylor hermon_rsrc_priv_mbox_t *priv;
14939e39c5baSBill Taylor
14949e39c5baSBill Taylor ASSERT(state != NULL);
14959e39c5baSBill Taylor ASSERT(info != NULL);
14969e39c5baSBill Taylor
14979e39c5baSBill Taylor rsrc_pool = info->mbi_rsrcpool;
14989e39c5baSBill Taylor ASSERT(rsrc_pool != NULL);
14999e39c5baSBill Taylor
15009e39c5baSBill Taylor /* Allocate and initialize mailbox private structure */
15019e39c5baSBill Taylor priv = kmem_zalloc(sizeof (hermon_rsrc_priv_mbox_t), KM_SLEEP);
15029e39c5baSBill Taylor priv->pmb_dip = state->hs_dip;
15039e39c5baSBill Taylor priv->pmb_devaccattr = state->hs_reg_accattr;
15049e39c5baSBill Taylor priv->pmb_xfer_mode = DDI_DMA_CONSISTENT;
15059e39c5baSBill Taylor
15069e39c5baSBill Taylor /*
15079e39c5baSBill Taylor * Initialize many of the default DMA attributes. Then set alignment
15089e39c5baSBill Taylor * and scatter-gather restrictions specific for mailbox memory.
15099e39c5baSBill Taylor */
15109e39c5baSBill Taylor hermon_dma_attr_init(state, &priv->pmb_dmaattr);
15119e39c5baSBill Taylor priv->pmb_dmaattr.dma_attr_align = HERMON_MBOX_ALIGN;
15129e39c5baSBill Taylor priv->pmb_dmaattr.dma_attr_sgllen = 1;
15139e39c5baSBill Taylor priv->pmb_dmaattr.dma_attr_flags = 0;
15149e39c5baSBill Taylor rsrc_pool->rsrc_private = priv;
15159e39c5baSBill Taylor
15169e39c5baSBill Taylor ASSERT(rsrc_pool->rsrc_loc == HERMON_IN_SYSMEM);
15179e39c5baSBill Taylor
15189e39c5baSBill Taylor rsrc_pool->rsrc_start = NULL;
15199e39c5baSBill Taylor rsrc_pool->rsrc_vmp = NULL;
15209e39c5baSBill Taylor
15219e39c5baSBill Taylor return (DDI_SUCCESS);
15229e39c5baSBill Taylor }
15239e39c5baSBill Taylor
15249e39c5baSBill Taylor
15259e39c5baSBill Taylor /*
15269e39c5baSBill Taylor * hermon_rsrc_mbox_fini()
15279e39c5baSBill Taylor * Context: Only called from attach() and/or detach() path contexts
15289e39c5baSBill Taylor */
15299e39c5baSBill Taylor /* ARGSUSED */
15309e39c5baSBill Taylor static void
hermon_rsrc_mbox_fini(hermon_state_t * state,hermon_rsrc_mbox_info_t * info)15319e39c5baSBill Taylor hermon_rsrc_mbox_fini(hermon_state_t *state, hermon_rsrc_mbox_info_t *info)
15329e39c5baSBill Taylor {
15339e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool;
15349e39c5baSBill Taylor
15359e39c5baSBill Taylor ASSERT(state != NULL);
15369e39c5baSBill Taylor ASSERT(info != NULL);
15379e39c5baSBill Taylor
15389e39c5baSBill Taylor rsrc_pool = info->mbi_rsrcpool;
15399e39c5baSBill Taylor ASSERT(rsrc_pool != NULL);
15409e39c5baSBill Taylor
15419e39c5baSBill Taylor /* Free up the private struct */
15429e39c5baSBill Taylor kmem_free(rsrc_pool->rsrc_private, sizeof (hermon_rsrc_priv_mbox_t));
15439e39c5baSBill Taylor }
15449e39c5baSBill Taylor
15459e39c5baSBill Taylor
15469e39c5baSBill Taylor /*
15479e39c5baSBill Taylor * hermon_rsrc_hw_entries_init()
15489e39c5baSBill Taylor * Context: Only called from attach() path context
15499e39c5baSBill Taylor */
15509e39c5baSBill Taylor int
hermon_rsrc_hw_entries_init(hermon_state_t * state,hermon_rsrc_hw_entry_info_t * info)15519e39c5baSBill Taylor hermon_rsrc_hw_entries_init(hermon_state_t *state,
15529e39c5baSBill Taylor hermon_rsrc_hw_entry_info_t *info)
15539e39c5baSBill Taylor {
15549e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool;
15559e39c5baSBill Taylor hermon_rsrc_t *rsvd_rsrc = NULL;
15569e39c5baSBill Taylor vmem_t *vmp;
15579e39c5baSBill Taylor uint64_t num_hwentry, max_hwentry, num_prealloc;
15589e39c5baSBill Taylor int status;
15599e39c5baSBill Taylor
15609e39c5baSBill Taylor ASSERT(state != NULL);
15619e39c5baSBill Taylor ASSERT(info != NULL);
15629e39c5baSBill Taylor
15639e39c5baSBill Taylor rsrc_pool = info->hwi_rsrcpool;
15649e39c5baSBill Taylor ASSERT(rsrc_pool != NULL);
15659e39c5baSBill Taylor num_hwentry = info->hwi_num;
15669e39c5baSBill Taylor max_hwentry = info->hwi_max;
15679e39c5baSBill Taylor num_prealloc = info->hwi_prealloc;
15689e39c5baSBill Taylor
15699e39c5baSBill Taylor if (hermon_rsrc_verbose) {
15709e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entries_init: "
15719e39c5baSBill Taylor "rsrc_type (0x%x) num (%llx) max (0x%llx) prealloc "
15729e39c5baSBill Taylor "(0x%llx)", rsrc_pool->rsrc_type, (longlong_t)num_hwentry,
15739e39c5baSBill Taylor (longlong_t)max_hwentry, (longlong_t)num_prealloc);
15749e39c5baSBill Taylor }
15759e39c5baSBill Taylor
15769e39c5baSBill Taylor /* Make sure number of HW entries makes sense */
15779e39c5baSBill Taylor if (num_hwentry > max_hwentry) {
15789e39c5baSBill Taylor return (DDI_FAILURE);
15799e39c5baSBill Taylor }
15809e39c5baSBill Taylor
15819e39c5baSBill Taylor /* Set this pool's rsrc_start from the initial ICM allocation */
15829e39c5baSBill Taylor if (rsrc_pool->rsrc_start == 0) {
1583c7facc54SBill Taylor
1584c7facc54SBill Taylor /* use a ROUND value that works on both 32 and 64-bit kernels */
1585c7facc54SBill Taylor rsrc_pool->rsrc_start = (void *)(uintptr_t)0x10000000;
15869e39c5baSBill Taylor
15879e39c5baSBill Taylor if (hermon_rsrc_verbose) {
15889e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entries_init:"
15899e39c5baSBill Taylor " rsrc_type (0x%x) rsrc_start set (0x%lx)",
15909e39c5baSBill Taylor rsrc_pool->rsrc_type, rsrc_pool->rsrc_start);
15919e39c5baSBill Taylor }
15929e39c5baSBill Taylor }
15939e39c5baSBill Taylor
15949e39c5baSBill Taylor /*
15959e39c5baSBill Taylor * Create new vmem arena for the HW entries table if rsrc_quantum
15969e39c5baSBill Taylor * is non-zero. Otherwise if rsrc_quantum is zero, then these HW
15979e39c5baSBill Taylor * entries are not going to be dynamically allocatable (i.e. they
15989e39c5baSBill Taylor * won't be allocated/freed through hermon_rsrc_alloc/free). This
15999e39c5baSBill Taylor * latter option is used for both ALTC and CMPT resources which
16009e39c5baSBill Taylor * are managed by hardware.
16019e39c5baSBill Taylor */
16029e39c5baSBill Taylor if (rsrc_pool->rsrc_quantum != 0) {
16039e39c5baSBill Taylor vmp = vmem_create(info->hwi_rsrcname,
16049e39c5baSBill Taylor (void *)(uintptr_t)rsrc_pool->rsrc_start,
16059e39c5baSBill Taylor rsrc_pool->rsrc_pool_size, rsrc_pool->rsrc_quantum,
16069e39c5baSBill Taylor NULL, NULL, NULL, 0, VM_SLEEP);
16079e39c5baSBill Taylor if (vmp == NULL) {
16089e39c5baSBill Taylor /* failed to create vmem arena */
16099e39c5baSBill Taylor return (DDI_FAILURE);
16109e39c5baSBill Taylor }
16119e39c5baSBill Taylor rsrc_pool->rsrc_vmp = vmp;
16129e39c5baSBill Taylor if (hermon_rsrc_verbose) {
16139e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entries_init:"
16149e39c5baSBill Taylor " rsrc_type (0x%x) created vmem arena for rsrc",
16159e39c5baSBill Taylor rsrc_pool->rsrc_type);
16169e39c5baSBill Taylor }
16179e39c5baSBill Taylor } else {
16189e39c5baSBill Taylor /* we do not require a vmem arena */
16199e39c5baSBill Taylor rsrc_pool->rsrc_vmp = NULL;
16209e39c5baSBill Taylor if (hermon_rsrc_verbose) {
16219e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entries_init:"
16229e39c5baSBill Taylor " rsrc_type (0x%x) vmem arena not required",
16239e39c5baSBill Taylor rsrc_pool->rsrc_type);
16249e39c5baSBill Taylor }
16259e39c5baSBill Taylor }
16269e39c5baSBill Taylor
16279e39c5baSBill Taylor /* Allocate hardware reserved resources, if any */
16289e39c5baSBill Taylor if (num_prealloc != 0) {
16299e39c5baSBill Taylor status = hermon_rsrc_alloc(state, rsrc_pool->rsrc_type,
16309e39c5baSBill Taylor num_prealloc, HERMON_SLEEP, &rsvd_rsrc);
16319e39c5baSBill Taylor if (status != DDI_SUCCESS) {
16329e39c5baSBill Taylor /* unable to preallocate the reserved entries */
16339e39c5baSBill Taylor if (rsrc_pool->rsrc_vmp != NULL) {
16349e39c5baSBill Taylor vmem_destroy(rsrc_pool->rsrc_vmp);
16359e39c5baSBill Taylor }
16369e39c5baSBill Taylor return (DDI_FAILURE);
16379e39c5baSBill Taylor }
16389e39c5baSBill Taylor }
16399e39c5baSBill Taylor rsrc_pool->rsrc_private = rsvd_rsrc;
16409e39c5baSBill Taylor
16419e39c5baSBill Taylor return (DDI_SUCCESS);
16429e39c5baSBill Taylor }
16439e39c5baSBill Taylor
16449e39c5baSBill Taylor
16459e39c5baSBill Taylor /*
16469e39c5baSBill Taylor * hermon_rsrc_hw_entries_fini()
16479e39c5baSBill Taylor * Context: Only called from attach() and/or detach() path contexts
16489e39c5baSBill Taylor */
16499e39c5baSBill Taylor void
hermon_rsrc_hw_entries_fini(hermon_state_t * state,hermon_rsrc_hw_entry_info_t * info)16509e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(hermon_state_t *state,
16519e39c5baSBill Taylor hermon_rsrc_hw_entry_info_t *info)
16529e39c5baSBill Taylor {
16539e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool;
16549e39c5baSBill Taylor hermon_rsrc_t *rsvd_rsrc;
16559e39c5baSBill Taylor
16569e39c5baSBill Taylor ASSERT(state != NULL);
16579e39c5baSBill Taylor ASSERT(info != NULL);
16589e39c5baSBill Taylor
16599e39c5baSBill Taylor rsrc_pool = info->hwi_rsrcpool;
16609e39c5baSBill Taylor ASSERT(rsrc_pool != NULL);
16619e39c5baSBill Taylor
16629e39c5baSBill Taylor /* Free up any "reserved" (i.e. preallocated) HW entries */
16639e39c5baSBill Taylor rsvd_rsrc = (hermon_rsrc_t *)rsrc_pool->rsrc_private;
16649e39c5baSBill Taylor if (rsvd_rsrc != NULL) {
16659e39c5baSBill Taylor hermon_rsrc_free(state, &rsvd_rsrc);
16669e39c5baSBill Taylor }
16679e39c5baSBill Taylor
16689e39c5baSBill Taylor /*
16699e39c5baSBill Taylor * If we've actually setup a vmem arena for the HW entries, then
16709e39c5baSBill Taylor * destroy it now
16719e39c5baSBill Taylor */
16729e39c5baSBill Taylor if (rsrc_pool->rsrc_vmp != NULL) {
16739e39c5baSBill Taylor vmem_destroy(rsrc_pool->rsrc_vmp);
16749e39c5baSBill Taylor }
16759e39c5baSBill Taylor }
16769e39c5baSBill Taylor
16779e39c5baSBill Taylor
16789e39c5baSBill Taylor /*
16799e39c5baSBill Taylor * hermon_rsrc_sw_handles_init()
16809e39c5baSBill Taylor * Context: Only called from attach() path context
16819e39c5baSBill Taylor */
16829e39c5baSBill Taylor /* ARGSUSED */
16839e39c5baSBill Taylor static int
hermon_rsrc_sw_handles_init(hermon_state_t * state,hermon_rsrc_sw_hdl_info_t * info)16849e39c5baSBill Taylor hermon_rsrc_sw_handles_init(hermon_state_t *state,
16859e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t *info)
16869e39c5baSBill Taylor {
16879e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool;
16889e39c5baSBill Taylor uint64_t num_swhdl, max_swhdl, prealloc_sz;
16899e39c5baSBill Taylor
16909e39c5baSBill Taylor ASSERT(state != NULL);
16919e39c5baSBill Taylor ASSERT(info != NULL);
16929e39c5baSBill Taylor
16939e39c5baSBill Taylor rsrc_pool = info->swi_rsrcpool;
16949e39c5baSBill Taylor ASSERT(rsrc_pool != NULL);
16959e39c5baSBill Taylor num_swhdl = info->swi_num;
16969e39c5baSBill Taylor max_swhdl = info->swi_max;
16979e39c5baSBill Taylor prealloc_sz = info->swi_prealloc_sz;
16989e39c5baSBill Taylor
16999e39c5baSBill Taylor
17009e39c5baSBill Taylor /* Make sure number of SW handles makes sense */
17019e39c5baSBill Taylor if (num_swhdl > max_swhdl) {
17029e39c5baSBill Taylor return (DDI_FAILURE);
17039e39c5baSBill Taylor }
17049e39c5baSBill Taylor
17059e39c5baSBill Taylor /*
17069e39c5baSBill Taylor * Depending on the flags parameter, create a kmem_cache for some
17079e39c5baSBill Taylor * number of software handle structures. Note: kmem_cache_create()
17089e39c5baSBill Taylor * will SLEEP until successful.
17099e39c5baSBill Taylor */
17109e39c5baSBill Taylor if (info->swi_flags & HERMON_SWHDL_KMEMCACHE_INIT) {
17119e39c5baSBill Taylor rsrc_pool->rsrc_private = kmem_cache_create(
17129e39c5baSBill Taylor info->swi_rsrcname, rsrc_pool->rsrc_quantum, 0,
17139e39c5baSBill Taylor info->swi_constructor, info->swi_destructor, NULL,
17149e39c5baSBill Taylor rsrc_pool->rsrc_state, NULL, 0);
17159e39c5baSBill Taylor }
17169e39c5baSBill Taylor
17179e39c5baSBill Taylor
17189e39c5baSBill Taylor /* Allocate the central list of SW handle pointers */
17199e39c5baSBill Taylor if (info->swi_flags & HERMON_SWHDL_TABLE_INIT) {
17209e39c5baSBill Taylor info->swi_table_ptr = kmem_zalloc(num_swhdl * prealloc_sz,
17219e39c5baSBill Taylor KM_SLEEP);
17229e39c5baSBill Taylor }
17239e39c5baSBill Taylor
17249e39c5baSBill Taylor return (DDI_SUCCESS);
17259e39c5baSBill Taylor }
17269e39c5baSBill Taylor
17279e39c5baSBill Taylor
17289e39c5baSBill Taylor /*
17299e39c5baSBill Taylor * hermon_rsrc_sw_handles_fini()
17309e39c5baSBill Taylor * Context: Only called from attach() and/or detach() path contexts
17319e39c5baSBill Taylor */
17329e39c5baSBill Taylor /* ARGSUSED */
17339e39c5baSBill Taylor static void
hermon_rsrc_sw_handles_fini(hermon_state_t * state,hermon_rsrc_sw_hdl_info_t * info)17349e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(hermon_state_t *state,
17359e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t *info)
17369e39c5baSBill Taylor {
17379e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool;
17389e39c5baSBill Taylor uint64_t num_swhdl, prealloc_sz;
17399e39c5baSBill Taylor
17409e39c5baSBill Taylor ASSERT(state != NULL);
17419e39c5baSBill Taylor ASSERT(info != NULL);
17429e39c5baSBill Taylor
17439e39c5baSBill Taylor rsrc_pool = info->swi_rsrcpool;
17449e39c5baSBill Taylor num_swhdl = info->swi_num;
17459e39c5baSBill Taylor prealloc_sz = info->swi_prealloc_sz;
17469e39c5baSBill Taylor
17479e39c5baSBill Taylor /*
17489e39c5baSBill Taylor * If a "software handle" kmem_cache exists for this resource, then
17499e39c5baSBill Taylor * destroy it now
17509e39c5baSBill Taylor */
17519e39c5baSBill Taylor if (rsrc_pool != NULL) {
17529e39c5baSBill Taylor kmem_cache_destroy(rsrc_pool->rsrc_private);
17539e39c5baSBill Taylor }
17549e39c5baSBill Taylor
17559e39c5baSBill Taylor /* Free up this central list of SW handle pointers */
17569e39c5baSBill Taylor if (info->swi_table_ptr != NULL) {
17579e39c5baSBill Taylor kmem_free(info->swi_table_ptr, num_swhdl * prealloc_sz);
17589e39c5baSBill Taylor }
17599e39c5baSBill Taylor }
17609e39c5baSBill Taylor
17619e39c5baSBill Taylor
17629e39c5baSBill Taylor /*
17639e39c5baSBill Taylor * hermon_rsrc_pd_handles_init()
17649e39c5baSBill Taylor * Context: Only called from attach() path context
17659e39c5baSBill Taylor */
17669e39c5baSBill Taylor static int
hermon_rsrc_pd_handles_init(hermon_state_t * state,hermon_rsrc_sw_hdl_info_t * info)17679e39c5baSBill Taylor hermon_rsrc_pd_handles_init(hermon_state_t *state,
17689e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t *info)
17699e39c5baSBill Taylor {
17709e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool;
17719e39c5baSBill Taylor vmem_t *vmp;
17729e39c5baSBill Taylor char vmem_name[HERMON_RSRC_NAME_MAXLEN];
17739e39c5baSBill Taylor int status;
17749e39c5baSBill Taylor
17759e39c5baSBill Taylor ASSERT(state != NULL);
17769e39c5baSBill Taylor ASSERT(info != NULL);
17779e39c5baSBill Taylor
17789e39c5baSBill Taylor rsrc_pool = info->swi_rsrcpool;
17799e39c5baSBill Taylor ASSERT(rsrc_pool != NULL);
17809e39c5baSBill Taylor
17819e39c5baSBill Taylor /* Initialize the resource pool for software handle table */
17829e39c5baSBill Taylor status = hermon_rsrc_sw_handles_init(state, info);
17839e39c5baSBill Taylor if (status != DDI_SUCCESS) {
17849e39c5baSBill Taylor return (DDI_FAILURE);
17859e39c5baSBill Taylor }
17869e39c5baSBill Taylor
17879e39c5baSBill Taylor /* Build vmem arena name from Hermon instance */
17889e39c5baSBill Taylor HERMON_RSRC_NAME(vmem_name, HERMON_PDHDL_VMEM);
17899e39c5baSBill Taylor
17909e39c5baSBill Taylor /* Create new vmem arena for PD numbers */
17919e39c5baSBill Taylor vmp = vmem_create(vmem_name, (caddr_t)1, info->swi_num, 1, NULL,
17929e39c5baSBill Taylor NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER);
17939e39c5baSBill Taylor if (vmp == NULL) {
17949e39c5baSBill Taylor /* Unable to create vmem arena */
17959e39c5baSBill Taylor info->swi_table_ptr = NULL;
17969e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, info);
17979e39c5baSBill Taylor return (DDI_FAILURE);
17989e39c5baSBill Taylor }
17999e39c5baSBill Taylor rsrc_pool->rsrc_vmp = vmp;
18009e39c5baSBill Taylor
18019e39c5baSBill Taylor return (DDI_SUCCESS);
18029e39c5baSBill Taylor }
18039e39c5baSBill Taylor
18049e39c5baSBill Taylor
18059e39c5baSBill Taylor /*
18069e39c5baSBill Taylor * hermon_rsrc_pd_handles_fini()
18079e39c5baSBill Taylor * Context: Only called from attach() and/or detach() path contexts
18089e39c5baSBill Taylor */
18099e39c5baSBill Taylor static void
hermon_rsrc_pd_handles_fini(hermon_state_t * state,hermon_rsrc_sw_hdl_info_t * info)18109e39c5baSBill Taylor hermon_rsrc_pd_handles_fini(hermon_state_t *state,
18119e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t *info)
18129e39c5baSBill Taylor {
18139e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool;
18149e39c5baSBill Taylor
18159e39c5baSBill Taylor ASSERT(state != NULL);
18169e39c5baSBill Taylor ASSERT(info != NULL);
18179e39c5baSBill Taylor
18189e39c5baSBill Taylor rsrc_pool = info->swi_rsrcpool;
18199e39c5baSBill Taylor
18209e39c5baSBill Taylor /* Destroy the specially created UAR scratch table vmem arena */
18219e39c5baSBill Taylor vmem_destroy(rsrc_pool->rsrc_vmp);
18229e39c5baSBill Taylor
18239e39c5baSBill Taylor /* Destroy the "hermon_sw_pd_t" kmem_cache */
18249e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, info);
18259e39c5baSBill Taylor }
18269e39c5baSBill Taylor
18279e39c5baSBill Taylor
18289e39c5baSBill Taylor /*
18299e39c5baSBill Taylor * hermon_rsrc_mbox_alloc()
18309e39c5baSBill Taylor * Context: Only called from attach() path context
18319e39c5baSBill Taylor */
18329e39c5baSBill Taylor static int
hermon_rsrc_mbox_alloc(hermon_rsrc_pool_info_t * pool_info,uint_t num,hermon_rsrc_t * hdl)18339e39c5baSBill Taylor hermon_rsrc_mbox_alloc(hermon_rsrc_pool_info_t *pool_info, uint_t num,
18349e39c5baSBill Taylor hermon_rsrc_t *hdl)
18359e39c5baSBill Taylor {
18369e39c5baSBill Taylor hermon_rsrc_priv_mbox_t *priv;
18379e39c5baSBill Taylor caddr_t kaddr;
18389e39c5baSBill Taylor size_t real_len, temp_len;
18399e39c5baSBill Taylor int status;
18409e39c5baSBill Taylor
18419e39c5baSBill Taylor ASSERT(pool_info != NULL);
18429e39c5baSBill Taylor ASSERT(hdl != NULL);
18439e39c5baSBill Taylor
18449e39c5baSBill Taylor /* Get the private pointer for the mailboxes */
18459e39c5baSBill Taylor priv = pool_info->rsrc_private;
18469e39c5baSBill Taylor ASSERT(priv != NULL);
18479e39c5baSBill Taylor
18489e39c5baSBill Taylor /* Allocate a DMA handle for the mailbox */
18499e39c5baSBill Taylor status = ddi_dma_alloc_handle(priv->pmb_dip, &priv->pmb_dmaattr,
18509e39c5baSBill Taylor DDI_DMA_SLEEP, NULL, &hdl->hr_dmahdl);
18519e39c5baSBill Taylor if (status != DDI_SUCCESS) {
18529e39c5baSBill Taylor return (DDI_FAILURE);
18539e39c5baSBill Taylor }
18549e39c5baSBill Taylor
18559e39c5baSBill Taylor /* Allocate memory for the mailbox */
185617a2b317SBill Taylor temp_len = (num << pool_info->rsrc_shift);
18579e39c5baSBill Taylor status = ddi_dma_mem_alloc(hdl->hr_dmahdl, temp_len,
18589e39c5baSBill Taylor &priv->pmb_devaccattr, priv->pmb_xfer_mode, DDI_DMA_SLEEP,
18599e39c5baSBill Taylor NULL, &kaddr, &real_len, &hdl->hr_acchdl);
18609e39c5baSBill Taylor if (status != DDI_SUCCESS) {
18619e39c5baSBill Taylor /* No more memory available for mailbox entries */
18629e39c5baSBill Taylor ddi_dma_free_handle(&hdl->hr_dmahdl);
18639e39c5baSBill Taylor return (DDI_FAILURE);
18649e39c5baSBill Taylor }
18659e39c5baSBill Taylor
18669e39c5baSBill Taylor hdl->hr_addr = (void *)kaddr;
18679e39c5baSBill Taylor hdl->hr_len = (uint32_t)real_len;
18689e39c5baSBill Taylor
18699e39c5baSBill Taylor return (DDI_SUCCESS);
18709e39c5baSBill Taylor }
18719e39c5baSBill Taylor
18729e39c5baSBill Taylor
18739e39c5baSBill Taylor /*
18749e39c5baSBill Taylor * hermon_rsrc_mbox_free()
18759e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
18769e39c5baSBill Taylor */
18779e39c5baSBill Taylor static void
hermon_rsrc_mbox_free(hermon_rsrc_t * hdl)187817a2b317SBill Taylor hermon_rsrc_mbox_free(hermon_rsrc_t *hdl)
18799e39c5baSBill Taylor {
18809e39c5baSBill Taylor ASSERT(hdl != NULL);
18819e39c5baSBill Taylor
18829e39c5baSBill Taylor /* Use ddi_dma_mem_free() to free up sys memory for mailbox */
18839e39c5baSBill Taylor ddi_dma_mem_free(&hdl->hr_acchdl);
18849e39c5baSBill Taylor
18859e39c5baSBill Taylor /* Free the DMA handle for the mailbox */
18869e39c5baSBill Taylor ddi_dma_free_handle(&hdl->hr_dmahdl);
18879e39c5baSBill Taylor }
18889e39c5baSBill Taylor
18899e39c5baSBill Taylor
18909e39c5baSBill Taylor /*
18919e39c5baSBill Taylor * hermon_rsrc_hw_entry_alloc()
18929e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
18939e39c5baSBill Taylor */
18949e39c5baSBill Taylor static int
hermon_rsrc_hw_entry_alloc(hermon_rsrc_pool_info_t * pool_info,uint_t num,uint_t num_align,uint_t sleepflag,hermon_rsrc_t * hdl)18959e39c5baSBill Taylor hermon_rsrc_hw_entry_alloc(hermon_rsrc_pool_info_t *pool_info, uint_t num,
189617a2b317SBill Taylor uint_t num_align, uint_t sleepflag, hermon_rsrc_t *hdl)
18979e39c5baSBill Taylor {
18989e39c5baSBill Taylor void *addr;
18999e39c5baSBill Taylor uint64_t offset;
19009e39c5baSBill Taylor uint32_t align;
19019e39c5baSBill Taylor int status;
19029e39c5baSBill Taylor int flag;
19039e39c5baSBill Taylor
19049e39c5baSBill Taylor ASSERT(pool_info != NULL);
19059e39c5baSBill Taylor ASSERT(hdl != NULL);
19069e39c5baSBill Taylor
19079e39c5baSBill Taylor /*
19089e39c5baSBill Taylor * Use vmem_xalloc() to get a properly aligned pointer (based on
19099e39c5baSBill Taylor * the number requested) to the HW entry(ies). This handles the
19109e39c5baSBill Taylor * cases (for special QPCs and for RDB entries) where we need more
19119e39c5baSBill Taylor * than one and need to ensure that they are properly aligned.
19129e39c5baSBill Taylor */
19139e39c5baSBill Taylor flag = (sleepflag == HERMON_SLEEP) ? VM_SLEEP : VM_NOSLEEP;
191417a2b317SBill Taylor hdl->hr_len = (num << pool_info->rsrc_shift);
191517a2b317SBill Taylor align = (num_align << pool_info->rsrc_shift);
19169e39c5baSBill Taylor
19179e39c5baSBill Taylor addr = vmem_xalloc(pool_info->rsrc_vmp, hdl->hr_len,
19189e39c5baSBill Taylor align, 0, 0, NULL, NULL, flag | VM_FIRSTFIT);
19199e39c5baSBill Taylor
19209e39c5baSBill Taylor if (addr == NULL) {
19219e39c5baSBill Taylor /* No more HW entries available */
19229e39c5baSBill Taylor return (DDI_FAILURE);
19239e39c5baSBill Taylor }
19249e39c5baSBill Taylor
192517a2b317SBill Taylor hdl->hr_acchdl = NULL; /* only used for mbox resources */
19269e39c5baSBill Taylor
19279e39c5baSBill Taylor /* Calculate vaddr and HW table index */
19289e39c5baSBill Taylor offset = (uintptr_t)addr - (uintptr_t)pool_info->rsrc_start;
192917a2b317SBill Taylor hdl->hr_addr = addr; /* only used for mbox and uarpg resources */
19309e39c5baSBill Taylor hdl->hr_indx = offset >> pool_info->rsrc_shift;
19319e39c5baSBill Taylor
19329e39c5baSBill Taylor if (pool_info->rsrc_loc == HERMON_IN_ICM) {
193317a2b317SBill Taylor int num_to_hdl;
193417a2b317SBill Taylor hermon_rsrc_type_t rsrc_type = pool_info->rsrc_type;
193517a2b317SBill Taylor
193617a2b317SBill Taylor num_to_hdl = (rsrc_type == HERMON_QPC ||
193717a2b317SBill Taylor rsrc_type == HERMON_CQC || rsrc_type == HERMON_SRQC);
193817a2b317SBill Taylor
19399e39c5baSBill Taylor /* confirm ICM is mapped, and allocate if necessary */
194017a2b317SBill Taylor status = hermon_rsrc_hw_entry_icm_confirm(pool_info, num, hdl,
194117a2b317SBill Taylor num_to_hdl);
19429e39c5baSBill Taylor if (status != DDI_SUCCESS) {
19439e39c5baSBill Taylor return (DDI_FAILURE);
19449e39c5baSBill Taylor }
194517a2b317SBill Taylor hdl->hr_addr = NULL; /* not used for ICM resources */
19469e39c5baSBill Taylor }
19479e39c5baSBill Taylor
19489e39c5baSBill Taylor return (DDI_SUCCESS);
19499e39c5baSBill Taylor }
19509e39c5baSBill Taylor
19519e39c5baSBill Taylor
195217a2b317SBill Taylor /*
195317a2b317SBill Taylor * hermon_rsrc_hw_entry_reserve()
195417a2b317SBill Taylor * Context: Can be called from interrupt or base context.
195517a2b317SBill Taylor */
195617a2b317SBill Taylor int
hermon_rsrc_hw_entry_reserve(hermon_rsrc_pool_info_t * pool_info,uint_t num,uint_t num_align,uint_t sleepflag,hermon_rsrc_t * hdl)195717a2b317SBill Taylor hermon_rsrc_hw_entry_reserve(hermon_rsrc_pool_info_t *pool_info, uint_t num,
195817a2b317SBill Taylor uint_t num_align, uint_t sleepflag, hermon_rsrc_t *hdl)
195917a2b317SBill Taylor {
196017a2b317SBill Taylor void *addr;
196117a2b317SBill Taylor uint64_t offset;
196217a2b317SBill Taylor uint32_t align;
196317a2b317SBill Taylor int flag;
196417a2b317SBill Taylor
196517a2b317SBill Taylor ASSERT(pool_info != NULL);
196617a2b317SBill Taylor ASSERT(hdl != NULL);
196717a2b317SBill Taylor ASSERT(pool_info->rsrc_loc == HERMON_IN_ICM);
196817a2b317SBill Taylor
196917a2b317SBill Taylor /*
197017a2b317SBill Taylor * Use vmem_xalloc() to get a properly aligned pointer (based on
197117a2b317SBill Taylor * the number requested) to the HW entry(ies). This handles the
197217a2b317SBill Taylor * cases (for special QPCs and for RDB entries) where we need more
197317a2b317SBill Taylor * than one and need to ensure that they are properly aligned.
197417a2b317SBill Taylor */
197517a2b317SBill Taylor flag = (sleepflag == HERMON_SLEEP) ? VM_SLEEP : VM_NOSLEEP;
197617a2b317SBill Taylor hdl->hr_len = (num << pool_info->rsrc_shift);
197717a2b317SBill Taylor align = (num_align << pool_info->rsrc_shift);
197817a2b317SBill Taylor
197917a2b317SBill Taylor addr = vmem_xalloc(pool_info->rsrc_vmp, hdl->hr_len,
198017a2b317SBill Taylor align, 0, 0, NULL, NULL, flag | VM_FIRSTFIT);
198117a2b317SBill Taylor
198217a2b317SBill Taylor if (addr == NULL) {
198317a2b317SBill Taylor /* No more HW entries available */
198417a2b317SBill Taylor return (DDI_FAILURE);
198517a2b317SBill Taylor }
198617a2b317SBill Taylor
198717a2b317SBill Taylor hdl->hr_acchdl = NULL; /* only used for mbox resources */
198817a2b317SBill Taylor
198917a2b317SBill Taylor /* Calculate vaddr and HW table index */
199017a2b317SBill Taylor offset = (uintptr_t)addr - (uintptr_t)pool_info->rsrc_start;
199117a2b317SBill Taylor hdl->hr_addr = NULL;
199217a2b317SBill Taylor hdl->hr_indx = offset >> pool_info->rsrc_shift;
199317a2b317SBill Taylor
199417a2b317SBill Taylor /* ICM will be allocated and mapped if and when it gets used */
199517a2b317SBill Taylor
199617a2b317SBill Taylor return (DDI_SUCCESS);
199717a2b317SBill Taylor }
199817a2b317SBill Taylor
19999e39c5baSBill Taylor
20009e39c5baSBill Taylor /*
20019e39c5baSBill Taylor * hermon_rsrc_hw_entry_free()
20029e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
20039e39c5baSBill Taylor */
20049e39c5baSBill Taylor static void
hermon_rsrc_hw_entry_free(hermon_rsrc_pool_info_t * pool_info,hermon_rsrc_t * hdl)20059e39c5baSBill Taylor hermon_rsrc_hw_entry_free(hermon_rsrc_pool_info_t *pool_info,
20069e39c5baSBill Taylor hermon_rsrc_t *hdl)
20079e39c5baSBill Taylor {
20089e39c5baSBill Taylor void *addr;
20099e39c5baSBill Taylor uint64_t offset;
20109e39c5baSBill Taylor int status;
20119e39c5baSBill Taylor
20129e39c5baSBill Taylor ASSERT(pool_info != NULL);
20139e39c5baSBill Taylor ASSERT(hdl != NULL);
20149e39c5baSBill Taylor
20159e39c5baSBill Taylor /* Calculate the allocated address */
20169e39c5baSBill Taylor offset = hdl->hr_indx << pool_info->rsrc_shift;
20179e39c5baSBill Taylor addr = (void *)(uintptr_t)(offset + (uintptr_t)pool_info->rsrc_start);
20189e39c5baSBill Taylor
20199e39c5baSBill Taylor /* Use vmem_xfree() to free up the HW table entry */
20209e39c5baSBill Taylor vmem_xfree(pool_info->rsrc_vmp, addr, hdl->hr_len);
20219e39c5baSBill Taylor
20229e39c5baSBill Taylor if (pool_info->rsrc_loc == HERMON_IN_ICM) {
202317a2b317SBill Taylor int num_to_hdl;
202417a2b317SBill Taylor hermon_rsrc_type_t rsrc_type = pool_info->rsrc_type;
202517a2b317SBill Taylor
202617a2b317SBill Taylor num_to_hdl = (rsrc_type == HERMON_QPC ||
202717a2b317SBill Taylor rsrc_type == HERMON_CQC || rsrc_type == HERMON_SRQC);
202817a2b317SBill Taylor
20299e39c5baSBill Taylor /* free ICM references, and free ICM if required */
203017a2b317SBill Taylor status = hermon_rsrc_hw_entry_icm_free(pool_info, hdl,
203117a2b317SBill Taylor num_to_hdl);
20329e39c5baSBill Taylor if (status != DDI_SUCCESS)
20339e39c5baSBill Taylor HERMON_WARNING(pool_info->rsrc_state,
20349e39c5baSBill Taylor "failure in hw_entry_free");
20359e39c5baSBill Taylor }
20369e39c5baSBill Taylor }
20379e39c5baSBill Taylor
20389e39c5baSBill Taylor /*
20399e39c5baSBill Taylor * hermon_rsrc_hw_entry_icm_confirm()
20409e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
20419e39c5baSBill Taylor */
20429e39c5baSBill Taylor static int
hermon_rsrc_hw_entry_icm_confirm(hermon_rsrc_pool_info_t * pool_info,uint_t num,hermon_rsrc_t * hdl,int num_to_hdl)20439e39c5baSBill Taylor hermon_rsrc_hw_entry_icm_confirm(hermon_rsrc_pool_info_t *pool_info, uint_t num,
204417a2b317SBill Taylor hermon_rsrc_t *hdl, int num_to_hdl)
20459e39c5baSBill Taylor {
20469e39c5baSBill Taylor hermon_state_t *state;
20479e39c5baSBill Taylor hermon_icm_table_t *icm_table;
20489e39c5baSBill Taylor uint8_t *bitmap;
20499e39c5baSBill Taylor hermon_dma_info_t *dma_info;
20509e39c5baSBill Taylor hermon_rsrc_type_t type;
20519e39c5baSBill Taylor uint32_t rindx, span_offset;
20529e39c5baSBill Taylor uint32_t span_avail;
20539e39c5baSBill Taylor int num_backed;
20549e39c5baSBill Taylor int status;
20559e39c5baSBill Taylor uint32_t index1, index2;
20569e39c5baSBill Taylor
20579e39c5baSBill Taylor /*
20589e39c5baSBill Taylor * Utility routine responsible for ensuring that there is memory
20599e39c5baSBill Taylor * backing the ICM resources allocated via hermon_rsrc_hw_entry_alloc().
20609e39c5baSBill Taylor * Confirm existing ICM mapping(s) or allocate ICM memory for the
20619e39c5baSBill Taylor * given hardware resources being allocated, and increment the
20629e39c5baSBill Taylor * ICM DMA structure(s) reference count.
20639e39c5baSBill Taylor *
20649e39c5baSBill Taylor * We may be allocating more objects than can fit in a single span,
20659e39c5baSBill Taylor * or more than will fit in the remaining contiguous memory (from
20669e39c5baSBill Taylor * the offset indicated by hdl->ar_indx) in the span in question.
20679e39c5baSBill Taylor * In either of these cases, we'll be breaking up our allocation
20689e39c5baSBill Taylor * into multiple spans.
20699e39c5baSBill Taylor */
20709e39c5baSBill Taylor state = pool_info->rsrc_state;
20719e39c5baSBill Taylor type = pool_info->rsrc_type;
20729e39c5baSBill Taylor icm_table = &state->hs_icm[type];
20739e39c5baSBill Taylor
20749e39c5baSBill Taylor rindx = hdl->hr_indx;
20759e39c5baSBill Taylor hermon_index(index1, index2, rindx, icm_table, span_offset);
20769e39c5baSBill Taylor
20779e39c5baSBill Taylor if (hermon_rsrc_verbose) {
20789e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entry_icm_confirm: "
20799e39c5baSBill Taylor "type (0x%x) num (0x%x) length (0x%x) index (0x%x, 0x%x): ",
20809e39c5baSBill Taylor type, num, hdl->hr_len, index1, index2);
20819e39c5baSBill Taylor }
20829e39c5baSBill Taylor
20839e39c5baSBill Taylor mutex_enter(&icm_table->icm_table_lock);
208417a2b317SBill Taylor hermon_bitmap(bitmap, dma_info, icm_table, index1, num_to_hdl);
20859e39c5baSBill Taylor while (num) {
20869e39c5baSBill Taylor #ifndef __lock_lint
20879e39c5baSBill Taylor while (icm_table->icm_busy) {
20889e39c5baSBill Taylor cv_wait(&icm_table->icm_table_cv,
20899e39c5baSBill Taylor &icm_table->icm_table_lock);
20909e39c5baSBill Taylor }
20919e39c5baSBill Taylor #endif
20929e39c5baSBill Taylor if (!HERMON_BMAP_BIT_ISSET(bitmap, index2)) {
20939e39c5baSBill Taylor /* Allocate ICM for this span */
20949e39c5baSBill Taylor icm_table->icm_busy = 1;
20959e39c5baSBill Taylor mutex_exit(&icm_table->icm_table_lock);
20969e39c5baSBill Taylor status = hermon_icm_alloc(state, type, index1, index2);
20979e39c5baSBill Taylor mutex_enter(&icm_table->icm_table_lock);
20989e39c5baSBill Taylor icm_table->icm_busy = 0;
20999e39c5baSBill Taylor cv_broadcast(&icm_table->icm_table_cv);
21009e39c5baSBill Taylor if (status != DDI_SUCCESS) {
21019e39c5baSBill Taylor goto fail_alloc;
21029e39c5baSBill Taylor }
21039e39c5baSBill Taylor if (hermon_rsrc_verbose) {
21049e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "hermon_rsrc_"
21059e39c5baSBill Taylor "hw_entry_icm_confirm: ALLOCATED ICM: "
21069e39c5baSBill Taylor "type (0x%x) index (0x%x, 0x%x)",
21079e39c5baSBill Taylor type, index1, index2);
21089e39c5baSBill Taylor }
21099e39c5baSBill Taylor }
21109e39c5baSBill Taylor
21119e39c5baSBill Taylor /*
21129e39c5baSBill Taylor * We need to increment the refcnt of this span by the
21139e39c5baSBill Taylor * number of objects in this resource allocation that are
21149e39c5baSBill Taylor * backed by this span. Given that the rsrc allocation is
21159e39c5baSBill Taylor * contiguous, this value will be the number of objects in
21169e39c5baSBill Taylor * the span from 'span_offset' onward, either up to a max
21179e39c5baSBill Taylor * of the total number of objects, or the end of the span.
21189e39c5baSBill Taylor * So, determine the number of objects that can be backed
21199e39c5baSBill Taylor * by this span ('span_avail'), then determine the number
21209e39c5baSBill Taylor * of backed resources.
21219e39c5baSBill Taylor */
21229e39c5baSBill Taylor span_avail = icm_table->span - span_offset;
21239e39c5baSBill Taylor if (num > span_avail) {
21249e39c5baSBill Taylor num_backed = span_avail;
21259e39c5baSBill Taylor } else {
21269e39c5baSBill Taylor num_backed = num;
21279e39c5baSBill Taylor }
21289e39c5baSBill Taylor
21299e39c5baSBill Taylor /*
21309e39c5baSBill Taylor * Now that we know 'num_backed', increment the refcnt,
21319e39c5baSBill Taylor * decrement the total number, and set 'span_offset' to
21329e39c5baSBill Taylor * 0 in case we roll over into the next span.
21339e39c5baSBill Taylor */
21349e39c5baSBill Taylor dma_info[index2].icm_refcnt += num_backed;
21359e39c5baSBill Taylor rindx += num_backed;
21369e39c5baSBill Taylor num -= num_backed;
21379e39c5baSBill Taylor
21389e39c5baSBill Taylor if (hermon_rsrc_verbose) {
21399e39c5baSBill Taylor IBTF_DPRINTF_L2("ALLOC", "ICM type (0x%x) index "
21409e39c5baSBill Taylor "(0x%x, 0x%x) num_backed (0x%x)",
21419e39c5baSBill Taylor type, index1, index2, num_backed);
21429e39c5baSBill Taylor IBTF_DPRINTF_L2("ALLOC", "ICM type (0x%x) refcnt now "
21439e39c5baSBill Taylor "(0x%x) num_remaining (0x%x)", type,
21449e39c5baSBill Taylor dma_info[index2].icm_refcnt, num);
21459e39c5baSBill Taylor }
21469e39c5baSBill Taylor if (num == 0)
21479e39c5baSBill Taylor break;
21489e39c5baSBill Taylor
21499e39c5baSBill Taylor hermon_index(index1, index2, rindx, icm_table, span_offset);
215017a2b317SBill Taylor hermon_bitmap(bitmap, dma_info, icm_table, index1, num_to_hdl);
21519e39c5baSBill Taylor }
21529e39c5baSBill Taylor mutex_exit(&icm_table->icm_table_lock);
21539e39c5baSBill Taylor
21549e39c5baSBill Taylor return (DDI_SUCCESS);
21559e39c5baSBill Taylor
21569e39c5baSBill Taylor fail_alloc:
21579e39c5baSBill Taylor /* JBDB */
21589e39c5baSBill Taylor if (hermon_rsrc_verbose) {
21599e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "hermon_rsrc_"
21609e39c5baSBill Taylor "hw_entry_icm_confirm: FAILED ICM ALLOC: "
21619e39c5baSBill Taylor "type (0x%x) num remaind (0x%x) index (0x%x, 0x%x)"
21629e39c5baSBill Taylor "refcnt (0x%x)", type, num, index1, index2,
21639e39c5baSBill Taylor icm_table->icm_dma[index1][index2].icm_refcnt);
21649e39c5baSBill Taylor }
21659e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "WARNING: "
21669e39c5baSBill Taylor "unimplemented fail code in hermon_rsrc_hw_entry_icm_alloc\n");
21679e39c5baSBill Taylor
21689e39c5baSBill Taylor #if needs_work
21699e39c5baSBill Taylor /* free refcnt's and any spans we've allocated */
21709e39c5baSBill Taylor while (index-- != start) {
21719e39c5baSBill Taylor /*
21729e39c5baSBill Taylor * JBDB - This is a bit tricky. We need to
21739e39c5baSBill Taylor * free refcnt's on any spans that we've
21749e39c5baSBill Taylor * incremented them on, and completely free
21759e39c5baSBill Taylor * spans that we've allocated. How do we do
21769e39c5baSBill Taylor * this here? Does it need to be as involved
21779e39c5baSBill Taylor * as the core of icm_free() below, or can
21789e39c5baSBill Taylor * we leverage breadcrumbs somehow?
21799e39c5baSBill Taylor */
21809e39c5baSBill Taylor HERMON_WARNING(state, "unable to allocate ICM memory: "
21819e39c5baSBill Taylor "UNIMPLEMENTED HANDLING!!");
21829e39c5baSBill Taylor }
21839e39c5baSBill Taylor #else
21849e39c5baSBill Taylor cmn_err(CE_WARN,
21859e39c5baSBill Taylor "unimplemented fail code in hermon_rsrc_hw_entry_icm_alloc\n");
21869e39c5baSBill Taylor #endif
21879e39c5baSBill Taylor mutex_exit(&icm_table->icm_table_lock);
21889e39c5baSBill Taylor
21899e39c5baSBill Taylor HERMON_WARNING(state, "unable to allocate ICM memory");
21909e39c5baSBill Taylor return (DDI_FAILURE);
21919e39c5baSBill Taylor }
21929e39c5baSBill Taylor
21939e39c5baSBill Taylor /*
21949e39c5baSBill Taylor * hermon_rsrc_hw_entry_icm_free()
21959e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
21969e39c5baSBill Taylor */
21979e39c5baSBill Taylor static int
hermon_rsrc_hw_entry_icm_free(hermon_rsrc_pool_info_t * pool_info,hermon_rsrc_t * hdl,int num_to_hdl)21989e39c5baSBill Taylor hermon_rsrc_hw_entry_icm_free(hermon_rsrc_pool_info_t *pool_info,
219917a2b317SBill Taylor hermon_rsrc_t *hdl, int num_to_hdl)
22009e39c5baSBill Taylor {
22019e39c5baSBill Taylor hermon_state_t *state;
22029e39c5baSBill Taylor hermon_icm_table_t *icm_table;
22039e39c5baSBill Taylor uint8_t *bitmap;
22049e39c5baSBill Taylor hermon_dma_info_t *dma_info;
22059e39c5baSBill Taylor hermon_rsrc_type_t type;
22069e39c5baSBill Taylor uint32_t span_offset;
22079e39c5baSBill Taylor uint32_t span_remain;
22089e39c5baSBill Taylor int num_freed;
22099e39c5baSBill Taylor int num;
22109e39c5baSBill Taylor uint32_t index1, index2, rindx;
22119e39c5baSBill Taylor
22129e39c5baSBill Taylor /*
22139e39c5baSBill Taylor * Utility routine responsible for freeing references to ICM
22149e39c5baSBill Taylor * DMA spans, and freeing the ICM memory if necessary.
22159e39c5baSBill Taylor *
22169e39c5baSBill Taylor * We may have allocated objects in a single contiguous resource
22179e39c5baSBill Taylor * allocation that reside in a number of spans, at any given
22189e39c5baSBill Taylor * starting offset within a span. We therefore must determine
22199e39c5baSBill Taylor * where this allocation starts, and then determine if we need
22209e39c5baSBill Taylor * to free objects in more than one span.
22219e39c5baSBill Taylor */
22229e39c5baSBill Taylor state = pool_info->rsrc_state;
22239e39c5baSBill Taylor type = pool_info->rsrc_type;
22249e39c5baSBill Taylor icm_table = &state->hs_icm[type];
22259e39c5baSBill Taylor
22269e39c5baSBill Taylor rindx = hdl->hr_indx;
22279e39c5baSBill Taylor hermon_index(index1, index2, rindx, icm_table, span_offset);
222817a2b317SBill Taylor hermon_bitmap(bitmap, dma_info, icm_table, index1, num_to_hdl);
22299e39c5baSBill Taylor
22309e39c5baSBill Taylor /* determine the number of ICM objects in this allocation */
22319e39c5baSBill Taylor num = hdl->hr_len >> pool_info->rsrc_shift;
22329e39c5baSBill Taylor
22339e39c5baSBill Taylor if (hermon_rsrc_verbose) {
22349e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entry_icm_free: "
22359e39c5baSBill Taylor "type (0x%x) num (0x%x) length (0x%x) index (0x%x, 0x%x)",
22369e39c5baSBill Taylor type, num, hdl->hr_len, index1, index2);
22379e39c5baSBill Taylor }
22389e39c5baSBill Taylor mutex_enter(&icm_table->icm_table_lock);
22399e39c5baSBill Taylor while (num) {
22409e39c5baSBill Taylor /*
22419e39c5baSBill Taylor * As with the ICM confirm code above, we need to
22429e39c5baSBill Taylor * decrement the ICM span(s) by the number of
22439e39c5baSBill Taylor * resources being freed. So, determine the number
22449e39c5baSBill Taylor * of objects that are backed in this span from
22459e39c5baSBill Taylor * 'span_offset' onward, and set 'num_freed' to
22469e39c5baSBill Taylor * the smaller of either that number ('span_remain'),
22479e39c5baSBill Taylor * or the total number of objects being freed.
22489e39c5baSBill Taylor */
22499e39c5baSBill Taylor span_remain = icm_table->span - span_offset;
22509e39c5baSBill Taylor if (num > span_remain) {
22519e39c5baSBill Taylor num_freed = span_remain;
22529e39c5baSBill Taylor } else {
22539e39c5baSBill Taylor num_freed = num;
22549e39c5baSBill Taylor }
22559e39c5baSBill Taylor
22569e39c5baSBill Taylor /*
22579e39c5baSBill Taylor * Now that we know 'num_freed', decrement the refcnt,
22589e39c5baSBill Taylor * decrement the total number, and set 'span_offset' to
22599e39c5baSBill Taylor * 0 in case we roll over into the next span.
22609e39c5baSBill Taylor */
22619e39c5baSBill Taylor dma_info[index2].icm_refcnt -= num_freed;
22629e39c5baSBill Taylor num -= num_freed;
22639e39c5baSBill Taylor rindx += num_freed;
22649e39c5baSBill Taylor
22659e39c5baSBill Taylor if (hermon_rsrc_verbose) {
22669e39c5baSBill Taylor IBTF_DPRINTF_L2("FREE", "ICM type (0x%x) index "
22679e39c5baSBill Taylor "(0x%x, 0x%x) num_freed (0x%x)", type,
22689e39c5baSBill Taylor index1, index2, num_freed);
22699e39c5baSBill Taylor IBTF_DPRINTF_L2("FREE", "ICM type (0x%x) refcnt now "
22709e39c5baSBill Taylor "(0x%x) num remaining (0x%x)", type,
22719e39c5baSBill Taylor icm_table->icm_dma[index1][index2].icm_refcnt, num);
22729e39c5baSBill Taylor }
22739e39c5baSBill Taylor
22749e39c5baSBill Taylor #if HERMON_ICM_FREE_ENABLED
22759e39c5baSBill Taylor /* If we've freed the last object in this span, free it */
22769e39c5baSBill Taylor if ((index1 != 0 || index2 != 0) &&
22779e39c5baSBill Taylor (dma_info[index2].icm_refcnt == 0)) {
22789e39c5baSBill Taylor if (hermon_rsrc_verbose) {
22799e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entry"
22809e39c5baSBill Taylor "_icm_free: freeing ICM type (0x%x) index"
22819e39c5baSBill Taylor " (0x%x, 0x%x)", type, index1, index2);
22829e39c5baSBill Taylor }
22839e39c5baSBill Taylor hermon_icm_free(state, type, index1, index2);
22849e39c5baSBill Taylor }
22859e39c5baSBill Taylor #endif
22869e39c5baSBill Taylor if (num == 0)
22879e39c5baSBill Taylor break;
22889e39c5baSBill Taylor
22899e39c5baSBill Taylor hermon_index(index1, index2, rindx, icm_table, span_offset);
229017a2b317SBill Taylor hermon_bitmap(bitmap, dma_info, icm_table, index1, num_to_hdl);
22919e39c5baSBill Taylor }
22929e39c5baSBill Taylor mutex_exit(&icm_table->icm_table_lock);
22939e39c5baSBill Taylor
22949e39c5baSBill Taylor return (DDI_SUCCESS);
22959e39c5baSBill Taylor }
22969e39c5baSBill Taylor
22979e39c5baSBill Taylor
22989e39c5baSBill Taylor
22999e39c5baSBill Taylor /*
23009e39c5baSBill Taylor * hermon_rsrc_swhdl_alloc()
23019e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
23029e39c5baSBill Taylor */
23039e39c5baSBill Taylor static int
hermon_rsrc_swhdl_alloc(hermon_rsrc_pool_info_t * pool_info,uint_t sleepflag,hermon_rsrc_t * hdl)23049e39c5baSBill Taylor hermon_rsrc_swhdl_alloc(hermon_rsrc_pool_info_t *pool_info, uint_t sleepflag,
23059e39c5baSBill Taylor hermon_rsrc_t *hdl)
23069e39c5baSBill Taylor {
23079e39c5baSBill Taylor void *addr;
23089e39c5baSBill Taylor int flag;
23099e39c5baSBill Taylor
23109e39c5baSBill Taylor ASSERT(pool_info != NULL);
23119e39c5baSBill Taylor ASSERT(hdl != NULL);
23129e39c5baSBill Taylor
23139e39c5baSBill Taylor /* Allocate the software handle structure */
23149e39c5baSBill Taylor flag = (sleepflag == HERMON_SLEEP) ? KM_SLEEP : KM_NOSLEEP;
23159e39c5baSBill Taylor addr = kmem_cache_alloc(pool_info->rsrc_private, flag);
23169e39c5baSBill Taylor if (addr == NULL) {
23179e39c5baSBill Taylor return (DDI_FAILURE);
23189e39c5baSBill Taylor }
23199e39c5baSBill Taylor hdl->hr_len = pool_info->rsrc_quantum;
23209e39c5baSBill Taylor hdl->hr_addr = addr;
23219e39c5baSBill Taylor
23229e39c5baSBill Taylor return (DDI_SUCCESS);
23239e39c5baSBill Taylor }
23249e39c5baSBill Taylor
23259e39c5baSBill Taylor
23269e39c5baSBill Taylor /*
23279e39c5baSBill Taylor * hermon_rsrc_swhdl_free()
23289e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
23299e39c5baSBill Taylor */
23309e39c5baSBill Taylor static void
hermon_rsrc_swhdl_free(hermon_rsrc_pool_info_t * pool_info,hermon_rsrc_t * hdl)23319e39c5baSBill Taylor hermon_rsrc_swhdl_free(hermon_rsrc_pool_info_t *pool_info, hermon_rsrc_t *hdl)
23329e39c5baSBill Taylor {
23339e39c5baSBill Taylor ASSERT(pool_info != NULL);
23349e39c5baSBill Taylor ASSERT(hdl != NULL);
23359e39c5baSBill Taylor
23369e39c5baSBill Taylor /* Free the software handle structure */
23379e39c5baSBill Taylor kmem_cache_free(pool_info->rsrc_private, hdl->hr_addr);
23389e39c5baSBill Taylor }
23399e39c5baSBill Taylor
23409e39c5baSBill Taylor
23419e39c5baSBill Taylor /*
23429e39c5baSBill Taylor * hermon_rsrc_pdhdl_alloc()
23439e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
23449e39c5baSBill Taylor */
23459e39c5baSBill Taylor static int
hermon_rsrc_pdhdl_alloc(hermon_rsrc_pool_info_t * pool_info,uint_t sleepflag,hermon_rsrc_t * hdl)23469e39c5baSBill Taylor hermon_rsrc_pdhdl_alloc(hermon_rsrc_pool_info_t *pool_info, uint_t sleepflag,
23479e39c5baSBill Taylor hermon_rsrc_t *hdl)
23489e39c5baSBill Taylor {
23499e39c5baSBill Taylor hermon_pdhdl_t addr;
23509e39c5baSBill Taylor void *tmpaddr;
23519e39c5baSBill Taylor int flag, status;
23529e39c5baSBill Taylor
23539e39c5baSBill Taylor ASSERT(pool_info != NULL);
23549e39c5baSBill Taylor ASSERT(hdl != NULL);
23559e39c5baSBill Taylor
23569e39c5baSBill Taylor /* Allocate the software handle */
23579e39c5baSBill Taylor status = hermon_rsrc_swhdl_alloc(pool_info, sleepflag, hdl);
23589e39c5baSBill Taylor if (status != DDI_SUCCESS) {
23599e39c5baSBill Taylor return (DDI_FAILURE);
23609e39c5baSBill Taylor }
23619e39c5baSBill Taylor addr = (hermon_pdhdl_t)hdl->hr_addr;
23629e39c5baSBill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*addr))
23639e39c5baSBill Taylor
23649e39c5baSBill Taylor /* Allocate a PD number for the handle */
23659e39c5baSBill Taylor flag = (sleepflag == HERMON_SLEEP) ? VM_SLEEP : VM_NOSLEEP;
23669e39c5baSBill Taylor tmpaddr = vmem_alloc(pool_info->rsrc_vmp, 1, flag);
23679e39c5baSBill Taylor if (tmpaddr == NULL) {
23689e39c5baSBill Taylor /* No more PD number entries available */
23699e39c5baSBill Taylor hermon_rsrc_swhdl_free(pool_info, hdl);
23709e39c5baSBill Taylor return (DDI_FAILURE);
23719e39c5baSBill Taylor }
23729e39c5baSBill Taylor addr->pd_pdnum = (uint32_t)(uintptr_t)tmpaddr;
23739e39c5baSBill Taylor addr->pd_rsrcp = hdl;
23749e39c5baSBill Taylor hdl->hr_indx = addr->pd_pdnum;
23759e39c5baSBill Taylor
23769e39c5baSBill Taylor return (DDI_SUCCESS);
23779e39c5baSBill Taylor }
23789e39c5baSBill Taylor
23799e39c5baSBill Taylor
23809e39c5baSBill Taylor /*
23819e39c5baSBill Taylor * hermon_rsrc_pdhdl_free()
23829e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
23839e39c5baSBill Taylor */
23849e39c5baSBill Taylor static void
hermon_rsrc_pdhdl_free(hermon_rsrc_pool_info_t * pool_info,hermon_rsrc_t * hdl)23859e39c5baSBill Taylor hermon_rsrc_pdhdl_free(hermon_rsrc_pool_info_t *pool_info, hermon_rsrc_t *hdl)
23869e39c5baSBill Taylor {
23879e39c5baSBill Taylor ASSERT(pool_info != NULL);
23889e39c5baSBill Taylor ASSERT(hdl != NULL);
23899e39c5baSBill Taylor
23909e39c5baSBill Taylor /* Use vmem_free() to free up the PD number */
23919e39c5baSBill Taylor vmem_free(pool_info->rsrc_vmp, (void *)(uintptr_t)hdl->hr_indx, 1);
23929e39c5baSBill Taylor
23939e39c5baSBill Taylor /* Free the software handle structure */
23949e39c5baSBill Taylor hermon_rsrc_swhdl_free(pool_info, hdl);
23959e39c5baSBill Taylor }
23969e39c5baSBill Taylor
23979e39c5baSBill Taylor
23989e39c5baSBill Taylor /*
23999e39c5baSBill Taylor * hermon_rsrc_pdhdl_constructor()
24009e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
24019e39c5baSBill Taylor */
24029e39c5baSBill Taylor /* ARGSUSED */
24039e39c5baSBill Taylor static int
hermon_rsrc_pdhdl_constructor(void * pd,void * priv,int flags)24049e39c5baSBill Taylor hermon_rsrc_pdhdl_constructor(void *pd, void *priv, int flags)
24059e39c5baSBill Taylor {
24069e39c5baSBill Taylor hermon_pdhdl_t pdhdl;
24079e39c5baSBill Taylor hermon_state_t *state;
24089e39c5baSBill Taylor
24099e39c5baSBill Taylor pdhdl = (hermon_pdhdl_t)pd;
24109e39c5baSBill Taylor state = (hermon_state_t *)priv;
24119e39c5baSBill Taylor
24129e39c5baSBill Taylor mutex_init(&pdhdl->pd_lock, NULL, MUTEX_DRIVER,
24139e39c5baSBill Taylor DDI_INTR_PRI(state->hs_intrmsi_pri));
24149e39c5baSBill Taylor
24159e39c5baSBill Taylor return (DDI_SUCCESS);
24169e39c5baSBill Taylor }
24179e39c5baSBill Taylor
24189e39c5baSBill Taylor
24199e39c5baSBill Taylor /*
24209e39c5baSBill Taylor * hermon_rsrc_pdhdl_destructor()
24219e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
24229e39c5baSBill Taylor */
24239e39c5baSBill Taylor /* ARGSUSED */
24249e39c5baSBill Taylor static void
hermon_rsrc_pdhdl_destructor(void * pd,void * priv)24259e39c5baSBill Taylor hermon_rsrc_pdhdl_destructor(void *pd, void *priv)
24269e39c5baSBill Taylor {
24279e39c5baSBill Taylor hermon_pdhdl_t pdhdl;
24289e39c5baSBill Taylor
24299e39c5baSBill Taylor pdhdl = (hermon_pdhdl_t)pd;
24309e39c5baSBill Taylor
24319e39c5baSBill Taylor mutex_destroy(&pdhdl->pd_lock);
24329e39c5baSBill Taylor }
24339e39c5baSBill Taylor
24349e39c5baSBill Taylor
24359e39c5baSBill Taylor /*
24369e39c5baSBill Taylor * hermon_rsrc_cqhdl_constructor()
24379e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
24389e39c5baSBill Taylor */
24399e39c5baSBill Taylor /* ARGSUSED */
24409e39c5baSBill Taylor static int
hermon_rsrc_cqhdl_constructor(void * cq,void * priv,int flags)24419e39c5baSBill Taylor hermon_rsrc_cqhdl_constructor(void *cq, void *priv, int flags)
24429e39c5baSBill Taylor {
24439e39c5baSBill Taylor hermon_cqhdl_t cqhdl;
24449e39c5baSBill Taylor hermon_state_t *state;
24459e39c5baSBill Taylor
24469e39c5baSBill Taylor cqhdl = (hermon_cqhdl_t)cq;
24479e39c5baSBill Taylor state = (hermon_state_t *)priv;
24489e39c5baSBill Taylor
24499e39c5baSBill Taylor mutex_init(&cqhdl->cq_lock, NULL, MUTEX_DRIVER,
24509e39c5baSBill Taylor DDI_INTR_PRI(state->hs_intrmsi_pri));
24519e39c5baSBill Taylor
24529e39c5baSBill Taylor return (DDI_SUCCESS);
24539e39c5baSBill Taylor }
24549e39c5baSBill Taylor
24559e39c5baSBill Taylor
24569e39c5baSBill Taylor /*
24579e39c5baSBill Taylor * hermon_rsrc_cqhdl_destructor()
24589e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
24599e39c5baSBill Taylor */
24609e39c5baSBill Taylor /* ARGSUSED */
24619e39c5baSBill Taylor static void
hermon_rsrc_cqhdl_destructor(void * cq,void * priv)24629e39c5baSBill Taylor hermon_rsrc_cqhdl_destructor(void *cq, void *priv)
24639e39c5baSBill Taylor {
24649e39c5baSBill Taylor hermon_cqhdl_t cqhdl;
24659e39c5baSBill Taylor
24669e39c5baSBill Taylor cqhdl = (hermon_cqhdl_t)cq;
24679e39c5baSBill Taylor
24689e39c5baSBill Taylor mutex_destroy(&cqhdl->cq_lock);
24699e39c5baSBill Taylor }
24709e39c5baSBill Taylor
24719e39c5baSBill Taylor
24729e39c5baSBill Taylor /*
24739e39c5baSBill Taylor * hermon_rsrc_qphdl_constructor()
24749e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
24759e39c5baSBill Taylor */
24769e39c5baSBill Taylor /* ARGSUSED */
24779e39c5baSBill Taylor static int
hermon_rsrc_qphdl_constructor(void * qp,void * priv,int flags)24789e39c5baSBill Taylor hermon_rsrc_qphdl_constructor(void *qp, void *priv, int flags)
24799e39c5baSBill Taylor {
24809e39c5baSBill Taylor hermon_qphdl_t qphdl;
24819e39c5baSBill Taylor hermon_state_t *state;
24829e39c5baSBill Taylor
24839e39c5baSBill Taylor qphdl = (hermon_qphdl_t)qp;
24849e39c5baSBill Taylor state = (hermon_state_t *)priv;
24859e39c5baSBill Taylor
24869e39c5baSBill Taylor mutex_init(&qphdl->qp_lock, NULL, MUTEX_DRIVER,
24879e39c5baSBill Taylor DDI_INTR_PRI(state->hs_intrmsi_pri));
24889e39c5baSBill Taylor
24899e39c5baSBill Taylor return (DDI_SUCCESS);
24909e39c5baSBill Taylor }
24919e39c5baSBill Taylor
24929e39c5baSBill Taylor
24939e39c5baSBill Taylor /*
24949e39c5baSBill Taylor * hermon_rsrc_qphdl_destructor()
24959e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
24969e39c5baSBill Taylor */
24979e39c5baSBill Taylor /* ARGSUSED */
24989e39c5baSBill Taylor static void
hermon_rsrc_qphdl_destructor(void * qp,void * priv)24999e39c5baSBill Taylor hermon_rsrc_qphdl_destructor(void *qp, void *priv)
25009e39c5baSBill Taylor {
25019e39c5baSBill Taylor hermon_qphdl_t qphdl;
25029e39c5baSBill Taylor
25039e39c5baSBill Taylor qphdl = (hermon_qphdl_t)qp;
25049e39c5baSBill Taylor
25059e39c5baSBill Taylor mutex_destroy(&qphdl->qp_lock);
25069e39c5baSBill Taylor }
25079e39c5baSBill Taylor
25089e39c5baSBill Taylor
25099e39c5baSBill Taylor /*
25109e39c5baSBill Taylor * hermon_rsrc_srqhdl_constructor()
25119e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
25129e39c5baSBill Taylor */
25139e39c5baSBill Taylor /* ARGSUSED */
25149e39c5baSBill Taylor static int
hermon_rsrc_srqhdl_constructor(void * srq,void * priv,int flags)25159e39c5baSBill Taylor hermon_rsrc_srqhdl_constructor(void *srq, void *priv, int flags)
25169e39c5baSBill Taylor {
25179e39c5baSBill Taylor hermon_srqhdl_t srqhdl;
25189e39c5baSBill Taylor hermon_state_t *state;
25199e39c5baSBill Taylor
25209e39c5baSBill Taylor srqhdl = (hermon_srqhdl_t)srq;
25219e39c5baSBill Taylor state = (hermon_state_t *)priv;
25229e39c5baSBill Taylor
25239e39c5baSBill Taylor mutex_init(&srqhdl->srq_lock, NULL, MUTEX_DRIVER,
25249e39c5baSBill Taylor DDI_INTR_PRI(state->hs_intrmsi_pri));
25259e39c5baSBill Taylor
25269e39c5baSBill Taylor return (DDI_SUCCESS);
25279e39c5baSBill Taylor }
25289e39c5baSBill Taylor
25299e39c5baSBill Taylor
25309e39c5baSBill Taylor /*
25319e39c5baSBill Taylor * hermon_rsrc_srqhdl_destructor()
25329e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
25339e39c5baSBill Taylor */
25349e39c5baSBill Taylor /* ARGSUSED */
25359e39c5baSBill Taylor static void
hermon_rsrc_srqhdl_destructor(void * srq,void * priv)25369e39c5baSBill Taylor hermon_rsrc_srqhdl_destructor(void *srq, void *priv)
25379e39c5baSBill Taylor {
25389e39c5baSBill Taylor hermon_srqhdl_t srqhdl;
25399e39c5baSBill Taylor
25409e39c5baSBill Taylor srqhdl = (hermon_srqhdl_t)srq;
25419e39c5baSBill Taylor
25429e39c5baSBill Taylor mutex_destroy(&srqhdl->srq_lock);
25439e39c5baSBill Taylor }
25449e39c5baSBill Taylor
25459e39c5baSBill Taylor
25469e39c5baSBill Taylor /*
25479e39c5baSBill Taylor * hermon_rsrc_refcnt_constructor()
25489e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
25499e39c5baSBill Taylor */
25509e39c5baSBill Taylor /* ARGSUSED */
25519e39c5baSBill Taylor static int
hermon_rsrc_refcnt_constructor(void * rc,void * priv,int flags)25529e39c5baSBill Taylor hermon_rsrc_refcnt_constructor(void *rc, void *priv, int flags)
25539e39c5baSBill Taylor {
25549e39c5baSBill Taylor hermon_sw_refcnt_t *refcnt;
25559e39c5baSBill Taylor hermon_state_t *state;
25569e39c5baSBill Taylor
25579e39c5baSBill Taylor refcnt = (hermon_sw_refcnt_t *)rc;
25589e39c5baSBill Taylor state = (hermon_state_t *)priv;
25599e39c5baSBill Taylor
25609e39c5baSBill Taylor mutex_init(&refcnt->swrc_lock, NULL, MUTEX_DRIVER,
25619e39c5baSBill Taylor DDI_INTR_PRI(state->hs_intrmsi_pri));
25629e39c5baSBill Taylor
25639e39c5baSBill Taylor return (DDI_SUCCESS);
25649e39c5baSBill Taylor }
25659e39c5baSBill Taylor
25669e39c5baSBill Taylor
25679e39c5baSBill Taylor /*
25689e39c5baSBill Taylor * hermon_rsrc_refcnt_destructor()
25699e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
25709e39c5baSBill Taylor */
25719e39c5baSBill Taylor /* ARGSUSED */
25729e39c5baSBill Taylor static void
hermon_rsrc_refcnt_destructor(void * rc,void * priv)25739e39c5baSBill Taylor hermon_rsrc_refcnt_destructor(void *rc, void *priv)
25749e39c5baSBill Taylor {
25759e39c5baSBill Taylor hermon_sw_refcnt_t *refcnt;
25769e39c5baSBill Taylor
25779e39c5baSBill Taylor refcnt = (hermon_sw_refcnt_t *)rc;
25789e39c5baSBill Taylor
25799e39c5baSBill Taylor mutex_destroy(&refcnt->swrc_lock);
25809e39c5baSBill Taylor }
25819e39c5baSBill Taylor
25829e39c5baSBill Taylor
25839e39c5baSBill Taylor /*
25849e39c5baSBill Taylor * hermon_rsrc_ahhdl_constructor()
25859e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
25869e39c5baSBill Taylor */
25879e39c5baSBill Taylor /* ARGSUSED */
25889e39c5baSBill Taylor static int
hermon_rsrc_ahhdl_constructor(void * ah,void * priv,int flags)25899e39c5baSBill Taylor hermon_rsrc_ahhdl_constructor(void *ah, void *priv, int flags)
25909e39c5baSBill Taylor {
25919e39c5baSBill Taylor hermon_ahhdl_t ahhdl;
25929e39c5baSBill Taylor hermon_state_t *state;
25939e39c5baSBill Taylor
25949e39c5baSBill Taylor ahhdl = (hermon_ahhdl_t)ah;
25959e39c5baSBill Taylor state = (hermon_state_t *)priv;
25969e39c5baSBill Taylor
25979e39c5baSBill Taylor mutex_init(&ahhdl->ah_lock, NULL, MUTEX_DRIVER,
25989e39c5baSBill Taylor DDI_INTR_PRI(state->hs_intrmsi_pri));
25999e39c5baSBill Taylor return (DDI_SUCCESS);
26009e39c5baSBill Taylor }
26019e39c5baSBill Taylor
26029e39c5baSBill Taylor
26039e39c5baSBill Taylor /*
26049e39c5baSBill Taylor * hermon_rsrc_ahhdl_destructor()
26059e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
26069e39c5baSBill Taylor */
26079e39c5baSBill Taylor /* ARGSUSED */
26089e39c5baSBill Taylor static void
hermon_rsrc_ahhdl_destructor(void * ah,void * priv)26099e39c5baSBill Taylor hermon_rsrc_ahhdl_destructor(void *ah, void *priv)
26109e39c5baSBill Taylor {
26119e39c5baSBill Taylor hermon_ahhdl_t ahhdl;
26129e39c5baSBill Taylor
26139e39c5baSBill Taylor ahhdl = (hermon_ahhdl_t)ah;
26149e39c5baSBill Taylor
26159e39c5baSBill Taylor mutex_destroy(&ahhdl->ah_lock);
26169e39c5baSBill Taylor }
26179e39c5baSBill Taylor
26189e39c5baSBill Taylor
26199e39c5baSBill Taylor /*
26209e39c5baSBill Taylor * hermon_rsrc_mrhdl_constructor()
26219e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
26229e39c5baSBill Taylor */
26239e39c5baSBill Taylor /* ARGSUSED */
26249e39c5baSBill Taylor static int
hermon_rsrc_mrhdl_constructor(void * mr,void * priv,int flags)26259e39c5baSBill Taylor hermon_rsrc_mrhdl_constructor(void *mr, void *priv, int flags)
26269e39c5baSBill Taylor {
26279e39c5baSBill Taylor hermon_mrhdl_t mrhdl;
26289e39c5baSBill Taylor hermon_state_t *state;
26299e39c5baSBill Taylor
26309e39c5baSBill Taylor mrhdl = (hermon_mrhdl_t)mr;
26319e39c5baSBill Taylor state = (hermon_state_t *)priv;
26329e39c5baSBill Taylor
26339e39c5baSBill Taylor mutex_init(&mrhdl->mr_lock, NULL, MUTEX_DRIVER,
26349e39c5baSBill Taylor DDI_INTR_PRI(state->hs_intrmsi_pri));
26359e39c5baSBill Taylor
26369e39c5baSBill Taylor return (DDI_SUCCESS);
26379e39c5baSBill Taylor }
26389e39c5baSBill Taylor
26399e39c5baSBill Taylor
26409e39c5baSBill Taylor /*
26419e39c5baSBill Taylor * hermon_rsrc_mrhdl_destructor()
26429e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
26439e39c5baSBill Taylor */
26449e39c5baSBill Taylor /* ARGSUSED */
26459e39c5baSBill Taylor static void
hermon_rsrc_mrhdl_destructor(void * mr,void * priv)26469e39c5baSBill Taylor hermon_rsrc_mrhdl_destructor(void *mr, void *priv)
26479e39c5baSBill Taylor {
26489e39c5baSBill Taylor hermon_mrhdl_t mrhdl;
26499e39c5baSBill Taylor
26509e39c5baSBill Taylor mrhdl = (hermon_mrhdl_t)mr;
26519e39c5baSBill Taylor
26529e39c5baSBill Taylor mutex_destroy(&mrhdl->mr_lock);
26539e39c5baSBill Taylor }
26549e39c5baSBill Taylor
26559e39c5baSBill Taylor
26569e39c5baSBill Taylor /*
26579e39c5baSBill Taylor * hermon_rsrc_mcg_entry_get_size()
26589e39c5baSBill Taylor */
26599e39c5baSBill Taylor static int
hermon_rsrc_mcg_entry_get_size(hermon_state_t * state,uint_t * mcg_size_shift)26609e39c5baSBill Taylor hermon_rsrc_mcg_entry_get_size(hermon_state_t *state, uint_t *mcg_size_shift)
26619e39c5baSBill Taylor {
26629e39c5baSBill Taylor uint_t num_qp_per_mcg, max_qp_per_mcg, log2;
26639e39c5baSBill Taylor
26649e39c5baSBill Taylor /*
26659e39c5baSBill Taylor * Round the configured number of QP per MCG to next larger
26669e39c5baSBill Taylor * power-of-2 size and update.
26679e39c5baSBill Taylor */
26689e39c5baSBill Taylor num_qp_per_mcg = state->hs_cfg_profile->cp_num_qp_per_mcg + 8;
26699e39c5baSBill Taylor log2 = highbit(num_qp_per_mcg);
2670*de710d24SJosef 'Jeff' Sipek if (ISP2(num_qp_per_mcg)) {
26719e39c5baSBill Taylor log2 = log2 - 1;
26729e39c5baSBill Taylor }
26739e39c5baSBill Taylor state->hs_cfg_profile->cp_num_qp_per_mcg = (1 << log2) - 8;
26749e39c5baSBill Taylor
26759e39c5baSBill Taylor /* Now make sure number of QP per MCG makes sense */
26769e39c5baSBill Taylor num_qp_per_mcg = state->hs_cfg_profile->cp_num_qp_per_mcg;
26779e39c5baSBill Taylor max_qp_per_mcg = (1 << state->hs_devlim.log_max_qp_mcg);
26789e39c5baSBill Taylor if (num_qp_per_mcg > max_qp_per_mcg) {
26799e39c5baSBill Taylor return (DDI_FAILURE);
26809e39c5baSBill Taylor }
26819e39c5baSBill Taylor
26829e39c5baSBill Taylor /* Return the (shift) size of an individual MCG HW entry */
26839e39c5baSBill Taylor *mcg_size_shift = log2 + 2;
26849e39c5baSBill Taylor
26859e39c5baSBill Taylor return (DDI_SUCCESS);
26869e39c5baSBill Taylor }
2687