19517SBill.Taylor@Sun.COM /*
29517SBill.Taylor@Sun.COM * CDDL HEADER START
39517SBill.Taylor@Sun.COM *
49517SBill.Taylor@Sun.COM * The contents of this file are subject to the terms of the
59517SBill.Taylor@Sun.COM * Common Development and Distribution License (the "License").
69517SBill.Taylor@Sun.COM * You may not use this file except in compliance with the License.
79517SBill.Taylor@Sun.COM *
89517SBill.Taylor@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99517SBill.Taylor@Sun.COM * or http://www.opensolaris.org/os/licensing.
109517SBill.Taylor@Sun.COM * See the License for the specific language governing permissions
119517SBill.Taylor@Sun.COM * and limitations under the License.
129517SBill.Taylor@Sun.COM *
139517SBill.Taylor@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
149517SBill.Taylor@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159517SBill.Taylor@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
169517SBill.Taylor@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
179517SBill.Taylor@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
189517SBill.Taylor@Sun.COM *
199517SBill.Taylor@Sun.COM * CDDL HEADER END
209517SBill.Taylor@Sun.COM */
219517SBill.Taylor@Sun.COM
229517SBill.Taylor@Sun.COM /*
23*12965SWilliam.Taylor@Oracle.COM * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
249517SBill.Taylor@Sun.COM */
259517SBill.Taylor@Sun.COM
269517SBill.Taylor@Sun.COM /*
279517SBill.Taylor@Sun.COM * hermon_rsrc.c
289517SBill.Taylor@Sun.COM * Hermon Resource Management Routines
299517SBill.Taylor@Sun.COM *
309517SBill.Taylor@Sun.COM * Implements all the routines necessary for setup, teardown, and
319517SBill.Taylor@Sun.COM * alloc/free of all Hermon resources, including those that are managed
329517SBill.Taylor@Sun.COM * by Hermon hardware or which live in Hermon's direct attached DDR memory.
339517SBill.Taylor@Sun.COM */
349517SBill.Taylor@Sun.COM
359517SBill.Taylor@Sun.COM #include <sys/types.h>
369517SBill.Taylor@Sun.COM #include <sys/conf.h>
379517SBill.Taylor@Sun.COM #include <sys/ddi.h>
389517SBill.Taylor@Sun.COM #include <sys/sunddi.h>
399517SBill.Taylor@Sun.COM #include <sys/modctl.h>
409517SBill.Taylor@Sun.COM #include <sys/vmem.h>
419517SBill.Taylor@Sun.COM #include <sys/bitmap.h>
429517SBill.Taylor@Sun.COM
439517SBill.Taylor@Sun.COM #include <sys/ib/adapters/hermon/hermon.h>
449517SBill.Taylor@Sun.COM
459517SBill.Taylor@Sun.COM int hermon_rsrc_verbose = 0;
469517SBill.Taylor@Sun.COM
479517SBill.Taylor@Sun.COM /*
489517SBill.Taylor@Sun.COM * The following routines are used for initializing and destroying
499517SBill.Taylor@Sun.COM * the resource pools used by the Hermon resource allocation routines.
509517SBill.Taylor@Sun.COM * They consist of four classes of object:
519517SBill.Taylor@Sun.COM *
529517SBill.Taylor@Sun.COM * Mailboxes: The "In" and "Out" mailbox types are used by the Hermon
539517SBill.Taylor@Sun.COM * command interface routines. Mailboxes are used to pass information
549517SBill.Taylor@Sun.COM * back and forth to the Hermon firmware. Either type of mailbox may
559517SBill.Taylor@Sun.COM * be allocated from Hermon's direct attached DDR memory or from system
569517SBill.Taylor@Sun.COM * memory (although currently all "In" mailboxes are in DDR and all "out"
579517SBill.Taylor@Sun.COM * mailboxes come from system memory.
589517SBill.Taylor@Sun.COM *
599517SBill.Taylor@Sun.COM * HW entry objects: These objects represent resources required by the Hermon
609517SBill.Taylor@Sun.COM * hardware. These objects include things like Queue Pair contexts (QPC),
619517SBill.Taylor@Sun.COM * Completion Queue contexts (CQC), Event Queue contexts (EQC), RDB (for
629517SBill.Taylor@Sun.COM * supporting RDMA Read/Atomic), Multicast Group entries (MCG), Memory
639517SBill.Taylor@Sun.COM * Protection Table entries (MPT), Memory Translation Table entries (MTT).
649517SBill.Taylor@Sun.COM *
659517SBill.Taylor@Sun.COM * What these objects all have in common is that they are each required
669517SBill.Taylor@Sun.COM * to come from ICM memory, they are always allocated from tables, and
679517SBill.Taylor@Sun.COM * they are not to be directly accessed (read or written) by driver
689517SBill.Taylor@Sun.COM * software (Mellanox FMR access to MPT is an exception).
699517SBill.Taylor@Sun.COM * The other notable exceptions are the UAR pages (UAR_PG) which are
709517SBill.Taylor@Sun.COM * allocated from the UAR address space rather than DDR, and the UD
719517SBill.Taylor@Sun.COM * address vectors (UDAV) which are similar to the common object types
729517SBill.Taylor@Sun.COM * with the major difference being that UDAVs _are_ directly read and
739517SBill.Taylor@Sun.COM * written by driver software.
749517SBill.Taylor@Sun.COM *
759517SBill.Taylor@Sun.COM * SW handle objects: These objects represent resources required by Hermon
769517SBill.Taylor@Sun.COM * driver software. They are primarily software tracking structures,
779517SBill.Taylor@Sun.COM * which are allocated from system memory (using kmem_cache). Several of
789517SBill.Taylor@Sun.COM * the objects have both a "constructor" and "destructor" method
799517SBill.Taylor@Sun.COM * associated with them (see below).
809517SBill.Taylor@Sun.COM *
819517SBill.Taylor@Sun.COM * Protection Domain (PD) handle objects: These objects are very much like
829517SBill.Taylor@Sun.COM * a SW handle object with the notable difference that all PD handle
839517SBill.Taylor@Sun.COM * objects have an actual Protection Domain number (PD) associated with
849517SBill.Taylor@Sun.COM * them (and the PD number is allocated/managed through a separate
859517SBill.Taylor@Sun.COM * vmem_arena specifically set aside for this purpose.
869517SBill.Taylor@Sun.COM */
879517SBill.Taylor@Sun.COM
889517SBill.Taylor@Sun.COM static int hermon_rsrc_mbox_init(hermon_state_t *state,
899517SBill.Taylor@Sun.COM hermon_rsrc_mbox_info_t *info);
909517SBill.Taylor@Sun.COM static void hermon_rsrc_mbox_fini(hermon_state_t *state,
919517SBill.Taylor@Sun.COM hermon_rsrc_mbox_info_t *info);
929517SBill.Taylor@Sun.COM
939517SBill.Taylor@Sun.COM static int hermon_rsrc_sw_handles_init(hermon_state_t *state,
949517SBill.Taylor@Sun.COM hermon_rsrc_sw_hdl_info_t *info);
959517SBill.Taylor@Sun.COM static void hermon_rsrc_sw_handles_fini(hermon_state_t *state,
969517SBill.Taylor@Sun.COM hermon_rsrc_sw_hdl_info_t *info);
979517SBill.Taylor@Sun.COM
989517SBill.Taylor@Sun.COM static int hermon_rsrc_pd_handles_init(hermon_state_t *state,
999517SBill.Taylor@Sun.COM hermon_rsrc_sw_hdl_info_t *info);
1009517SBill.Taylor@Sun.COM static void hermon_rsrc_pd_handles_fini(hermon_state_t *state,
1019517SBill.Taylor@Sun.COM hermon_rsrc_sw_hdl_info_t *info);
1029517SBill.Taylor@Sun.COM
1039517SBill.Taylor@Sun.COM /*
1049517SBill.Taylor@Sun.COM * The following routines are used for allocating and freeing the specific
1059517SBill.Taylor@Sun.COM * types of objects described above from their associated resource pools.
1069517SBill.Taylor@Sun.COM */
1079517SBill.Taylor@Sun.COM static int hermon_rsrc_mbox_alloc(hermon_rsrc_pool_info_t *pool_info,
1089517SBill.Taylor@Sun.COM uint_t num, hermon_rsrc_t *hdl);
109*12965SWilliam.Taylor@Oracle.COM static void hermon_rsrc_mbox_free(hermon_rsrc_t *hdl);
1109517SBill.Taylor@Sun.COM
1119517SBill.Taylor@Sun.COM static int hermon_rsrc_hw_entry_alloc(hermon_rsrc_pool_info_t *pool_info,
112*12965SWilliam.Taylor@Oracle.COM uint_t num, uint_t num_align, uint_t sleepflag, hermon_rsrc_t *hdl);
1139517SBill.Taylor@Sun.COM static void hermon_rsrc_hw_entry_free(hermon_rsrc_pool_info_t *pool_info,
1149517SBill.Taylor@Sun.COM hermon_rsrc_t *hdl);
115*12965SWilliam.Taylor@Oracle.COM static int hermon_rsrc_hw_entry_reserve(hermon_rsrc_pool_info_t *pool_info,
116*12965SWilliam.Taylor@Oracle.COM uint_t num, uint_t num_align, uint_t sleepflag, hermon_rsrc_t *hdl);
1179517SBill.Taylor@Sun.COM
1189517SBill.Taylor@Sun.COM static int hermon_rsrc_hw_entry_icm_confirm(hermon_rsrc_pool_info_t *pool_info,
119*12965SWilliam.Taylor@Oracle.COM uint_t num, hermon_rsrc_t *hdl, int num_to_hdl);
1209517SBill.Taylor@Sun.COM static int hermon_rsrc_hw_entry_icm_free(hermon_rsrc_pool_info_t *pool_info,
121*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_t *hdl, int num_to_hdl);
1229517SBill.Taylor@Sun.COM
1239517SBill.Taylor@Sun.COM static int hermon_rsrc_swhdl_alloc(hermon_rsrc_pool_info_t *pool_info,
1249517SBill.Taylor@Sun.COM uint_t sleepflag, hermon_rsrc_t *hdl);
1259517SBill.Taylor@Sun.COM static void hermon_rsrc_swhdl_free(hermon_rsrc_pool_info_t *pool_info,
1269517SBill.Taylor@Sun.COM hermon_rsrc_t *hdl);
1279517SBill.Taylor@Sun.COM
1289517SBill.Taylor@Sun.COM static int hermon_rsrc_pdhdl_alloc(hermon_rsrc_pool_info_t *pool_info,
1299517SBill.Taylor@Sun.COM uint_t sleepflag, hermon_rsrc_t *hdl);
1309517SBill.Taylor@Sun.COM static void hermon_rsrc_pdhdl_free(hermon_rsrc_pool_info_t *pool_info,
1319517SBill.Taylor@Sun.COM hermon_rsrc_t *hdl);
1329517SBill.Taylor@Sun.COM
133*12965SWilliam.Taylor@Oracle.COM static int hermon_rsrc_fexch_alloc(hermon_state_t *state,
134*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_type_t rsrc, uint_t num, uint_t sleepflag, hermon_rsrc_t *hdl);
135*12965SWilliam.Taylor@Oracle.COM static void hermon_rsrc_fexch_free(hermon_state_t *state, hermon_rsrc_t *hdl);
136*12965SWilliam.Taylor@Oracle.COM static int hermon_rsrc_rfci_alloc(hermon_state_t *state,
137*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_type_t rsrc, uint_t num, uint_t sleepflag, hermon_rsrc_t *hdl);
138*12965SWilliam.Taylor@Oracle.COM static void hermon_rsrc_rfci_free(hermon_state_t *state, hermon_rsrc_t *hdl);
139*12965SWilliam.Taylor@Oracle.COM
1409517SBill.Taylor@Sun.COM /*
1419517SBill.Taylor@Sun.COM * The following routines are the constructors and destructors for several
1429517SBill.Taylor@Sun.COM * of the SW handle type objects. For certain types of SW handles objects
1439517SBill.Taylor@Sun.COM * (all of which are implemented using kmem_cache), we need to do some
1449517SBill.Taylor@Sun.COM * special field initialization (specifically, mutex_init/destroy). These
1459517SBill.Taylor@Sun.COM * routines enable that init and teardown.
1469517SBill.Taylor@Sun.COM */
1479517SBill.Taylor@Sun.COM static int hermon_rsrc_pdhdl_constructor(void *pd, void *priv, int flags);
1489517SBill.Taylor@Sun.COM static void hermon_rsrc_pdhdl_destructor(void *pd, void *state);
1499517SBill.Taylor@Sun.COM static int hermon_rsrc_cqhdl_constructor(void *cq, void *priv, int flags);
1509517SBill.Taylor@Sun.COM static void hermon_rsrc_cqhdl_destructor(void *cq, void *state);
1519517SBill.Taylor@Sun.COM static int hermon_rsrc_qphdl_constructor(void *cq, void *priv, int flags);
1529517SBill.Taylor@Sun.COM static void hermon_rsrc_qphdl_destructor(void *cq, void *state);
1539517SBill.Taylor@Sun.COM static int hermon_rsrc_srqhdl_constructor(void *srq, void *priv, int flags);
1549517SBill.Taylor@Sun.COM static void hermon_rsrc_srqhdl_destructor(void *srq, void *state);
1559517SBill.Taylor@Sun.COM static int hermon_rsrc_refcnt_constructor(void *rc, void *priv, int flags);
1569517SBill.Taylor@Sun.COM static void hermon_rsrc_refcnt_destructor(void *rc, void *state);
1579517SBill.Taylor@Sun.COM static int hermon_rsrc_ahhdl_constructor(void *ah, void *priv, int flags);
1589517SBill.Taylor@Sun.COM static void hermon_rsrc_ahhdl_destructor(void *ah, void *state);
1599517SBill.Taylor@Sun.COM static int hermon_rsrc_mrhdl_constructor(void *mr, void *priv, int flags);
1609517SBill.Taylor@Sun.COM static void hermon_rsrc_mrhdl_destructor(void *mr, void *state);
1619517SBill.Taylor@Sun.COM
1629517SBill.Taylor@Sun.COM /*
1639517SBill.Taylor@Sun.COM * Special routine to calculate and return the size of a MCG object based
1649517SBill.Taylor@Sun.COM * on current driver configuration (specifically, the number of QP per MCG
1659517SBill.Taylor@Sun.COM * that has been configured.
1669517SBill.Taylor@Sun.COM */
1679517SBill.Taylor@Sun.COM static int hermon_rsrc_mcg_entry_get_size(hermon_state_t *state,
1689517SBill.Taylor@Sun.COM uint_t *mcg_size_shift);
1699517SBill.Taylor@Sun.COM
1709517SBill.Taylor@Sun.COM
1719517SBill.Taylor@Sun.COM /*
1729517SBill.Taylor@Sun.COM * hermon_rsrc_alloc()
1739517SBill.Taylor@Sun.COM *
1749517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
1759517SBill.Taylor@Sun.COM * The "sleepflag" parameter is used by all object allocators to
1769517SBill.Taylor@Sun.COM * determine whether to SLEEP for resources or not.
1779517SBill.Taylor@Sun.COM */
1789517SBill.Taylor@Sun.COM int
hermon_rsrc_alloc(hermon_state_t * state,hermon_rsrc_type_t rsrc,uint_t num,uint_t sleepflag,hermon_rsrc_t ** hdl)1799517SBill.Taylor@Sun.COM hermon_rsrc_alloc(hermon_state_t *state, hermon_rsrc_type_t rsrc, uint_t num,
1809517SBill.Taylor@Sun.COM uint_t sleepflag, hermon_rsrc_t **hdl)
1819517SBill.Taylor@Sun.COM {
1829517SBill.Taylor@Sun.COM hermon_rsrc_pool_info_t *rsrc_pool;
1839517SBill.Taylor@Sun.COM hermon_rsrc_t *tmp_rsrc_hdl;
1849517SBill.Taylor@Sun.COM int flag, status = DDI_FAILURE;
1859517SBill.Taylor@Sun.COM
1869517SBill.Taylor@Sun.COM ASSERT(state != NULL);
1879517SBill.Taylor@Sun.COM ASSERT(hdl != NULL);
1889517SBill.Taylor@Sun.COM
1899517SBill.Taylor@Sun.COM rsrc_pool = &state->hs_rsrc_hdl[rsrc];
1909517SBill.Taylor@Sun.COM ASSERT(rsrc_pool != NULL);
1919517SBill.Taylor@Sun.COM
1929517SBill.Taylor@Sun.COM /*
1939517SBill.Taylor@Sun.COM * Allocate space for the object used to track the resource handle
1949517SBill.Taylor@Sun.COM */
1959517SBill.Taylor@Sun.COM flag = (sleepflag == HERMON_SLEEP) ? KM_SLEEP : KM_NOSLEEP;
196*12965SWilliam.Taylor@Oracle.COM tmp_rsrc_hdl = kmem_cache_alloc(state->hs_rsrc_cache, flag);
1979517SBill.Taylor@Sun.COM if (tmp_rsrc_hdl == NULL) {
1989517SBill.Taylor@Sun.COM return (DDI_FAILURE);
1999517SBill.Taylor@Sun.COM }
2009517SBill.Taylor@Sun.COM _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*tmp_rsrc_hdl))
2019517SBill.Taylor@Sun.COM
2029517SBill.Taylor@Sun.COM /*
2039517SBill.Taylor@Sun.COM * Set rsrc_hdl type. This is later used by the hermon_rsrc_free call
2049517SBill.Taylor@Sun.COM * to know what type of resource is being freed.
2059517SBill.Taylor@Sun.COM */
2069517SBill.Taylor@Sun.COM tmp_rsrc_hdl->rsrc_type = rsrc;
2079517SBill.Taylor@Sun.COM
2089517SBill.Taylor@Sun.COM /*
2099517SBill.Taylor@Sun.COM * Depending on resource type, call the appropriate alloc routine
2109517SBill.Taylor@Sun.COM */
211*12965SWilliam.Taylor@Oracle.COM switch (rsrc) {
2129517SBill.Taylor@Sun.COM case HERMON_IN_MBOX:
2139517SBill.Taylor@Sun.COM case HERMON_OUT_MBOX:
2149517SBill.Taylor@Sun.COM case HERMON_INTR_IN_MBOX:
2159517SBill.Taylor@Sun.COM case HERMON_INTR_OUT_MBOX:
2169517SBill.Taylor@Sun.COM status = hermon_rsrc_mbox_alloc(rsrc_pool, num, tmp_rsrc_hdl);
2179517SBill.Taylor@Sun.COM break;
2189517SBill.Taylor@Sun.COM
219*12965SWilliam.Taylor@Oracle.COM case HERMON_DMPT:
220*12965SWilliam.Taylor@Oracle.COM /* Allocate "num" (contiguous/aligned for FEXCH) DMPTs */
2219517SBill.Taylor@Sun.COM case HERMON_QPC:
222*12965SWilliam.Taylor@Oracle.COM /* Allocate "num" (contiguous/aligned for RSS) QPCs */
22311972SBill.Taylor@Sun.COM status = hermon_rsrc_hw_entry_alloc(rsrc_pool, num, num,
2249517SBill.Taylor@Sun.COM sleepflag, tmp_rsrc_hdl);
2259517SBill.Taylor@Sun.COM break;
2269517SBill.Taylor@Sun.COM
227*12965SWilliam.Taylor@Oracle.COM case HERMON_QPC_FEXCH_PORT1:
228*12965SWilliam.Taylor@Oracle.COM case HERMON_QPC_FEXCH_PORT2:
229*12965SWilliam.Taylor@Oracle.COM /* Allocate "num" contiguous/aligned QPCs for FEXCH */
230*12965SWilliam.Taylor@Oracle.COM status = hermon_rsrc_fexch_alloc(state, rsrc, num,
231*12965SWilliam.Taylor@Oracle.COM sleepflag, tmp_rsrc_hdl);
2329517SBill.Taylor@Sun.COM break;
2339517SBill.Taylor@Sun.COM
234*12965SWilliam.Taylor@Oracle.COM case HERMON_QPC_RFCI_PORT1:
235*12965SWilliam.Taylor@Oracle.COM case HERMON_QPC_RFCI_PORT2:
236*12965SWilliam.Taylor@Oracle.COM /* Allocate "num" contiguous/aligned QPCs for RFCI */
237*12965SWilliam.Taylor@Oracle.COM status = hermon_rsrc_rfci_alloc(state, rsrc, num,
2389517SBill.Taylor@Sun.COM sleepflag, tmp_rsrc_hdl);
2399517SBill.Taylor@Sun.COM break;
2409517SBill.Taylor@Sun.COM
2419517SBill.Taylor@Sun.COM case HERMON_MTT:
242*12965SWilliam.Taylor@Oracle.COM case HERMON_CQC:
243*12965SWilliam.Taylor@Oracle.COM case HERMON_SRQC:
244*12965SWilliam.Taylor@Oracle.COM case HERMON_EQC:
245*12965SWilliam.Taylor@Oracle.COM case HERMON_MCG:
246*12965SWilliam.Taylor@Oracle.COM case HERMON_UARPG:
247*12965SWilliam.Taylor@Oracle.COM /* Allocate "num" unaligned resources */
2489517SBill.Taylor@Sun.COM status = hermon_rsrc_hw_entry_alloc(rsrc_pool, num, 1,
249*12965SWilliam.Taylor@Oracle.COM sleepflag, tmp_rsrc_hdl);
2509517SBill.Taylor@Sun.COM break;
2519517SBill.Taylor@Sun.COM
2529517SBill.Taylor@Sun.COM case HERMON_MRHDL:
2539517SBill.Taylor@Sun.COM case HERMON_EQHDL:
2549517SBill.Taylor@Sun.COM case HERMON_CQHDL:
2559517SBill.Taylor@Sun.COM case HERMON_SRQHDL:
2569517SBill.Taylor@Sun.COM case HERMON_AHHDL:
2579517SBill.Taylor@Sun.COM case HERMON_QPHDL:
2589517SBill.Taylor@Sun.COM case HERMON_REFCNT:
2599517SBill.Taylor@Sun.COM status = hermon_rsrc_swhdl_alloc(rsrc_pool, sleepflag,
2609517SBill.Taylor@Sun.COM tmp_rsrc_hdl);
2619517SBill.Taylor@Sun.COM break;
2629517SBill.Taylor@Sun.COM
2639517SBill.Taylor@Sun.COM case HERMON_PDHDL:
2649517SBill.Taylor@Sun.COM status = hermon_rsrc_pdhdl_alloc(rsrc_pool, sleepflag,
2659517SBill.Taylor@Sun.COM tmp_rsrc_hdl);
2669517SBill.Taylor@Sun.COM break;
2679517SBill.Taylor@Sun.COM
2689517SBill.Taylor@Sun.COM case HERMON_RDB: /* handled during HERMON_QPC */
2699517SBill.Taylor@Sun.COM case HERMON_ALTC: /* handled during HERMON_QPC */
2709517SBill.Taylor@Sun.COM case HERMON_AUXC: /* handled during HERMON_QPC */
2719517SBill.Taylor@Sun.COM case HERMON_CMPT_QPC: /* handled during HERMON_QPC */
2729517SBill.Taylor@Sun.COM case HERMON_CMPT_SRQC: /* handled during HERMON_SRQC */
2739517SBill.Taylor@Sun.COM case HERMON_CMPT_CQC: /* handled during HERMON_CPC */
2749517SBill.Taylor@Sun.COM case HERMON_CMPT_EQC: /* handled during HERMON_EPC */
2759517SBill.Taylor@Sun.COM default:
2769517SBill.Taylor@Sun.COM HERMON_WARNING(state, "unexpected resource type in alloc ");
2779517SBill.Taylor@Sun.COM cmn_err(CE_WARN, "Resource type %x \n", rsrc_pool->rsrc_type);
2789517SBill.Taylor@Sun.COM break;
2799517SBill.Taylor@Sun.COM }
2809517SBill.Taylor@Sun.COM
2819517SBill.Taylor@Sun.COM /*
2829517SBill.Taylor@Sun.COM * If the resource allocation failed, then free the special resource
2839517SBill.Taylor@Sun.COM * tracking structure and return failure. Otherwise return the
2849517SBill.Taylor@Sun.COM * handle for the resource tracking structure.
2859517SBill.Taylor@Sun.COM */
2869517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
2879517SBill.Taylor@Sun.COM kmem_cache_free(state->hs_rsrc_cache, tmp_rsrc_hdl);
288*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
289*12965SWilliam.Taylor@Oracle.COM } else {
290*12965SWilliam.Taylor@Oracle.COM *hdl = tmp_rsrc_hdl;
291*12965SWilliam.Taylor@Oracle.COM return (DDI_SUCCESS);
292*12965SWilliam.Taylor@Oracle.COM }
293*12965SWilliam.Taylor@Oracle.COM }
294*12965SWilliam.Taylor@Oracle.COM
295*12965SWilliam.Taylor@Oracle.COM
296*12965SWilliam.Taylor@Oracle.COM /*
297*12965SWilliam.Taylor@Oracle.COM * hermon_rsrc_reserve()
298*12965SWilliam.Taylor@Oracle.COM *
299*12965SWilliam.Taylor@Oracle.COM * Context: Can only be called from attach.
300*12965SWilliam.Taylor@Oracle.COM * The "sleepflag" parameter is used by all object allocators to
301*12965SWilliam.Taylor@Oracle.COM * determine whether to SLEEP for resources or not.
302*12965SWilliam.Taylor@Oracle.COM */
303*12965SWilliam.Taylor@Oracle.COM int
hermon_rsrc_reserve(hermon_state_t * state,hermon_rsrc_type_t rsrc,uint_t num,uint_t sleepflag,hermon_rsrc_t ** hdl)304*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_reserve(hermon_state_t *state, hermon_rsrc_type_t rsrc, uint_t num,
305*12965SWilliam.Taylor@Oracle.COM uint_t sleepflag, hermon_rsrc_t **hdl)
306*12965SWilliam.Taylor@Oracle.COM {
307*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_pool_info_t *rsrc_pool;
308*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_t *tmp_rsrc_hdl;
309*12965SWilliam.Taylor@Oracle.COM int flag, status = DDI_FAILURE;
310*12965SWilliam.Taylor@Oracle.COM
311*12965SWilliam.Taylor@Oracle.COM ASSERT(state != NULL);
312*12965SWilliam.Taylor@Oracle.COM ASSERT(hdl != NULL);
313*12965SWilliam.Taylor@Oracle.COM
314*12965SWilliam.Taylor@Oracle.COM rsrc_pool = &state->hs_rsrc_hdl[rsrc];
315*12965SWilliam.Taylor@Oracle.COM ASSERT(rsrc_pool != NULL);
316*12965SWilliam.Taylor@Oracle.COM
317*12965SWilliam.Taylor@Oracle.COM /*
318*12965SWilliam.Taylor@Oracle.COM * Allocate space for the object used to track the resource handle
319*12965SWilliam.Taylor@Oracle.COM */
320*12965SWilliam.Taylor@Oracle.COM flag = (sleepflag == HERMON_SLEEP) ? KM_SLEEP : KM_NOSLEEP;
321*12965SWilliam.Taylor@Oracle.COM tmp_rsrc_hdl = kmem_cache_alloc(state->hs_rsrc_cache, flag);
322*12965SWilliam.Taylor@Oracle.COM if (tmp_rsrc_hdl == NULL) {
323*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
324*12965SWilliam.Taylor@Oracle.COM }
325*12965SWilliam.Taylor@Oracle.COM _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*tmp_rsrc_hdl))
326*12965SWilliam.Taylor@Oracle.COM
327*12965SWilliam.Taylor@Oracle.COM /*
328*12965SWilliam.Taylor@Oracle.COM * Set rsrc_hdl type. This is later used by the hermon_rsrc_free call
329*12965SWilliam.Taylor@Oracle.COM * to know what type of resource is being freed.
330*12965SWilliam.Taylor@Oracle.COM */
331*12965SWilliam.Taylor@Oracle.COM tmp_rsrc_hdl->rsrc_type = rsrc;
332*12965SWilliam.Taylor@Oracle.COM
333*12965SWilliam.Taylor@Oracle.COM switch (rsrc) {
334*12965SWilliam.Taylor@Oracle.COM case HERMON_QPC:
335*12965SWilliam.Taylor@Oracle.COM case HERMON_DMPT:
336*12965SWilliam.Taylor@Oracle.COM case HERMON_MTT:
337*12965SWilliam.Taylor@Oracle.COM /*
338*12965SWilliam.Taylor@Oracle.COM * Reserve num resources, naturally aligned (N * num).
339*12965SWilliam.Taylor@Oracle.COM */
340*12965SWilliam.Taylor@Oracle.COM status = hermon_rsrc_hw_entry_reserve(rsrc_pool, num, num,
341*12965SWilliam.Taylor@Oracle.COM sleepflag, tmp_rsrc_hdl);
342*12965SWilliam.Taylor@Oracle.COM break;
343*12965SWilliam.Taylor@Oracle.COM
344*12965SWilliam.Taylor@Oracle.COM default:
345*12965SWilliam.Taylor@Oracle.COM HERMON_WARNING(state, "unexpected resource type in reserve ");
346*12965SWilliam.Taylor@Oracle.COM cmn_err(CE_WARN, "Resource type %x \n", rsrc);
347*12965SWilliam.Taylor@Oracle.COM break;
348*12965SWilliam.Taylor@Oracle.COM }
349*12965SWilliam.Taylor@Oracle.COM
350*12965SWilliam.Taylor@Oracle.COM /*
351*12965SWilliam.Taylor@Oracle.COM * If the resource allocation failed, then free the special resource
352*12965SWilliam.Taylor@Oracle.COM * tracking structure and return failure. Otherwise return the
353*12965SWilliam.Taylor@Oracle.COM * handle for the resource tracking structure.
354*12965SWilliam.Taylor@Oracle.COM */
355*12965SWilliam.Taylor@Oracle.COM if (status != DDI_SUCCESS) {
356*12965SWilliam.Taylor@Oracle.COM kmem_cache_free(state->hs_rsrc_cache, tmp_rsrc_hdl);
3579517SBill.Taylor@Sun.COM return (DDI_FAILURE);
3589517SBill.Taylor@Sun.COM } else {
3599517SBill.Taylor@Sun.COM *hdl = tmp_rsrc_hdl;
3609517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
3619517SBill.Taylor@Sun.COM }
3629517SBill.Taylor@Sun.COM }
3639517SBill.Taylor@Sun.COM
3649517SBill.Taylor@Sun.COM
3659517SBill.Taylor@Sun.COM /*
366*12965SWilliam.Taylor@Oracle.COM * hermon_rsrc_fexch_alloc()
367*12965SWilliam.Taylor@Oracle.COM *
368*12965SWilliam.Taylor@Oracle.COM * Context: Can only be called from base context.
369*12965SWilliam.Taylor@Oracle.COM * The "sleepflag" parameter is used by all object allocators to
370*12965SWilliam.Taylor@Oracle.COM * determine whether to SLEEP for resources or not.
371*12965SWilliam.Taylor@Oracle.COM */
372*12965SWilliam.Taylor@Oracle.COM 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)373*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_fexch_alloc(hermon_state_t *state, hermon_rsrc_type_t rsrc,
374*12965SWilliam.Taylor@Oracle.COM uint_t num, uint_t sleepflag, hermon_rsrc_t *hdl)
375*12965SWilliam.Taylor@Oracle.COM {
376*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_t *fcoib;
377*12965SWilliam.Taylor@Oracle.COM void *addr;
378*12965SWilliam.Taylor@Oracle.COM uint32_t fexch_qpn_base;
379*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_pool_info_t *qpc_pool, *mpt_pool, *mtt_pool;
380*12965SWilliam.Taylor@Oracle.COM int flag, status;
381*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_t mpt_hdl; /* temporary, just for icm_confirm */
382*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_t mtt_hdl; /* temporary, just for icm_confirm */
383*12965SWilliam.Taylor@Oracle.COM uint_t portm1; /* hca_port_number - 1 */
384*12965SWilliam.Taylor@Oracle.COM uint_t nummtt;
385*12965SWilliam.Taylor@Oracle.COM vmem_t *vmp;
386*12965SWilliam.Taylor@Oracle.COM
387*12965SWilliam.Taylor@Oracle.COM ASSERT(state != NULL);
388*12965SWilliam.Taylor@Oracle.COM ASSERT(hdl != NULL);
389*12965SWilliam.Taylor@Oracle.COM
390*12965SWilliam.Taylor@Oracle.COM if ((state->hs_ibtfinfo.hca_attr->hca_flags2 & IBT_HCA2_FC) == 0)
391*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
392*12965SWilliam.Taylor@Oracle.COM
393*12965SWilliam.Taylor@Oracle.COM portm1 = rsrc - HERMON_QPC_FEXCH_PORT1;
394*12965SWilliam.Taylor@Oracle.COM fcoib = &state->hs_fcoib;
395*12965SWilliam.Taylor@Oracle.COM flag = (sleepflag == HERMON_SLEEP) ? VM_SLEEP : VM_NOSLEEP;
396*12965SWilliam.Taylor@Oracle.COM
397*12965SWilliam.Taylor@Oracle.COM /* Allocate from the FEXCH QP range */
398*12965SWilliam.Taylor@Oracle.COM vmp = fcoib->hfc_fexch_vmemp[portm1];
399*12965SWilliam.Taylor@Oracle.COM addr = vmem_xalloc(vmp, num, num, 0, 0, NULL, NULL, flag | VM_FIRSTFIT);
400*12965SWilliam.Taylor@Oracle.COM if (addr == NULL) {
401*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
402*12965SWilliam.Taylor@Oracle.COM }
403*12965SWilliam.Taylor@Oracle.COM fexch_qpn_base = (uint32_t)((uintptr_t)addr -
404*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_vmemstart + fcoib->hfc_fexch_base[portm1]);
405*12965SWilliam.Taylor@Oracle.COM
406*12965SWilliam.Taylor@Oracle.COM /* ICM confirm for the FEXCH QP range */
407*12965SWilliam.Taylor@Oracle.COM qpc_pool = &state->hs_rsrc_hdl[HERMON_QPC];
408*12965SWilliam.Taylor@Oracle.COM hdl->hr_len = num << qpc_pool->rsrc_shift;
409*12965SWilliam.Taylor@Oracle.COM hdl->hr_addr = addr; /* used only for vmem_xfree */
410*12965SWilliam.Taylor@Oracle.COM hdl->hr_indx = fexch_qpn_base;
411*12965SWilliam.Taylor@Oracle.COM
412*12965SWilliam.Taylor@Oracle.COM status = hermon_rsrc_hw_entry_icm_confirm(qpc_pool, num, hdl, 1);
413*12965SWilliam.Taylor@Oracle.COM if (status != DDI_SUCCESS) {
414*12965SWilliam.Taylor@Oracle.COM vmem_xfree(vmp, addr, num);
415*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
416*12965SWilliam.Taylor@Oracle.COM }
417*12965SWilliam.Taylor@Oracle.COM
418*12965SWilliam.Taylor@Oracle.COM /* ICM confirm for the Primary MKEYs (client side only) */
419*12965SWilliam.Taylor@Oracle.COM mpt_pool = &state->hs_rsrc_hdl[HERMON_DMPT];
420*12965SWilliam.Taylor@Oracle.COM mpt_hdl.hr_len = num << mpt_pool->rsrc_shift;
421*12965SWilliam.Taylor@Oracle.COM mpt_hdl.hr_addr = NULL;
422*12965SWilliam.Taylor@Oracle.COM mpt_hdl.hr_indx = fcoib->hfc_mpt_base[portm1] +
423*12965SWilliam.Taylor@Oracle.COM (fexch_qpn_base - fcoib->hfc_fexch_base[portm1]);
424*12965SWilliam.Taylor@Oracle.COM
425*12965SWilliam.Taylor@Oracle.COM status = hermon_rsrc_hw_entry_icm_confirm(mpt_pool, num, &mpt_hdl, 0);
426*12965SWilliam.Taylor@Oracle.COM if (status != DDI_SUCCESS) {
427*12965SWilliam.Taylor@Oracle.COM status = hermon_rsrc_hw_entry_icm_free(qpc_pool, hdl, 1);
428*12965SWilliam.Taylor@Oracle.COM vmem_xfree(vmp, addr, num);
429*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
430*12965SWilliam.Taylor@Oracle.COM }
431*12965SWilliam.Taylor@Oracle.COM
432*12965SWilliam.Taylor@Oracle.COM /* ICM confirm for the MTTs of the Primary MKEYs (client side only) */
433*12965SWilliam.Taylor@Oracle.COM nummtt = fcoib->hfc_mtts_per_mpt;
434*12965SWilliam.Taylor@Oracle.COM num *= nummtt;
435*12965SWilliam.Taylor@Oracle.COM mtt_pool = &state->hs_rsrc_hdl[HERMON_MTT];
436*12965SWilliam.Taylor@Oracle.COM mtt_hdl.hr_len = num << mtt_pool->rsrc_shift;
437*12965SWilliam.Taylor@Oracle.COM mtt_hdl.hr_addr = NULL;
438*12965SWilliam.Taylor@Oracle.COM mtt_hdl.hr_indx = fcoib->hfc_mtt_base[portm1] +
439*12965SWilliam.Taylor@Oracle.COM (fexch_qpn_base - fcoib->hfc_fexch_base[portm1]) *
440*12965SWilliam.Taylor@Oracle.COM nummtt;
441*12965SWilliam.Taylor@Oracle.COM
442*12965SWilliam.Taylor@Oracle.COM status = hermon_rsrc_hw_entry_icm_confirm(mtt_pool, num, &mtt_hdl, 0);
443*12965SWilliam.Taylor@Oracle.COM if (status != DDI_SUCCESS) {
444*12965SWilliam.Taylor@Oracle.COM vmem_xfree(vmp, addr, num);
445*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
446*12965SWilliam.Taylor@Oracle.COM }
447*12965SWilliam.Taylor@Oracle.COM return (DDI_SUCCESS);
448*12965SWilliam.Taylor@Oracle.COM }
449*12965SWilliam.Taylor@Oracle.COM
450*12965SWilliam.Taylor@Oracle.COM static void
hermon_rsrc_fexch_free(hermon_state_t * state,hermon_rsrc_t * hdl)451*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_fexch_free(hermon_state_t *state, hermon_rsrc_t *hdl)
452*12965SWilliam.Taylor@Oracle.COM {
453*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_t *fcoib;
454*12965SWilliam.Taylor@Oracle.COM uint_t portm1; /* hca_port_number - 1 */
455*12965SWilliam.Taylor@Oracle.COM
456*12965SWilliam.Taylor@Oracle.COM ASSERT(state != NULL);
457*12965SWilliam.Taylor@Oracle.COM ASSERT(hdl != NULL);
458*12965SWilliam.Taylor@Oracle.COM
459*12965SWilliam.Taylor@Oracle.COM portm1 = hdl->rsrc_type - HERMON_QPC_FEXCH_PORT1;
460*12965SWilliam.Taylor@Oracle.COM fcoib = &state->hs_fcoib;
461*12965SWilliam.Taylor@Oracle.COM vmem_xfree(fcoib->hfc_fexch_vmemp[portm1], hdl->hr_addr,
462*12965SWilliam.Taylor@Oracle.COM hdl->hr_len >> state->hs_rsrc_hdl[HERMON_QPC].rsrc_shift);
463*12965SWilliam.Taylor@Oracle.COM }
464*12965SWilliam.Taylor@Oracle.COM
465*12965SWilliam.Taylor@Oracle.COM /*
466*12965SWilliam.Taylor@Oracle.COM * hermon_rsrc_rfci_alloc()
467*12965SWilliam.Taylor@Oracle.COM *
468*12965SWilliam.Taylor@Oracle.COM * Context: Can only be called from base context.
469*12965SWilliam.Taylor@Oracle.COM * The "sleepflag" parameter is used by all object allocators to
470*12965SWilliam.Taylor@Oracle.COM * determine whether to SLEEP for resources or not.
471*12965SWilliam.Taylor@Oracle.COM */
472*12965SWilliam.Taylor@Oracle.COM 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)473*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_rfci_alloc(hermon_state_t *state, hermon_rsrc_type_t rsrc,
474*12965SWilliam.Taylor@Oracle.COM uint_t num, uint_t sleepflag, hermon_rsrc_t *hdl)
475*12965SWilliam.Taylor@Oracle.COM {
476*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_t *fcoib;
477*12965SWilliam.Taylor@Oracle.COM void *addr;
478*12965SWilliam.Taylor@Oracle.COM uint32_t rfci_qpn_base;
479*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_pool_info_t *qpc_pool;
480*12965SWilliam.Taylor@Oracle.COM int flag, status;
481*12965SWilliam.Taylor@Oracle.COM uint_t portm1; /* hca_port_number - 1 */
482*12965SWilliam.Taylor@Oracle.COM vmem_t *vmp;
483*12965SWilliam.Taylor@Oracle.COM
484*12965SWilliam.Taylor@Oracle.COM ASSERT(state != NULL);
485*12965SWilliam.Taylor@Oracle.COM ASSERT(hdl != NULL);
486*12965SWilliam.Taylor@Oracle.COM
487*12965SWilliam.Taylor@Oracle.COM if ((state->hs_ibtfinfo.hca_attr->hca_flags2 & IBT_HCA2_FC) == 0)
488*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
489*12965SWilliam.Taylor@Oracle.COM
490*12965SWilliam.Taylor@Oracle.COM portm1 = rsrc - HERMON_QPC_RFCI_PORT1;
491*12965SWilliam.Taylor@Oracle.COM fcoib = &state->hs_fcoib;
492*12965SWilliam.Taylor@Oracle.COM flag = (sleepflag == HERMON_SLEEP) ? VM_SLEEP : VM_NOSLEEP;
493*12965SWilliam.Taylor@Oracle.COM
494*12965SWilliam.Taylor@Oracle.COM /* Allocate from the RFCI QP range */
495*12965SWilliam.Taylor@Oracle.COM vmp = fcoib->hfc_rfci_vmemp[portm1];
496*12965SWilliam.Taylor@Oracle.COM addr = vmem_xalloc(vmp, num, num, 0, 0, NULL, NULL, flag | VM_FIRSTFIT);
497*12965SWilliam.Taylor@Oracle.COM if (addr == NULL) {
498*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
499*12965SWilliam.Taylor@Oracle.COM }
500*12965SWilliam.Taylor@Oracle.COM rfci_qpn_base = (uint32_t)((uintptr_t)addr -
501*12965SWilliam.Taylor@Oracle.COM fcoib->hfc_vmemstart + fcoib->hfc_rfci_base[portm1]);
502*12965SWilliam.Taylor@Oracle.COM
503*12965SWilliam.Taylor@Oracle.COM /* ICM confirm for the RFCI QP */
504*12965SWilliam.Taylor@Oracle.COM qpc_pool = &state->hs_rsrc_hdl[HERMON_QPC];
505*12965SWilliam.Taylor@Oracle.COM hdl->hr_len = num << qpc_pool->rsrc_shift;
506*12965SWilliam.Taylor@Oracle.COM hdl->hr_addr = addr; /* used only for vmem_xfree */
507*12965SWilliam.Taylor@Oracle.COM hdl->hr_indx = rfci_qpn_base;
508*12965SWilliam.Taylor@Oracle.COM
509*12965SWilliam.Taylor@Oracle.COM status = hermon_rsrc_hw_entry_icm_confirm(qpc_pool, num, hdl, 1);
510*12965SWilliam.Taylor@Oracle.COM if (status != DDI_SUCCESS) {
511*12965SWilliam.Taylor@Oracle.COM vmem_xfree(vmp, addr, num);
512*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
513*12965SWilliam.Taylor@Oracle.COM }
514*12965SWilliam.Taylor@Oracle.COM return (DDI_SUCCESS);
515*12965SWilliam.Taylor@Oracle.COM }
516*12965SWilliam.Taylor@Oracle.COM
517*12965SWilliam.Taylor@Oracle.COM static void
hermon_rsrc_rfci_free(hermon_state_t * state,hermon_rsrc_t * hdl)518*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_rfci_free(hermon_state_t *state, hermon_rsrc_t *hdl)
519*12965SWilliam.Taylor@Oracle.COM {
520*12965SWilliam.Taylor@Oracle.COM hermon_fcoib_t *fcoib;
521*12965SWilliam.Taylor@Oracle.COM uint_t portm1; /* hca_port_number - 1 */
522*12965SWilliam.Taylor@Oracle.COM
523*12965SWilliam.Taylor@Oracle.COM ASSERT(state != NULL);
524*12965SWilliam.Taylor@Oracle.COM ASSERT(hdl != NULL);
525*12965SWilliam.Taylor@Oracle.COM
526*12965SWilliam.Taylor@Oracle.COM portm1 = hdl->rsrc_type - HERMON_QPC_RFCI_PORT1;
527*12965SWilliam.Taylor@Oracle.COM fcoib = &state->hs_fcoib;
528*12965SWilliam.Taylor@Oracle.COM vmem_xfree(fcoib->hfc_rfci_vmemp[portm1], hdl->hr_addr,
529*12965SWilliam.Taylor@Oracle.COM hdl->hr_len >> state->hs_rsrc_hdl[HERMON_QPC].rsrc_shift);
530*12965SWilliam.Taylor@Oracle.COM }
531*12965SWilliam.Taylor@Oracle.COM
532*12965SWilliam.Taylor@Oracle.COM
533*12965SWilliam.Taylor@Oracle.COM /*
5349517SBill.Taylor@Sun.COM * hermon_rsrc_free()
5359517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
5369517SBill.Taylor@Sun.COM */
5379517SBill.Taylor@Sun.COM void
hermon_rsrc_free(hermon_state_t * state,hermon_rsrc_t ** hdl)5389517SBill.Taylor@Sun.COM hermon_rsrc_free(hermon_state_t *state, hermon_rsrc_t **hdl)
5399517SBill.Taylor@Sun.COM {
5409517SBill.Taylor@Sun.COM hermon_rsrc_pool_info_t *rsrc_pool;
5419517SBill.Taylor@Sun.COM
5429517SBill.Taylor@Sun.COM ASSERT(state != NULL);
5439517SBill.Taylor@Sun.COM ASSERT(hdl != NULL);
5449517SBill.Taylor@Sun.COM
5459517SBill.Taylor@Sun.COM rsrc_pool = &state->hs_rsrc_hdl[(*hdl)->rsrc_type];
5469517SBill.Taylor@Sun.COM ASSERT(rsrc_pool != NULL);
5479517SBill.Taylor@Sun.COM
5489517SBill.Taylor@Sun.COM /*
5499517SBill.Taylor@Sun.COM * Depending on resource type, call the appropriate free routine
5509517SBill.Taylor@Sun.COM */
5519517SBill.Taylor@Sun.COM switch (rsrc_pool->rsrc_type) {
5529517SBill.Taylor@Sun.COM case HERMON_IN_MBOX:
5539517SBill.Taylor@Sun.COM case HERMON_OUT_MBOX:
5549517SBill.Taylor@Sun.COM case HERMON_INTR_IN_MBOX:
5559517SBill.Taylor@Sun.COM case HERMON_INTR_OUT_MBOX:
556*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_mbox_free(*hdl);
557*12965SWilliam.Taylor@Oracle.COM break;
558*12965SWilliam.Taylor@Oracle.COM
559*12965SWilliam.Taylor@Oracle.COM case HERMON_QPC_FEXCH_PORT1:
560*12965SWilliam.Taylor@Oracle.COM case HERMON_QPC_FEXCH_PORT2:
561*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_fexch_free(state, *hdl);
562*12965SWilliam.Taylor@Oracle.COM break;
563*12965SWilliam.Taylor@Oracle.COM
564*12965SWilliam.Taylor@Oracle.COM case HERMON_QPC_RFCI_PORT1:
565*12965SWilliam.Taylor@Oracle.COM case HERMON_QPC_RFCI_PORT2:
566*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_rfci_free(state, *hdl);
5679517SBill.Taylor@Sun.COM break;
5689517SBill.Taylor@Sun.COM
5699517SBill.Taylor@Sun.COM case HERMON_QPC:
5709517SBill.Taylor@Sun.COM case HERMON_CQC:
5719517SBill.Taylor@Sun.COM case HERMON_SRQC:
5729517SBill.Taylor@Sun.COM case HERMON_EQC:
5739517SBill.Taylor@Sun.COM case HERMON_DMPT:
5749517SBill.Taylor@Sun.COM case HERMON_MCG:
5759517SBill.Taylor@Sun.COM case HERMON_MTT:
5769517SBill.Taylor@Sun.COM case HERMON_UARPG:
5779517SBill.Taylor@Sun.COM hermon_rsrc_hw_entry_free(rsrc_pool, *hdl);
5789517SBill.Taylor@Sun.COM break;
5799517SBill.Taylor@Sun.COM
5809517SBill.Taylor@Sun.COM case HERMON_MRHDL:
5819517SBill.Taylor@Sun.COM case HERMON_EQHDL:
5829517SBill.Taylor@Sun.COM case HERMON_CQHDL:
5839517SBill.Taylor@Sun.COM case HERMON_SRQHDL:
5849517SBill.Taylor@Sun.COM case HERMON_AHHDL:
5859517SBill.Taylor@Sun.COM case HERMON_QPHDL:
5869517SBill.Taylor@Sun.COM case HERMON_REFCNT:
5879517SBill.Taylor@Sun.COM hermon_rsrc_swhdl_free(rsrc_pool, *hdl);
5889517SBill.Taylor@Sun.COM break;
5899517SBill.Taylor@Sun.COM
5909517SBill.Taylor@Sun.COM case HERMON_PDHDL:
5919517SBill.Taylor@Sun.COM hermon_rsrc_pdhdl_free(rsrc_pool, *hdl);
5929517SBill.Taylor@Sun.COM break;
5939517SBill.Taylor@Sun.COM
5949517SBill.Taylor@Sun.COM case HERMON_RDB:
5959517SBill.Taylor@Sun.COM case HERMON_ALTC:
5969517SBill.Taylor@Sun.COM case HERMON_AUXC:
5979517SBill.Taylor@Sun.COM case HERMON_CMPT_QPC:
5989517SBill.Taylor@Sun.COM case HERMON_CMPT_SRQC:
5999517SBill.Taylor@Sun.COM case HERMON_CMPT_CQC:
6009517SBill.Taylor@Sun.COM case HERMON_CMPT_EQC:
6019517SBill.Taylor@Sun.COM default:
602*12965SWilliam.Taylor@Oracle.COM cmn_err(CE_CONT, "!rsrc_type = 0x%x\n", rsrc_pool->rsrc_type);
6039517SBill.Taylor@Sun.COM break;
6049517SBill.Taylor@Sun.COM }
6059517SBill.Taylor@Sun.COM
6069517SBill.Taylor@Sun.COM /*
6079517SBill.Taylor@Sun.COM * Free the special resource tracking structure, set the handle to
6089517SBill.Taylor@Sun.COM * NULL, and return.
6099517SBill.Taylor@Sun.COM */
6109517SBill.Taylor@Sun.COM kmem_cache_free(state->hs_rsrc_cache, *hdl);
6119517SBill.Taylor@Sun.COM *hdl = NULL;
6129517SBill.Taylor@Sun.COM }
6139517SBill.Taylor@Sun.COM
6149517SBill.Taylor@Sun.COM
6159517SBill.Taylor@Sun.COM /*
6169517SBill.Taylor@Sun.COM * hermon_rsrc_init_phase1()
6179517SBill.Taylor@Sun.COM *
6189517SBill.Taylor@Sun.COM * Completes the first phase of Hermon resource/configuration init.
6199517SBill.Taylor@Sun.COM * This involves creating the kmem_cache for the "hermon_rsrc_t"
6209517SBill.Taylor@Sun.COM * structs, allocating the space for the resource pool handles,
6219517SBill.Taylor@Sun.COM * and setting up the "Out" mailboxes.
6229517SBill.Taylor@Sun.COM *
6239517SBill.Taylor@Sun.COM * When this function completes, the Hermon driver is ready to
6249517SBill.Taylor@Sun.COM * post the following commands which return information only in the
6259517SBill.Taylor@Sun.COM * "Out" mailbox: QUERY_DDR, QUERY_FW, QUERY_DEV_LIM, and QUERY_ADAPTER
6269517SBill.Taylor@Sun.COM * If any of these commands are to be posted at this time, they must be
6279517SBill.Taylor@Sun.COM * done so only when "spinning" (as the outstanding command list and
6289517SBill.Taylor@Sun.COM * EQ setup code has not yet run)
6299517SBill.Taylor@Sun.COM *
6309517SBill.Taylor@Sun.COM * Context: Only called from attach() path context
6319517SBill.Taylor@Sun.COM */
6329517SBill.Taylor@Sun.COM int
hermon_rsrc_init_phase1(hermon_state_t * state)6339517SBill.Taylor@Sun.COM hermon_rsrc_init_phase1(hermon_state_t *state)
6349517SBill.Taylor@Sun.COM {
6359517SBill.Taylor@Sun.COM hermon_rsrc_pool_info_t *rsrc_pool;
6369517SBill.Taylor@Sun.COM hermon_rsrc_mbox_info_t mbox_info;
6379517SBill.Taylor@Sun.COM hermon_rsrc_cleanup_level_t cleanup;
6389517SBill.Taylor@Sun.COM hermon_cfg_profile_t *cfgprof;
6399517SBill.Taylor@Sun.COM uint64_t num, size;
6409517SBill.Taylor@Sun.COM int status;
6419517SBill.Taylor@Sun.COM char *rsrc_name;
6429517SBill.Taylor@Sun.COM
6439517SBill.Taylor@Sun.COM ASSERT(state != NULL);
6449517SBill.Taylor@Sun.COM
6459517SBill.Taylor@Sun.COM /* This is where Phase 1 of resource initialization begins */
6469517SBill.Taylor@Sun.COM cleanup = HERMON_RSRC_CLEANUP_LEVEL0;
6479517SBill.Taylor@Sun.COM
6489517SBill.Taylor@Sun.COM /* Build kmem cache name from Hermon instance */
649*12965SWilliam.Taylor@Oracle.COM rsrc_name = kmem_zalloc(HERMON_RSRC_NAME_MAXLEN, KM_SLEEP);
6509517SBill.Taylor@Sun.COM HERMON_RSRC_NAME(rsrc_name, HERMON_RSRC_CACHE);
6519517SBill.Taylor@Sun.COM
6529517SBill.Taylor@Sun.COM /*
6539517SBill.Taylor@Sun.COM * Create the kmem_cache for "hermon_rsrc_t" structures
6549517SBill.Taylor@Sun.COM * (kmem_cache_create will SLEEP until successful)
6559517SBill.Taylor@Sun.COM */
6569517SBill.Taylor@Sun.COM state->hs_rsrc_cache = kmem_cache_create(rsrc_name,
6579517SBill.Taylor@Sun.COM sizeof (hermon_rsrc_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
6589517SBill.Taylor@Sun.COM
6599517SBill.Taylor@Sun.COM /*
6609517SBill.Taylor@Sun.COM * Allocate an array of hermon_rsrc_pool_info_t's (used in all
6619517SBill.Taylor@Sun.COM * subsequent resource allocations)
6629517SBill.Taylor@Sun.COM */
6639517SBill.Taylor@Sun.COM state->hs_rsrc_hdl = kmem_zalloc(HERMON_NUM_RESOURCES *
6649517SBill.Taylor@Sun.COM sizeof (hermon_rsrc_pool_info_t), KM_SLEEP);
6659517SBill.Taylor@Sun.COM
6669517SBill.Taylor@Sun.COM /* Pull in the configuration profile */
6679517SBill.Taylor@Sun.COM cfgprof = state->hs_cfg_profile;
6689517SBill.Taylor@Sun.COM
6699517SBill.Taylor@Sun.COM /* Initialize the resource pool for "out" mailboxes */
6709517SBill.Taylor@Sun.COM num = ((uint64_t)1 << cfgprof->cp_log_num_outmbox);
6719517SBill.Taylor@Sun.COM size = ((uint64_t)1 << cfgprof->cp_log_outmbox_size);
6729517SBill.Taylor@Sun.COM rsrc_pool = &state->hs_rsrc_hdl[HERMON_OUT_MBOX];
6739517SBill.Taylor@Sun.COM rsrc_pool->rsrc_loc = HERMON_IN_SYSMEM;
6749517SBill.Taylor@Sun.COM rsrc_pool->rsrc_pool_size = (size * num);
6759517SBill.Taylor@Sun.COM rsrc_pool->rsrc_shift = cfgprof->cp_log_outmbox_size;
6769517SBill.Taylor@Sun.COM rsrc_pool->rsrc_quantum = (uint_t)size;
6779517SBill.Taylor@Sun.COM rsrc_pool->rsrc_align = HERMON_MBOX_ALIGN;
6789517SBill.Taylor@Sun.COM rsrc_pool->rsrc_state = state;
6799517SBill.Taylor@Sun.COM mbox_info.mbi_num = num;
6809517SBill.Taylor@Sun.COM mbox_info.mbi_size = size;
6819517SBill.Taylor@Sun.COM mbox_info.mbi_rsrcpool = rsrc_pool;
6829517SBill.Taylor@Sun.COM status = hermon_rsrc_mbox_init(state, &mbox_info);
6839517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
6849517SBill.Taylor@Sun.COM hermon_rsrc_fini(state, cleanup);
6859517SBill.Taylor@Sun.COM status = DDI_FAILURE;
6869517SBill.Taylor@Sun.COM goto rsrcinitp1_fail;
6879517SBill.Taylor@Sun.COM }
6889517SBill.Taylor@Sun.COM cleanup = HERMON_RSRC_CLEANUP_LEVEL1;
6899517SBill.Taylor@Sun.COM
6909517SBill.Taylor@Sun.COM /* Initialize the mailbox list */
6919517SBill.Taylor@Sun.COM status = hermon_outmbox_list_init(state);
6929517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
6939517SBill.Taylor@Sun.COM hermon_rsrc_fini(state, cleanup);
6949517SBill.Taylor@Sun.COM status = DDI_FAILURE;
6959517SBill.Taylor@Sun.COM goto rsrcinitp1_fail;
6969517SBill.Taylor@Sun.COM }
6979517SBill.Taylor@Sun.COM cleanup = HERMON_RSRC_CLEANUP_LEVEL2;
6989517SBill.Taylor@Sun.COM
6999517SBill.Taylor@Sun.COM /* Initialize the resource pool for "interrupt out" mailboxes */
7009517SBill.Taylor@Sun.COM num = ((uint64_t)1 << cfgprof->cp_log_num_intr_outmbox);
7019517SBill.Taylor@Sun.COM size = ((uint64_t)1 << cfgprof->cp_log_outmbox_size);
7029517SBill.Taylor@Sun.COM rsrc_pool = &state->hs_rsrc_hdl[HERMON_INTR_OUT_MBOX];
7039517SBill.Taylor@Sun.COM rsrc_pool->rsrc_loc = HERMON_IN_SYSMEM;
7049517SBill.Taylor@Sun.COM rsrc_pool->rsrc_pool_size = (size * num);
7059517SBill.Taylor@Sun.COM rsrc_pool->rsrc_shift = cfgprof->cp_log_outmbox_size;
7069517SBill.Taylor@Sun.COM rsrc_pool->rsrc_quantum = (uint_t)size;
7079517SBill.Taylor@Sun.COM rsrc_pool->rsrc_align = HERMON_MBOX_ALIGN;
7089517SBill.Taylor@Sun.COM rsrc_pool->rsrc_state = state;
7099517SBill.Taylor@Sun.COM mbox_info.mbi_num = num;
7109517SBill.Taylor@Sun.COM mbox_info.mbi_size = size;
7119517SBill.Taylor@Sun.COM mbox_info.mbi_rsrcpool = rsrc_pool;
7129517SBill.Taylor@Sun.COM status = hermon_rsrc_mbox_init(state, &mbox_info);
7139517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
7149517SBill.Taylor@Sun.COM hermon_rsrc_fini(state, cleanup);
7159517SBill.Taylor@Sun.COM status = DDI_FAILURE;
7169517SBill.Taylor@Sun.COM goto rsrcinitp1_fail;
7179517SBill.Taylor@Sun.COM }
7189517SBill.Taylor@Sun.COM cleanup = HERMON_RSRC_CLEANUP_LEVEL3;
7199517SBill.Taylor@Sun.COM
7209517SBill.Taylor@Sun.COM /* Initialize the mailbox list */
7219517SBill.Taylor@Sun.COM status = hermon_intr_outmbox_list_init(state);
7229517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
7239517SBill.Taylor@Sun.COM hermon_rsrc_fini(state, cleanup);
7249517SBill.Taylor@Sun.COM status = DDI_FAILURE;
7259517SBill.Taylor@Sun.COM goto rsrcinitp1_fail;
7269517SBill.Taylor@Sun.COM }
7279517SBill.Taylor@Sun.COM cleanup = HERMON_RSRC_CLEANUP_LEVEL4;
7289517SBill.Taylor@Sun.COM
7299517SBill.Taylor@Sun.COM /* Initialize the resource pool for "in" mailboxes */
7309517SBill.Taylor@Sun.COM num = ((uint64_t)1 << cfgprof->cp_log_num_inmbox);
7319517SBill.Taylor@Sun.COM size = ((uint64_t)1 << cfgprof->cp_log_inmbox_size);
7329517SBill.Taylor@Sun.COM rsrc_pool = &state->hs_rsrc_hdl[HERMON_IN_MBOX];
7339517SBill.Taylor@Sun.COM rsrc_pool->rsrc_loc = HERMON_IN_SYSMEM;
7349517SBill.Taylor@Sun.COM rsrc_pool->rsrc_pool_size = (size * num);
7359517SBill.Taylor@Sun.COM rsrc_pool->rsrc_shift = cfgprof->cp_log_inmbox_size;
7369517SBill.Taylor@Sun.COM rsrc_pool->rsrc_quantum = (uint_t)size;
7379517SBill.Taylor@Sun.COM rsrc_pool->rsrc_align = HERMON_MBOX_ALIGN;
7389517SBill.Taylor@Sun.COM rsrc_pool->rsrc_state = state;
7399517SBill.Taylor@Sun.COM mbox_info.mbi_num = num;
7409517SBill.Taylor@Sun.COM mbox_info.mbi_size = size;
7419517SBill.Taylor@Sun.COM mbox_info.mbi_rsrcpool = rsrc_pool;
7429517SBill.Taylor@Sun.COM status = hermon_rsrc_mbox_init(state, &mbox_info);
7439517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
7449517SBill.Taylor@Sun.COM hermon_rsrc_fini(state, cleanup);
7459517SBill.Taylor@Sun.COM status = DDI_FAILURE;
7469517SBill.Taylor@Sun.COM goto rsrcinitp1_fail;
7479517SBill.Taylor@Sun.COM }
7489517SBill.Taylor@Sun.COM cleanup = HERMON_RSRC_CLEANUP_LEVEL5;
7499517SBill.Taylor@Sun.COM
7509517SBill.Taylor@Sun.COM /* Initialize the mailbox list */
7519517SBill.Taylor@Sun.COM status = hermon_inmbox_list_init(state);
7529517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
7539517SBill.Taylor@Sun.COM hermon_rsrc_fini(state, cleanup);
7549517SBill.Taylor@Sun.COM status = DDI_FAILURE;
7559517SBill.Taylor@Sun.COM goto rsrcinitp1_fail;
7569517SBill.Taylor@Sun.COM }
7579517SBill.Taylor@Sun.COM cleanup = HERMON_RSRC_CLEANUP_LEVEL6;
7589517SBill.Taylor@Sun.COM
7599517SBill.Taylor@Sun.COM /* Initialize the resource pool for "interrupt in" mailboxes */
7609517SBill.Taylor@Sun.COM num = ((uint64_t)1 << cfgprof->cp_log_num_intr_inmbox);
7619517SBill.Taylor@Sun.COM size = ((uint64_t)1 << cfgprof->cp_log_inmbox_size);
7629517SBill.Taylor@Sun.COM rsrc_pool = &state->hs_rsrc_hdl[HERMON_INTR_IN_MBOX];
7639517SBill.Taylor@Sun.COM rsrc_pool->rsrc_loc = HERMON_IN_SYSMEM;
7649517SBill.Taylor@Sun.COM rsrc_pool->rsrc_pool_size = (size * num);
7659517SBill.Taylor@Sun.COM rsrc_pool->rsrc_shift = cfgprof->cp_log_inmbox_size;
7669517SBill.Taylor@Sun.COM rsrc_pool->rsrc_quantum = (uint_t)size;
7679517SBill.Taylor@Sun.COM rsrc_pool->rsrc_align = HERMON_MBOX_ALIGN;
7689517SBill.Taylor@Sun.COM rsrc_pool->rsrc_state = state;
7699517SBill.Taylor@Sun.COM mbox_info.mbi_num = num;
7709517SBill.Taylor@Sun.COM mbox_info.mbi_size = size;
7719517SBill.Taylor@Sun.COM mbox_info.mbi_rsrcpool = rsrc_pool;
7729517SBill.Taylor@Sun.COM status = hermon_rsrc_mbox_init(state, &mbox_info);
7739517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
7749517SBill.Taylor@Sun.COM hermon_rsrc_fini(state, cleanup);
7759517SBill.Taylor@Sun.COM status = DDI_FAILURE;
7769517SBill.Taylor@Sun.COM goto rsrcinitp1_fail;
7779517SBill.Taylor@Sun.COM }
7789517SBill.Taylor@Sun.COM cleanup = HERMON_RSRC_CLEANUP_LEVEL7;
7799517SBill.Taylor@Sun.COM
7809517SBill.Taylor@Sun.COM /* Initialize the mailbox list */
7819517SBill.Taylor@Sun.COM status = hermon_intr_inmbox_list_init(state);
7829517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
7839517SBill.Taylor@Sun.COM hermon_rsrc_fini(state, cleanup);
7849517SBill.Taylor@Sun.COM status = DDI_FAILURE;
7859517SBill.Taylor@Sun.COM goto rsrcinitp1_fail;
7869517SBill.Taylor@Sun.COM }
7879517SBill.Taylor@Sun.COM cleanup = HERMON_RSRC_CLEANUP_PHASE1_COMPLETE;
7889517SBill.Taylor@Sun.COM kmem_free(rsrc_name, HERMON_RSRC_NAME_MAXLEN);
7899517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
7909517SBill.Taylor@Sun.COM
7919517SBill.Taylor@Sun.COM rsrcinitp1_fail:
7929517SBill.Taylor@Sun.COM kmem_free(rsrc_name, HERMON_RSRC_NAME_MAXLEN);
7939517SBill.Taylor@Sun.COM return (status);
7949517SBill.Taylor@Sun.COM }
7959517SBill.Taylor@Sun.COM
7969517SBill.Taylor@Sun.COM
7979517SBill.Taylor@Sun.COM /*
7989517SBill.Taylor@Sun.COM * hermon_rsrc_init_phase2()
7999517SBill.Taylor@Sun.COM * Context: Only called from attach() path context
8009517SBill.Taylor@Sun.COM */
8019517SBill.Taylor@Sun.COM int
hermon_rsrc_init_phase2(hermon_state_t * state)8029517SBill.Taylor@Sun.COM hermon_rsrc_init_phase2(hermon_state_t *state)
8039517SBill.Taylor@Sun.COM {
8049517SBill.Taylor@Sun.COM hermon_rsrc_sw_hdl_info_t hdl_info;
8059517SBill.Taylor@Sun.COM hermon_rsrc_hw_entry_info_t entry_info;
8069517SBill.Taylor@Sun.COM hermon_rsrc_pool_info_t *rsrc_pool;
8079517SBill.Taylor@Sun.COM hermon_rsrc_cleanup_level_t cleanup, ncleanup;
8089517SBill.Taylor@Sun.COM hermon_cfg_profile_t *cfgprof;
8099517SBill.Taylor@Sun.COM hermon_hw_querydevlim_t *devlim;
8109517SBill.Taylor@Sun.COM uint64_t num, max, num_prealloc;
8119517SBill.Taylor@Sun.COM uint_t mcg_size, mcg_size_shift;
8129517SBill.Taylor@Sun.COM int i, status;
8139517SBill.Taylor@Sun.COM char *rsrc_name;
8149517SBill.Taylor@Sun.COM
8159517SBill.Taylor@Sun.COM ASSERT(state != NULL);
8169517SBill.Taylor@Sun.COM
8179517SBill.Taylor@Sun.COM /* Phase 2 initialization begins where Phase 1 left off */
8189517SBill.Taylor@Sun.COM cleanup = HERMON_RSRC_CLEANUP_PHASE1_COMPLETE;
8199517SBill.Taylor@Sun.COM
8209517SBill.Taylor@Sun.COM /* Allocate the ICM resource name space */
8219517SBill.Taylor@Sun.COM
8229517SBill.Taylor@Sun.COM /* Build the ICM vmem arena names from Hermon instance */
823*12965SWilliam.Taylor@Oracle.COM rsrc_name = kmem_zalloc(HERMON_RSRC_NAME_MAXLEN, KM_SLEEP);
8249517SBill.Taylor@Sun.COM
8259517SBill.Taylor@Sun.COM /*
8269517SBill.Taylor@Sun.COM * Initialize the resource pools for all objects that exist in
8279517SBill.Taylor@Sun.COM * context memory (ICM). The ICM consists of context tables, each
8289517SBill.Taylor@Sun.COM * type of resource (QP, CQ, EQ, etc) having it's own context table
8299517SBill.Taylor@Sun.COM * (QPC, CQC, EQC, etc...).
8309517SBill.Taylor@Sun.COM */
8319517SBill.Taylor@Sun.COM cfgprof = state->hs_cfg_profile;
8329517SBill.Taylor@Sun.COM devlim = &state->hs_devlim;
8339517SBill.Taylor@Sun.COM
8349517SBill.Taylor@Sun.COM /*
8359517SBill.Taylor@Sun.COM * Initialize the resource pools for each of the driver resources.
8369517SBill.Taylor@Sun.COM * With a few exceptions, these resources fall into the two cateogories
8379517SBill.Taylor@Sun.COM * of either hw_entries or sw_entries.
8389517SBill.Taylor@Sun.COM */
8399517SBill.Taylor@Sun.COM
8409517SBill.Taylor@Sun.COM /*
8419517SBill.Taylor@Sun.COM * Initialize the resource pools for ICM (hardware) types first.
8429517SBill.Taylor@Sun.COM * These resources are managed through vmem arenas, which are
8439517SBill.Taylor@Sun.COM * created via the rsrc pool initialization routine. Note that,
8449517SBill.Taylor@Sun.COM * due to further calculations, the MCG resource pool is
8459517SBill.Taylor@Sun.COM * initialized seperately.
8469517SBill.Taylor@Sun.COM */
8479517SBill.Taylor@Sun.COM for (i = 0; i < HERMON_NUM_ICM_RESOURCES; i++) {
8489517SBill.Taylor@Sun.COM
8499517SBill.Taylor@Sun.COM rsrc_pool = &state->hs_rsrc_hdl[i];
8509517SBill.Taylor@Sun.COM rsrc_pool->rsrc_type = i;
851*12965SWilliam.Taylor@Oracle.COM rsrc_pool->rsrc_state = state;
8529517SBill.Taylor@Sun.COM
8539517SBill.Taylor@Sun.COM /* Set the resource-specific attributes */
8549517SBill.Taylor@Sun.COM switch (i) {
8559517SBill.Taylor@Sun.COM case HERMON_MTT:
8569517SBill.Taylor@Sun.COM max = ((uint64_t)1 << devlim->log_max_mtt);
8579517SBill.Taylor@Sun.COM num_prealloc = ((uint64_t)1 << devlim->log_rsvd_mtt);
8589517SBill.Taylor@Sun.COM HERMON_RSRC_NAME(rsrc_name, HERMON_MTT_VMEM);
8599517SBill.Taylor@Sun.COM ncleanup = HERMON_RSRC_CLEANUP_LEVEL9;
8609517SBill.Taylor@Sun.COM break;
8619517SBill.Taylor@Sun.COM
8629517SBill.Taylor@Sun.COM case HERMON_DMPT:
8639517SBill.Taylor@Sun.COM max = ((uint64_t)1 << devlim->log_max_dmpt);
8649517SBill.Taylor@Sun.COM num_prealloc = ((uint64_t)1 << devlim->log_rsvd_dmpt);
8659517SBill.Taylor@Sun.COM HERMON_RSRC_NAME(rsrc_name, HERMON_DMPT_VMEM);
8669517SBill.Taylor@Sun.COM ncleanup = HERMON_RSRC_CLEANUP_LEVEL10;
8679517SBill.Taylor@Sun.COM break;
8689517SBill.Taylor@Sun.COM
8699517SBill.Taylor@Sun.COM case HERMON_QPC:
8709517SBill.Taylor@Sun.COM max = ((uint64_t)1 << devlim->log_max_qp);
8719517SBill.Taylor@Sun.COM num_prealloc = ((uint64_t)1 << devlim->log_rsvd_qp);
8729517SBill.Taylor@Sun.COM HERMON_RSRC_NAME(rsrc_name, HERMON_QPC_VMEM);
8739517SBill.Taylor@Sun.COM ncleanup = HERMON_RSRC_CLEANUP_LEVEL11;
8749517SBill.Taylor@Sun.COM break;
8759517SBill.Taylor@Sun.COM
8769517SBill.Taylor@Sun.COM case HERMON_CQC:
8779517SBill.Taylor@Sun.COM max = ((uint64_t)1 << devlim->log_max_cq);
8789517SBill.Taylor@Sun.COM num_prealloc = ((uint64_t)1 << devlim->log_rsvd_cq);
8799517SBill.Taylor@Sun.COM HERMON_RSRC_NAME(rsrc_name, HERMON_CQC_VMEM);
8809517SBill.Taylor@Sun.COM ncleanup = HERMON_RSRC_CLEANUP_LEVEL13;
8819517SBill.Taylor@Sun.COM break;
8829517SBill.Taylor@Sun.COM
8839517SBill.Taylor@Sun.COM case HERMON_SRQC:
8849517SBill.Taylor@Sun.COM max = ((uint64_t)1 << devlim->log_max_srq);
8859517SBill.Taylor@Sun.COM num_prealloc = ((uint64_t)1 << devlim->log_rsvd_srq);
8869517SBill.Taylor@Sun.COM HERMON_RSRC_NAME(rsrc_name, HERMON_SRQC_VMEM);
8879517SBill.Taylor@Sun.COM ncleanup = HERMON_RSRC_CLEANUP_LEVEL16;
8889517SBill.Taylor@Sun.COM break;
8899517SBill.Taylor@Sun.COM
8909517SBill.Taylor@Sun.COM case HERMON_EQC:
8919517SBill.Taylor@Sun.COM max = ((uint64_t)1 << devlim->log_max_eq);
892*12965SWilliam.Taylor@Oracle.COM num_prealloc = state->hs_rsvd_eqs;
8939517SBill.Taylor@Sun.COM HERMON_RSRC_NAME(rsrc_name, HERMON_EQC_VMEM);
8949517SBill.Taylor@Sun.COM ncleanup = HERMON_RSRC_CLEANUP_LEVEL18;
8959517SBill.Taylor@Sun.COM break;
8969517SBill.Taylor@Sun.COM
8979517SBill.Taylor@Sun.COM case HERMON_MCG: /* handled below */
8989517SBill.Taylor@Sun.COM case HERMON_AUXC:
8999517SBill.Taylor@Sun.COM case HERMON_ALTC:
9009517SBill.Taylor@Sun.COM case HERMON_RDB:
9019517SBill.Taylor@Sun.COM case HERMON_CMPT_QPC:
9029517SBill.Taylor@Sun.COM case HERMON_CMPT_SRQC:
9039517SBill.Taylor@Sun.COM case HERMON_CMPT_CQC:
9049517SBill.Taylor@Sun.COM case HERMON_CMPT_EQC:
9059517SBill.Taylor@Sun.COM default:
9069517SBill.Taylor@Sun.COM /* We don't need to initialize this rsrc here. */
9079517SBill.Taylor@Sun.COM continue;
9089517SBill.Taylor@Sun.COM }
9099517SBill.Taylor@Sun.COM
9109517SBill.Taylor@Sun.COM /* Set the common values for all resource pools */
9119517SBill.Taylor@Sun.COM rsrc_pool->rsrc_state = state;
9129517SBill.Taylor@Sun.COM rsrc_pool->rsrc_loc = HERMON_IN_ICM;
9139517SBill.Taylor@Sun.COM rsrc_pool->rsrc_pool_size = state->hs_icm[i].table_size;
9149517SBill.Taylor@Sun.COM rsrc_pool->rsrc_align = state->hs_icm[i].table_size;
9159517SBill.Taylor@Sun.COM rsrc_pool->rsrc_shift = state->hs_icm[i].log_object_size;
9169517SBill.Taylor@Sun.COM rsrc_pool->rsrc_quantum = state->hs_icm[i].object_size;
9179517SBill.Taylor@Sun.COM
9189517SBill.Taylor@Sun.COM /* Now, initialize the entry_info and call the init routine */
9199517SBill.Taylor@Sun.COM entry_info.hwi_num = state->hs_icm[i].num_entries;
9209517SBill.Taylor@Sun.COM entry_info.hwi_max = max;
9219517SBill.Taylor@Sun.COM entry_info.hwi_prealloc = num_prealloc;
9229517SBill.Taylor@Sun.COM entry_info.hwi_rsrcpool = rsrc_pool;
9239517SBill.Taylor@Sun.COM entry_info.hwi_rsrcname = rsrc_name;
9249517SBill.Taylor@Sun.COM status = hermon_rsrc_hw_entries_init(state, &entry_info);
9259517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
9269517SBill.Taylor@Sun.COM hermon_rsrc_fini(state, cleanup);
9279517SBill.Taylor@Sun.COM status = DDI_FAILURE;
9289517SBill.Taylor@Sun.COM goto rsrcinitp2_fail;
9299517SBill.Taylor@Sun.COM }
9309517SBill.Taylor@Sun.COM cleanup = ncleanup;
9319517SBill.Taylor@Sun.COM }
9329517SBill.Taylor@Sun.COM
9339517SBill.Taylor@Sun.COM /*
9349517SBill.Taylor@Sun.COM * Initialize the Multicast Group (MCG) entries. First, calculate
9359517SBill.Taylor@Sun.COM * (and validate) the size of the MCGs.
9369517SBill.Taylor@Sun.COM */
9379517SBill.Taylor@Sun.COM status = hermon_rsrc_mcg_entry_get_size(state, &mcg_size_shift);
9389517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
9399517SBill.Taylor@Sun.COM hermon_rsrc_fini(state, cleanup);
9409517SBill.Taylor@Sun.COM status = DDI_FAILURE;
9419517SBill.Taylor@Sun.COM goto rsrcinitp2_fail;
9429517SBill.Taylor@Sun.COM }
9439517SBill.Taylor@Sun.COM mcg_size = HERMON_MCGMEM_SZ(state);
9449517SBill.Taylor@Sun.COM
9459517SBill.Taylor@Sun.COM /*
9469517SBill.Taylor@Sun.COM * Initialize the resource pool for the MCG table entries. Notice
9479517SBill.Taylor@Sun.COM * that the number of MCGs is configurable. Note also that a certain
9489517SBill.Taylor@Sun.COM * number of MCGs must be set aside for Hermon firmware use (they
9499517SBill.Taylor@Sun.COM * correspond to the number of MCGs used by the internal hash
9509517SBill.Taylor@Sun.COM * function).
9519517SBill.Taylor@Sun.COM */
9529517SBill.Taylor@Sun.COM num = ((uint64_t)1 << cfgprof->cp_log_num_mcg);
9539517SBill.Taylor@Sun.COM max = ((uint64_t)1 << devlim->log_max_mcg);
9549517SBill.Taylor@Sun.COM num_prealloc = ((uint64_t)1 << cfgprof->cp_log_num_mcg_hash);
9559517SBill.Taylor@Sun.COM rsrc_pool = &state->hs_rsrc_hdl[HERMON_MCG];
9569517SBill.Taylor@Sun.COM rsrc_pool->rsrc_loc = HERMON_IN_ICM;
9579517SBill.Taylor@Sun.COM rsrc_pool->rsrc_pool_size = (mcg_size * num);
9589517SBill.Taylor@Sun.COM rsrc_pool->rsrc_shift = mcg_size_shift;
9599517SBill.Taylor@Sun.COM rsrc_pool->rsrc_quantum = mcg_size;
9609517SBill.Taylor@Sun.COM rsrc_pool->rsrc_align = (mcg_size * num);
9619517SBill.Taylor@Sun.COM rsrc_pool->rsrc_state = state;
9629517SBill.Taylor@Sun.COM HERMON_RSRC_NAME(rsrc_name, HERMON_MCG_VMEM);
9639517SBill.Taylor@Sun.COM entry_info.hwi_num = num;
9649517SBill.Taylor@Sun.COM entry_info.hwi_max = max;
9659517SBill.Taylor@Sun.COM entry_info.hwi_prealloc = num_prealloc;
9669517SBill.Taylor@Sun.COM entry_info.hwi_rsrcpool = rsrc_pool;
9679517SBill.Taylor@Sun.COM entry_info.hwi_rsrcname = rsrc_name;
9689517SBill.Taylor@Sun.COM status = hermon_rsrc_hw_entries_init(state, &entry_info);
9699517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
9709517SBill.Taylor@Sun.COM hermon_rsrc_fini(state, cleanup);
9719517SBill.Taylor@Sun.COM status = DDI_FAILURE;
9729517SBill.Taylor@Sun.COM goto rsrcinitp2_fail;
9739517SBill.Taylor@Sun.COM }
9749517SBill.Taylor@Sun.COM cleanup = HERMON_RSRC_CLEANUP_LEVEL19;
9759517SBill.Taylor@Sun.COM
9769517SBill.Taylor@Sun.COM /*
9779517SBill.Taylor@Sun.COM * Initialize the full range of ICM for the AUXC resource.
9789517SBill.Taylor@Sun.COM * This is done because its size is so small, about 1 byte per QP.
9799517SBill.Taylor@Sun.COM */
9809517SBill.Taylor@Sun.COM
9819517SBill.Taylor@Sun.COM /*
9829517SBill.Taylor@Sun.COM * Initialize the Hermon command handling interfaces. This step
9839517SBill.Taylor@Sun.COM * sets up the outstanding command tracking mechanism for easy access
9849517SBill.Taylor@Sun.COM * and fast allocation (see hermon_cmd.c for more details).
9859517SBill.Taylor@Sun.COM */
9869517SBill.Taylor@Sun.COM status = hermon_outstanding_cmdlist_init(state);
9879517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
9889517SBill.Taylor@Sun.COM hermon_rsrc_fini(state, cleanup);
9899517SBill.Taylor@Sun.COM status = DDI_FAILURE;
9909517SBill.Taylor@Sun.COM goto rsrcinitp2_fail;
9919517SBill.Taylor@Sun.COM }
9929517SBill.Taylor@Sun.COM cleanup = HERMON_RSRC_CLEANUP_LEVEL20;
9939517SBill.Taylor@Sun.COM
9949517SBill.Taylor@Sun.COM /* Initialize the resource pool and vmem arena for the PD handles */
9959517SBill.Taylor@Sun.COM rsrc_pool = &state->hs_rsrc_hdl[HERMON_PDHDL];
9969517SBill.Taylor@Sun.COM rsrc_pool->rsrc_loc = HERMON_IN_SYSMEM;
9979517SBill.Taylor@Sun.COM rsrc_pool->rsrc_quantum = sizeof (struct hermon_sw_pd_s);
9989517SBill.Taylor@Sun.COM rsrc_pool->rsrc_state = state;
9999517SBill.Taylor@Sun.COM HERMON_RSRC_NAME(rsrc_name, HERMON_PDHDL_CACHE);
10009517SBill.Taylor@Sun.COM hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_pd);
10019517SBill.Taylor@Sun.COM hdl_info.swi_max = ((uint64_t)1 << devlim->log_max_pd);
10029517SBill.Taylor@Sun.COM hdl_info.swi_rsrcpool = rsrc_pool;
10039517SBill.Taylor@Sun.COM hdl_info.swi_constructor = hermon_rsrc_pdhdl_constructor;
10049517SBill.Taylor@Sun.COM hdl_info.swi_destructor = hermon_rsrc_pdhdl_destructor;
10059517SBill.Taylor@Sun.COM hdl_info.swi_rsrcname = rsrc_name;
10069517SBill.Taylor@Sun.COM hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT;
10079517SBill.Taylor@Sun.COM status = hermon_rsrc_pd_handles_init(state, &hdl_info);
10089517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
10099517SBill.Taylor@Sun.COM hermon_rsrc_fini(state, cleanup);
10109517SBill.Taylor@Sun.COM status = DDI_FAILURE;
10119517SBill.Taylor@Sun.COM goto rsrcinitp2_fail;
10129517SBill.Taylor@Sun.COM }
10139517SBill.Taylor@Sun.COM cleanup = HERMON_RSRC_CLEANUP_LEVEL21;
10149517SBill.Taylor@Sun.COM
10159517SBill.Taylor@Sun.COM /*
10169517SBill.Taylor@Sun.COM * Initialize the resource pools for the rest of the software handles.
10179517SBill.Taylor@Sun.COM * This includes MR handles, EQ handles, QP handles, etc. These
10189517SBill.Taylor@Sun.COM * objects are almost entirely managed using kmem_cache routines,
10199517SBill.Taylor@Sun.COM * and do not utilize a vmem arena.
10209517SBill.Taylor@Sun.COM */
10219517SBill.Taylor@Sun.COM for (i = HERMON_NUM_ICM_RESOURCES; i < HERMON_NUM_RESOURCES; i++) {
10229517SBill.Taylor@Sun.COM rsrc_pool = &state->hs_rsrc_hdl[i];
1023*12965SWilliam.Taylor@Oracle.COM rsrc_pool->rsrc_type = i;
10249517SBill.Taylor@Sun.COM
10259517SBill.Taylor@Sun.COM /* Set the resource-specific attributes */
10269517SBill.Taylor@Sun.COM switch (i) {
10279517SBill.Taylor@Sun.COM case HERMON_MRHDL:
10289517SBill.Taylor@Sun.COM rsrc_pool->rsrc_quantum =
10299517SBill.Taylor@Sun.COM sizeof (struct hermon_sw_mr_s);
10309517SBill.Taylor@Sun.COM HERMON_RSRC_NAME(rsrc_name, HERMON_MRHDL_CACHE);
10319517SBill.Taylor@Sun.COM hdl_info.swi_num =
10329517SBill.Taylor@Sun.COM ((uint64_t)1 << cfgprof->cp_log_num_dmpt) +
10339517SBill.Taylor@Sun.COM ((uint64_t)1 << cfgprof->cp_log_num_cmpt);
10349517SBill.Taylor@Sun.COM hdl_info.swi_max =
10359517SBill.Taylor@Sun.COM ((uint64_t)1 << cfgprof->cp_log_num_dmpt) +
10369517SBill.Taylor@Sun.COM ((uint64_t)1 << cfgprof->cp_log_num_cmpt);
10379517SBill.Taylor@Sun.COM hdl_info.swi_constructor =
10389517SBill.Taylor@Sun.COM hermon_rsrc_mrhdl_constructor;
10399517SBill.Taylor@Sun.COM hdl_info.swi_destructor = hermon_rsrc_mrhdl_destructor;
10409517SBill.Taylor@Sun.COM hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT;
10419517SBill.Taylor@Sun.COM ncleanup = HERMON_RSRC_CLEANUP_LEVEL22;
10429517SBill.Taylor@Sun.COM break;
10439517SBill.Taylor@Sun.COM
10449517SBill.Taylor@Sun.COM case HERMON_EQHDL:
10459517SBill.Taylor@Sun.COM rsrc_pool->rsrc_quantum =
10469517SBill.Taylor@Sun.COM sizeof (struct hermon_sw_eq_s);
10479517SBill.Taylor@Sun.COM HERMON_RSRC_NAME(rsrc_name, HERMON_EQHDL_CACHE);
10489517SBill.Taylor@Sun.COM hdl_info.swi_num = HERMON_NUM_EQ;
10499517SBill.Taylor@Sun.COM hdl_info.swi_max = ((uint64_t)1 << devlim->log_max_eq);
10509517SBill.Taylor@Sun.COM hdl_info.swi_constructor = NULL;
10519517SBill.Taylor@Sun.COM hdl_info.swi_destructor = NULL;
10529517SBill.Taylor@Sun.COM hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT;
10539517SBill.Taylor@Sun.COM ncleanup = HERMON_RSRC_CLEANUP_LEVEL23;
10549517SBill.Taylor@Sun.COM break;
10559517SBill.Taylor@Sun.COM
10569517SBill.Taylor@Sun.COM case HERMON_CQHDL:
10579517SBill.Taylor@Sun.COM rsrc_pool->rsrc_quantum =
10589517SBill.Taylor@Sun.COM sizeof (struct hermon_sw_cq_s);
10599517SBill.Taylor@Sun.COM HERMON_RSRC_NAME(rsrc_name, HERMON_CQHDL_CACHE);
10609517SBill.Taylor@Sun.COM hdl_info.swi_num =
10619517SBill.Taylor@Sun.COM (uint64_t)1 << cfgprof->cp_log_num_cq;
10629517SBill.Taylor@Sun.COM hdl_info.swi_max = (uint64_t)1 << devlim->log_max_cq;
10639517SBill.Taylor@Sun.COM hdl_info.swi_constructor =
10649517SBill.Taylor@Sun.COM hermon_rsrc_cqhdl_constructor;
10659517SBill.Taylor@Sun.COM hdl_info.swi_destructor = hermon_rsrc_cqhdl_destructor;
1066*12965SWilliam.Taylor@Oracle.COM hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT;
10679517SBill.Taylor@Sun.COM hdl_info.swi_prealloc_sz = sizeof (hermon_cqhdl_t);
10689517SBill.Taylor@Sun.COM ncleanup = HERMON_RSRC_CLEANUP_LEVEL24;
10699517SBill.Taylor@Sun.COM break;
10709517SBill.Taylor@Sun.COM
10719517SBill.Taylor@Sun.COM case HERMON_SRQHDL:
10729517SBill.Taylor@Sun.COM rsrc_pool->rsrc_quantum =
10739517SBill.Taylor@Sun.COM sizeof (struct hermon_sw_srq_s);
10749517SBill.Taylor@Sun.COM HERMON_RSRC_NAME(rsrc_name, HERMON_SRQHDL_CACHE);
10759517SBill.Taylor@Sun.COM hdl_info.swi_num =
10769517SBill.Taylor@Sun.COM (uint64_t)1 << cfgprof->cp_log_num_srq;
10779517SBill.Taylor@Sun.COM hdl_info.swi_max = (uint64_t)1 << devlim->log_max_srq;
10789517SBill.Taylor@Sun.COM hdl_info.swi_constructor =
10799517SBill.Taylor@Sun.COM hermon_rsrc_srqhdl_constructor;
10809517SBill.Taylor@Sun.COM hdl_info.swi_destructor = hermon_rsrc_srqhdl_destructor;
1081*12965SWilliam.Taylor@Oracle.COM hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT;
10829517SBill.Taylor@Sun.COM hdl_info.swi_prealloc_sz = sizeof (hermon_srqhdl_t);
10839517SBill.Taylor@Sun.COM ncleanup = HERMON_RSRC_CLEANUP_LEVEL25;
10849517SBill.Taylor@Sun.COM break;
10859517SBill.Taylor@Sun.COM
10869517SBill.Taylor@Sun.COM case HERMON_AHHDL:
10879517SBill.Taylor@Sun.COM rsrc_pool->rsrc_quantum =
10889517SBill.Taylor@Sun.COM sizeof (struct hermon_sw_ah_s);
10899517SBill.Taylor@Sun.COM HERMON_RSRC_NAME(rsrc_name, HERMON_AHHDL_CACHE);
10909517SBill.Taylor@Sun.COM hdl_info.swi_num =
10919517SBill.Taylor@Sun.COM (uint64_t)1 << cfgprof->cp_log_num_ah;
10929517SBill.Taylor@Sun.COM hdl_info.swi_max = HERMON_NUM_AH;
10939517SBill.Taylor@Sun.COM hdl_info.swi_constructor =
10949517SBill.Taylor@Sun.COM hermon_rsrc_ahhdl_constructor;
10959517SBill.Taylor@Sun.COM hdl_info.swi_destructor = hermon_rsrc_ahhdl_destructor;
10969517SBill.Taylor@Sun.COM hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT;
10979517SBill.Taylor@Sun.COM ncleanup = HERMON_RSRC_CLEANUP_LEVEL26;
10989517SBill.Taylor@Sun.COM break;
10999517SBill.Taylor@Sun.COM
11009517SBill.Taylor@Sun.COM case HERMON_QPHDL:
11019517SBill.Taylor@Sun.COM rsrc_pool->rsrc_quantum =
11029517SBill.Taylor@Sun.COM sizeof (struct hermon_sw_qp_s);
11039517SBill.Taylor@Sun.COM HERMON_RSRC_NAME(rsrc_name, HERMON_QPHDL_CACHE);
11049517SBill.Taylor@Sun.COM hdl_info.swi_num =
11059517SBill.Taylor@Sun.COM (uint64_t)1 << cfgprof->cp_log_num_qp;
11069517SBill.Taylor@Sun.COM hdl_info.swi_max = (uint64_t)1 << devlim->log_max_qp;
11079517SBill.Taylor@Sun.COM hdl_info.swi_constructor =
11089517SBill.Taylor@Sun.COM hermon_rsrc_qphdl_constructor;
11099517SBill.Taylor@Sun.COM hdl_info.swi_destructor = hermon_rsrc_qphdl_destructor;
1110*12965SWilliam.Taylor@Oracle.COM hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT;
11119517SBill.Taylor@Sun.COM hdl_info.swi_prealloc_sz = sizeof (hermon_qphdl_t);
11129517SBill.Taylor@Sun.COM ncleanup = HERMON_RSRC_CLEANUP_LEVEL27;
11139517SBill.Taylor@Sun.COM break;
11149517SBill.Taylor@Sun.COM
11159517SBill.Taylor@Sun.COM case HERMON_REFCNT:
11169517SBill.Taylor@Sun.COM rsrc_pool->rsrc_quantum = sizeof (hermon_sw_refcnt_t);
11179517SBill.Taylor@Sun.COM HERMON_RSRC_NAME(rsrc_name, HERMON_REFCNT_CACHE);
11189517SBill.Taylor@Sun.COM hdl_info.swi_num =
11199517SBill.Taylor@Sun.COM (uint64_t)1 << cfgprof->cp_log_num_dmpt;
11209517SBill.Taylor@Sun.COM hdl_info.swi_max = (uint64_t)1 << devlim->log_max_dmpt;
11219517SBill.Taylor@Sun.COM hdl_info.swi_constructor =
11229517SBill.Taylor@Sun.COM hermon_rsrc_refcnt_constructor;
11239517SBill.Taylor@Sun.COM hdl_info.swi_destructor = hermon_rsrc_refcnt_destructor;
11249517SBill.Taylor@Sun.COM hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT;
11259517SBill.Taylor@Sun.COM ncleanup = HERMON_RSRC_CLEANUP_LEVEL28;
11269517SBill.Taylor@Sun.COM break;
11279517SBill.Taylor@Sun.COM
11289517SBill.Taylor@Sun.COM default:
11299517SBill.Taylor@Sun.COM continue;
11309517SBill.Taylor@Sun.COM }
11319517SBill.Taylor@Sun.COM
11329517SBill.Taylor@Sun.COM /* Set the common values and call the init routine */
11339517SBill.Taylor@Sun.COM rsrc_pool->rsrc_loc = HERMON_IN_SYSMEM;
11349517SBill.Taylor@Sun.COM rsrc_pool->rsrc_state = state;
11359517SBill.Taylor@Sun.COM hdl_info.swi_rsrcpool = rsrc_pool;
11369517SBill.Taylor@Sun.COM hdl_info.swi_rsrcname = rsrc_name;
11379517SBill.Taylor@Sun.COM status = hermon_rsrc_sw_handles_init(state, &hdl_info);
11389517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
11399517SBill.Taylor@Sun.COM hermon_rsrc_fini(state, cleanup);
11409517SBill.Taylor@Sun.COM status = DDI_FAILURE;
11419517SBill.Taylor@Sun.COM goto rsrcinitp2_fail;
11429517SBill.Taylor@Sun.COM }
11439517SBill.Taylor@Sun.COM cleanup = ncleanup;
11449517SBill.Taylor@Sun.COM }
11459517SBill.Taylor@Sun.COM
11469517SBill.Taylor@Sun.COM /*
11479517SBill.Taylor@Sun.COM * Initialize a resource pool for the MCG handles. Notice that for
11489517SBill.Taylor@Sun.COM * these MCG handles, we are allocating a table of structures (used to
11499517SBill.Taylor@Sun.COM * keep track of the MCG entries that are being written to hardware
11509517SBill.Taylor@Sun.COM * and to speed up multicast attach/detach operations).
11519517SBill.Taylor@Sun.COM */
11529517SBill.Taylor@Sun.COM hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_mcg);
11539517SBill.Taylor@Sun.COM hdl_info.swi_max = ((uint64_t)1 << devlim->log_max_mcg);
11549517SBill.Taylor@Sun.COM hdl_info.swi_flags = HERMON_SWHDL_TABLE_INIT;
11559517SBill.Taylor@Sun.COM hdl_info.swi_prealloc_sz = sizeof (struct hermon_sw_mcg_list_s);
11569517SBill.Taylor@Sun.COM status = hermon_rsrc_sw_handles_init(state, &hdl_info);
11579517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
11589517SBill.Taylor@Sun.COM hermon_rsrc_fini(state, cleanup);
11599517SBill.Taylor@Sun.COM status = DDI_FAILURE;
11609517SBill.Taylor@Sun.COM goto rsrcinitp2_fail;
11619517SBill.Taylor@Sun.COM }
11629517SBill.Taylor@Sun.COM state->hs_mcghdl = hdl_info.swi_table_ptr;
11639517SBill.Taylor@Sun.COM cleanup = HERMON_RSRC_CLEANUP_LEVEL29;
11649517SBill.Taylor@Sun.COM
11659517SBill.Taylor@Sun.COM /*
11669517SBill.Taylor@Sun.COM * Last, initialize the resource pool for the UAR pages, which contain
11679517SBill.Taylor@Sun.COM * the hardware's doorbell registers. Each process supported in User
11689517SBill.Taylor@Sun.COM * Mode is assigned a UAR page. Also coming from this pool are the
11699517SBill.Taylor@Sun.COM * kernel-assigned UAR page, and any hardware-reserved pages. Note
11709517SBill.Taylor@Sun.COM * that the number of UAR pages is configurable, the value must be less
11719517SBill.Taylor@Sun.COM * than the maximum value (obtained from the QUERY_DEV_LIM command) or
11729517SBill.Taylor@Sun.COM * the initialization will fail. Note also that we assign the base
11739517SBill.Taylor@Sun.COM * address of the UAR BAR to the rsrc_start parameter.
11749517SBill.Taylor@Sun.COM */
11759517SBill.Taylor@Sun.COM num = ((uint64_t)1 << cfgprof->cp_log_num_uar);
11769517SBill.Taylor@Sun.COM max = num;
11779517SBill.Taylor@Sun.COM num_prealloc = max(devlim->num_rsvd_uar, 128);
11789517SBill.Taylor@Sun.COM rsrc_pool = &state->hs_rsrc_hdl[HERMON_UARPG];
11799517SBill.Taylor@Sun.COM rsrc_pool->rsrc_loc = HERMON_IN_UAR;
11809517SBill.Taylor@Sun.COM rsrc_pool->rsrc_pool_size = (num << PAGESHIFT);
11819517SBill.Taylor@Sun.COM rsrc_pool->rsrc_shift = PAGESHIFT;
11829517SBill.Taylor@Sun.COM rsrc_pool->rsrc_quantum = (uint_t)PAGESIZE;
11839517SBill.Taylor@Sun.COM rsrc_pool->rsrc_align = PAGESIZE;
11849517SBill.Taylor@Sun.COM rsrc_pool->rsrc_state = state;
11859517SBill.Taylor@Sun.COM rsrc_pool->rsrc_start = (void *)state->hs_reg_uar_baseaddr;
11869517SBill.Taylor@Sun.COM HERMON_RSRC_NAME(rsrc_name, HERMON_UAR_PAGE_VMEM_ATTCH);
11879517SBill.Taylor@Sun.COM entry_info.hwi_num = num;
11889517SBill.Taylor@Sun.COM entry_info.hwi_max = max;
11899517SBill.Taylor@Sun.COM entry_info.hwi_prealloc = num_prealloc;
11909517SBill.Taylor@Sun.COM entry_info.hwi_rsrcpool = rsrc_pool;
11919517SBill.Taylor@Sun.COM entry_info.hwi_rsrcname = rsrc_name;
11929517SBill.Taylor@Sun.COM status = hermon_rsrc_hw_entries_init(state, &entry_info);
11939517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
11949517SBill.Taylor@Sun.COM hermon_rsrc_fini(state, cleanup);
11959517SBill.Taylor@Sun.COM status = DDI_FAILURE;
11969517SBill.Taylor@Sun.COM goto rsrcinitp2_fail;
11979517SBill.Taylor@Sun.COM }
11989517SBill.Taylor@Sun.COM
11999517SBill.Taylor@Sun.COM cleanup = HERMON_RSRC_CLEANUP_ALL;
12009517SBill.Taylor@Sun.COM
12019517SBill.Taylor@Sun.COM kmem_free(rsrc_name, HERMON_RSRC_NAME_MAXLEN);
12029517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
12039517SBill.Taylor@Sun.COM
12049517SBill.Taylor@Sun.COM rsrcinitp2_fail:
12059517SBill.Taylor@Sun.COM kmem_free(rsrc_name, HERMON_RSRC_NAME_MAXLEN);
12069517SBill.Taylor@Sun.COM return (status);
12079517SBill.Taylor@Sun.COM }
12089517SBill.Taylor@Sun.COM
12099517SBill.Taylor@Sun.COM
12109517SBill.Taylor@Sun.COM /*
12119517SBill.Taylor@Sun.COM * hermon_rsrc_fini()
12129517SBill.Taylor@Sun.COM * Context: Only called from attach() and/or detach() path contexts
12139517SBill.Taylor@Sun.COM */
12149517SBill.Taylor@Sun.COM void
hermon_rsrc_fini(hermon_state_t * state,hermon_rsrc_cleanup_level_t clean)12159517SBill.Taylor@Sun.COM hermon_rsrc_fini(hermon_state_t *state, hermon_rsrc_cleanup_level_t clean)
12169517SBill.Taylor@Sun.COM {
12179517SBill.Taylor@Sun.COM hermon_rsrc_sw_hdl_info_t hdl_info;
12189517SBill.Taylor@Sun.COM hermon_rsrc_hw_entry_info_t entry_info;
12199517SBill.Taylor@Sun.COM hermon_rsrc_mbox_info_t mbox_info;
12209517SBill.Taylor@Sun.COM hermon_cfg_profile_t *cfgprof;
12219517SBill.Taylor@Sun.COM
12229517SBill.Taylor@Sun.COM ASSERT(state != NULL);
12239517SBill.Taylor@Sun.COM
12249517SBill.Taylor@Sun.COM cfgprof = state->hs_cfg_profile;
12259517SBill.Taylor@Sun.COM
12269517SBill.Taylor@Sun.COM /*
12279517SBill.Taylor@Sun.COM * If init code above is shortened up (see comments), then we
12289517SBill.Taylor@Sun.COM * need to establish how to safely and simply clean up from any
12299517SBill.Taylor@Sun.COM * given failure point. Flags, maybe...
12309517SBill.Taylor@Sun.COM */
12319517SBill.Taylor@Sun.COM
12329517SBill.Taylor@Sun.COM switch (clean) {
12339517SBill.Taylor@Sun.COM /*
12349517SBill.Taylor@Sun.COM * If we add more resources that need to be cleaned up here, we should
12359517SBill.Taylor@Sun.COM * ensure that HERMON_RSRC_CLEANUP_ALL is still the first entry (i.e.
12369517SBill.Taylor@Sun.COM * corresponds to the last resource allocated).
12379517SBill.Taylor@Sun.COM */
12389517SBill.Taylor@Sun.COM
12399517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_ALL:
12409517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL31:
12419517SBill.Taylor@Sun.COM /* Cleanup the UAR page resource pool, first the dbr pages */
12429517SBill.Taylor@Sun.COM if (state->hs_kern_dbr) {
12439517SBill.Taylor@Sun.COM hermon_dbr_kern_free(state);
12449517SBill.Taylor@Sun.COM state->hs_kern_dbr = NULL;
12459517SBill.Taylor@Sun.COM }
12469517SBill.Taylor@Sun.COM
12479517SBill.Taylor@Sun.COM /* NS then, the pool itself */
12489517SBill.Taylor@Sun.COM entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_UARPG];
12499517SBill.Taylor@Sun.COM hermon_rsrc_hw_entries_fini(state, &entry_info);
12509517SBill.Taylor@Sun.COM
12519517SBill.Taylor@Sun.COM /* FALLTHROUGH */
12529517SBill.Taylor@Sun.COM
12539517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL30:
12549517SBill.Taylor@Sun.COM /* Cleanup the central MCG handle pointers list */
12559517SBill.Taylor@Sun.COM hdl_info.swi_rsrcpool = NULL;
12569517SBill.Taylor@Sun.COM hdl_info.swi_table_ptr = state->hs_mcghdl;
12579517SBill.Taylor@Sun.COM hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_mcg);
12589517SBill.Taylor@Sun.COM hdl_info.swi_prealloc_sz = sizeof (struct hermon_sw_mcg_list_s);
12599517SBill.Taylor@Sun.COM hermon_rsrc_sw_handles_fini(state, &hdl_info);
12609517SBill.Taylor@Sun.COM /* FALLTHROUGH */
12619517SBill.Taylor@Sun.COM
12629517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL29:
12639517SBill.Taylor@Sun.COM /* Cleanup the reference count resource pool */
12649517SBill.Taylor@Sun.COM hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_REFCNT];
12659517SBill.Taylor@Sun.COM hdl_info.swi_table_ptr = NULL;
12669517SBill.Taylor@Sun.COM hermon_rsrc_sw_handles_fini(state, &hdl_info);
12679517SBill.Taylor@Sun.COM /* FALLTHROUGH */
12689517SBill.Taylor@Sun.COM
12699517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL28:
12709517SBill.Taylor@Sun.COM /* Cleanup the QP handle resource pool */
12719517SBill.Taylor@Sun.COM hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_QPHDL];
1272*12965SWilliam.Taylor@Oracle.COM hdl_info.swi_table_ptr = NULL;
12739517SBill.Taylor@Sun.COM hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_qp);
12749517SBill.Taylor@Sun.COM hdl_info.swi_prealloc_sz = sizeof (hermon_qphdl_t);
12759517SBill.Taylor@Sun.COM hermon_rsrc_sw_handles_fini(state, &hdl_info);
12769517SBill.Taylor@Sun.COM /* FALLTHROUGH */
12779517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL27:
12789517SBill.Taylor@Sun.COM /* Cleanup the address handle resrouce pool */
12799517SBill.Taylor@Sun.COM hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_AHHDL];
12809517SBill.Taylor@Sun.COM hdl_info.swi_table_ptr = NULL;
12819517SBill.Taylor@Sun.COM hermon_rsrc_sw_handles_fini(state, &hdl_info);
12829517SBill.Taylor@Sun.COM /* FALLTHROUGH */
12839517SBill.Taylor@Sun.COM
12849517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL26:
12859517SBill.Taylor@Sun.COM /* Cleanup the SRQ handle resource pool. */
12869517SBill.Taylor@Sun.COM hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_SRQHDL];
1287*12965SWilliam.Taylor@Oracle.COM hdl_info.swi_table_ptr = NULL;
12889517SBill.Taylor@Sun.COM hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_srq);
12899517SBill.Taylor@Sun.COM hdl_info.swi_prealloc_sz = sizeof (hermon_srqhdl_t);
12909517SBill.Taylor@Sun.COM hermon_rsrc_sw_handles_fini(state, &hdl_info);
12919517SBill.Taylor@Sun.COM /* FALLTHROUGH */
12929517SBill.Taylor@Sun.COM
12939517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL25:
12949517SBill.Taylor@Sun.COM /* Cleanup the CQ handle resource pool */
12959517SBill.Taylor@Sun.COM hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_CQHDL];
1296*12965SWilliam.Taylor@Oracle.COM hdl_info.swi_table_ptr = NULL;
12979517SBill.Taylor@Sun.COM hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_cq);
12989517SBill.Taylor@Sun.COM hdl_info.swi_prealloc_sz = sizeof (hermon_cqhdl_t);
12999517SBill.Taylor@Sun.COM hermon_rsrc_sw_handles_fini(state, &hdl_info);
13009517SBill.Taylor@Sun.COM /* FALLTHROUGH */
13019517SBill.Taylor@Sun.COM
13029517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL24:
13039517SBill.Taylor@Sun.COM /* Cleanup the EQ handle resource pool */
13049517SBill.Taylor@Sun.COM hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_EQHDL];
13059517SBill.Taylor@Sun.COM hdl_info.swi_table_ptr = NULL;
13069517SBill.Taylor@Sun.COM hermon_rsrc_sw_handles_fini(state, &hdl_info);
13079517SBill.Taylor@Sun.COM /* FALLTHROUGH */
13089517SBill.Taylor@Sun.COM
13099517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL23:
13109517SBill.Taylor@Sun.COM /* Cleanup the MR handle resource pool */
13119517SBill.Taylor@Sun.COM hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_MRHDL];
13129517SBill.Taylor@Sun.COM hdl_info.swi_table_ptr = NULL;
13139517SBill.Taylor@Sun.COM hermon_rsrc_sw_handles_fini(state, &hdl_info);
13149517SBill.Taylor@Sun.COM /* FALLTHROUGH */
13159517SBill.Taylor@Sun.COM
13169517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL22:
13179517SBill.Taylor@Sun.COM /* Cleanup the PD handle resource pool */
13189517SBill.Taylor@Sun.COM hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_PDHDL];
13199517SBill.Taylor@Sun.COM hdl_info.swi_table_ptr = NULL;
13209517SBill.Taylor@Sun.COM hermon_rsrc_pd_handles_fini(state, &hdl_info);
13219517SBill.Taylor@Sun.COM /* FALLTHROUGH */
13229517SBill.Taylor@Sun.COM
13239517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL21:
13249517SBill.Taylor@Sun.COM /* Currently unused - FALLTHROUGH */
13259517SBill.Taylor@Sun.COM
13269517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL20:
13279517SBill.Taylor@Sun.COM /* Cleanup the outstanding command list */
13289517SBill.Taylor@Sun.COM hermon_outstanding_cmdlist_fini(state);
13299517SBill.Taylor@Sun.COM /* FALLTHROUGH */
13309517SBill.Taylor@Sun.COM
13319517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL19:
13329517SBill.Taylor@Sun.COM /* Cleanup the EQC table resource pool */
13339517SBill.Taylor@Sun.COM entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_EQC];
13349517SBill.Taylor@Sun.COM hermon_rsrc_hw_entries_fini(state, &entry_info);
13359517SBill.Taylor@Sun.COM /* FALLTHROUGH */
13369517SBill.Taylor@Sun.COM
13379517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL18:
13389517SBill.Taylor@Sun.COM /* Cleanup the MCG table resource pool */
13399517SBill.Taylor@Sun.COM entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_MCG];
13409517SBill.Taylor@Sun.COM hermon_rsrc_hw_entries_fini(state, &entry_info);
13419517SBill.Taylor@Sun.COM /* FALLTHROUGH */
13429517SBill.Taylor@Sun.COM
13439517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL17:
13449517SBill.Taylor@Sun.COM /* Currently Unused - fallthrough */
13459517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL16:
13469517SBill.Taylor@Sun.COM /* Cleanup the SRQC table resource pool */
13479517SBill.Taylor@Sun.COM entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_SRQC];
13489517SBill.Taylor@Sun.COM hermon_rsrc_hw_entries_fini(state, &entry_info);
13499517SBill.Taylor@Sun.COM /* FALLTHROUGH */
13509517SBill.Taylor@Sun.COM
13519517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL15:
13529517SBill.Taylor@Sun.COM /* Cleanup the AUXC table resource pool */
13539517SBill.Taylor@Sun.COM entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_AUXC];
13549517SBill.Taylor@Sun.COM hermon_rsrc_hw_entries_fini(state, &entry_info);
13559517SBill.Taylor@Sun.COM /* FALLTHROUGH */
13569517SBill.Taylor@Sun.COM
13579517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL14:
13589517SBill.Taylor@Sun.COM /* Cleanup the ALTCF table resource pool */
13599517SBill.Taylor@Sun.COM entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_ALTC];
13609517SBill.Taylor@Sun.COM hermon_rsrc_hw_entries_fini(state, &entry_info);
13619517SBill.Taylor@Sun.COM /* FALLTHROUGH */
13629517SBill.Taylor@Sun.COM
13639517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL13:
13649517SBill.Taylor@Sun.COM /* Cleanup the CQC table resource pool */
13659517SBill.Taylor@Sun.COM entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_CQC];
13669517SBill.Taylor@Sun.COM hermon_rsrc_hw_entries_fini(state, &entry_info);
13679517SBill.Taylor@Sun.COM /* FALLTHROUGH */
13689517SBill.Taylor@Sun.COM
13699517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL12:
13709517SBill.Taylor@Sun.COM /* Cleanup the RDB table resource pool */
13719517SBill.Taylor@Sun.COM entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_RDB];
13729517SBill.Taylor@Sun.COM hermon_rsrc_hw_entries_fini(state, &entry_info);
13739517SBill.Taylor@Sun.COM /* FALLTHROUGH */
13749517SBill.Taylor@Sun.COM
13759517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL11:
13769517SBill.Taylor@Sun.COM /* Cleanup the QPC table resource pool */
13779517SBill.Taylor@Sun.COM entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_QPC];
13789517SBill.Taylor@Sun.COM hermon_rsrc_hw_entries_fini(state, &entry_info);
13799517SBill.Taylor@Sun.COM /* FALLTHROUGH */
13809517SBill.Taylor@Sun.COM
13819517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL10EQ:
13829517SBill.Taylor@Sun.COM /* Cleanup the cMPTs for the EQs, CQs, SRQs, and QPs */
13839517SBill.Taylor@Sun.COM entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_CMPT_EQC];
13849517SBill.Taylor@Sun.COM hermon_rsrc_hw_entries_fini(state, &entry_info);
13859517SBill.Taylor@Sun.COM /* FALLTHROUGH */
13869517SBill.Taylor@Sun.COM
13879517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL10CQ:
13889517SBill.Taylor@Sun.COM /* Cleanup the cMPTs for the EQs, CQs, SRQs, and QPs */
13899517SBill.Taylor@Sun.COM entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_CMPT_CQC];
13909517SBill.Taylor@Sun.COM hermon_rsrc_hw_entries_fini(state, &entry_info);
13919517SBill.Taylor@Sun.COM /* FALLTHROUGH */
13929517SBill.Taylor@Sun.COM
13939517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL10SRQ:
13949517SBill.Taylor@Sun.COM /* Cleanup the cMPTs for the EQs, CQs, SRQs, and QPs */
13959517SBill.Taylor@Sun.COM entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_CMPT_SRQC];
13969517SBill.Taylor@Sun.COM hermon_rsrc_hw_entries_fini(state, &entry_info);
13979517SBill.Taylor@Sun.COM /* FALLTHROUGH */
13989517SBill.Taylor@Sun.COM
13999517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL10QP:
14009517SBill.Taylor@Sun.COM /* Cleanup the cMPTs for the EQs, CQs, SRQs, and QPs */
14019517SBill.Taylor@Sun.COM entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_CMPT_QPC];
14029517SBill.Taylor@Sun.COM hermon_rsrc_hw_entries_fini(state, &entry_info);
14039517SBill.Taylor@Sun.COM /* FALLTHROUGH */
14049517SBill.Taylor@Sun.COM
14059517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL10:
14069517SBill.Taylor@Sun.COM /* Cleanup the dMPT table resource pool */
14079517SBill.Taylor@Sun.COM entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_DMPT];
14089517SBill.Taylor@Sun.COM hermon_rsrc_hw_entries_fini(state, &entry_info);
14099517SBill.Taylor@Sun.COM /* FALLTHROUGH */
14109517SBill.Taylor@Sun.COM
14119517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL9:
14129517SBill.Taylor@Sun.COM /* Cleanup the MTT table resource pool */
14139517SBill.Taylor@Sun.COM entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_MTT];
14149517SBill.Taylor@Sun.COM hermon_rsrc_hw_entries_fini(state, &entry_info);
14159517SBill.Taylor@Sun.COM break;
14169517SBill.Taylor@Sun.COM
14179517SBill.Taylor@Sun.COM /*
14189517SBill.Taylor@Sun.COM * The cleanup below comes from the "Phase 1" initialization step.
14199517SBill.Taylor@Sun.COM * (see hermon_rsrc_init_phase1() above)
14209517SBill.Taylor@Sun.COM */
14219517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_PHASE1_COMPLETE:
14229517SBill.Taylor@Sun.COM /* Cleanup the "In" mailbox list */
14239517SBill.Taylor@Sun.COM hermon_intr_inmbox_list_fini(state);
14249517SBill.Taylor@Sun.COM /* FALLTHROUGH */
14259517SBill.Taylor@Sun.COM
14269517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL7:
14279517SBill.Taylor@Sun.COM /* Cleanup the interrupt "In" mailbox resource pool */
14289517SBill.Taylor@Sun.COM mbox_info.mbi_rsrcpool =
14299517SBill.Taylor@Sun.COM &state->hs_rsrc_hdl[HERMON_INTR_IN_MBOX];
14309517SBill.Taylor@Sun.COM hermon_rsrc_mbox_fini(state, &mbox_info);
14319517SBill.Taylor@Sun.COM /* FALLTHROUGH */
14329517SBill.Taylor@Sun.COM
14339517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL6:
14349517SBill.Taylor@Sun.COM /* Cleanup the "In" mailbox list */
14359517SBill.Taylor@Sun.COM hermon_inmbox_list_fini(state);
14369517SBill.Taylor@Sun.COM /* FALLTHROUGH */
14379517SBill.Taylor@Sun.COM
14389517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL5:
14399517SBill.Taylor@Sun.COM /* Cleanup the "In" mailbox resource pool */
14409517SBill.Taylor@Sun.COM mbox_info.mbi_rsrcpool = &state->hs_rsrc_hdl[HERMON_IN_MBOX];
14419517SBill.Taylor@Sun.COM hermon_rsrc_mbox_fini(state, &mbox_info);
14429517SBill.Taylor@Sun.COM /* FALLTHROUGH */
14439517SBill.Taylor@Sun.COM
14449517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL4:
14459517SBill.Taylor@Sun.COM /* Cleanup the interrupt "Out" mailbox list */
14469517SBill.Taylor@Sun.COM hermon_intr_outmbox_list_fini(state);
14479517SBill.Taylor@Sun.COM /* FALLTHROUGH */
14489517SBill.Taylor@Sun.COM
14499517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL3:
14509517SBill.Taylor@Sun.COM /* Cleanup the "Out" mailbox resource pool */
14519517SBill.Taylor@Sun.COM mbox_info.mbi_rsrcpool =
14529517SBill.Taylor@Sun.COM &state->hs_rsrc_hdl[HERMON_INTR_OUT_MBOX];
14539517SBill.Taylor@Sun.COM hermon_rsrc_mbox_fini(state, &mbox_info);
14549517SBill.Taylor@Sun.COM /* FALLTHROUGH */
14559517SBill.Taylor@Sun.COM
14569517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL2:
14579517SBill.Taylor@Sun.COM /* Cleanup the "Out" mailbox list */
14589517SBill.Taylor@Sun.COM hermon_outmbox_list_fini(state);
14599517SBill.Taylor@Sun.COM /* FALLTHROUGH */
14609517SBill.Taylor@Sun.COM
14619517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL1:
14629517SBill.Taylor@Sun.COM /* Cleanup the "Out" mailbox resource pool */
14639517SBill.Taylor@Sun.COM mbox_info.mbi_rsrcpool = &state->hs_rsrc_hdl[HERMON_OUT_MBOX];
14649517SBill.Taylor@Sun.COM hermon_rsrc_mbox_fini(state, &mbox_info);
14659517SBill.Taylor@Sun.COM /* FALLTHROUGH */
14669517SBill.Taylor@Sun.COM
14679517SBill.Taylor@Sun.COM case HERMON_RSRC_CLEANUP_LEVEL0:
14689517SBill.Taylor@Sun.COM /* Free the array of hermon_rsrc_pool_info_t's */
14699517SBill.Taylor@Sun.COM
14709517SBill.Taylor@Sun.COM kmem_free(state->hs_rsrc_hdl, HERMON_NUM_RESOURCES *
14719517SBill.Taylor@Sun.COM sizeof (hermon_rsrc_pool_info_t));
14729517SBill.Taylor@Sun.COM
14739517SBill.Taylor@Sun.COM kmem_cache_destroy(state->hs_rsrc_cache);
14749517SBill.Taylor@Sun.COM break;
14759517SBill.Taylor@Sun.COM
14769517SBill.Taylor@Sun.COM default:
14779517SBill.Taylor@Sun.COM HERMON_WARNING(state, "unexpected resource cleanup level");
14789517SBill.Taylor@Sun.COM break;
14799517SBill.Taylor@Sun.COM }
14809517SBill.Taylor@Sun.COM }
14819517SBill.Taylor@Sun.COM
14829517SBill.Taylor@Sun.COM
14839517SBill.Taylor@Sun.COM /*
14849517SBill.Taylor@Sun.COM * hermon_rsrc_mbox_init()
14859517SBill.Taylor@Sun.COM * Context: Only called from attach() path context
14869517SBill.Taylor@Sun.COM */
14879517SBill.Taylor@Sun.COM static int
hermon_rsrc_mbox_init(hermon_state_t * state,hermon_rsrc_mbox_info_t * info)14889517SBill.Taylor@Sun.COM hermon_rsrc_mbox_init(hermon_state_t *state, hermon_rsrc_mbox_info_t *info)
14899517SBill.Taylor@Sun.COM {
14909517SBill.Taylor@Sun.COM hermon_rsrc_pool_info_t *rsrc_pool;
14919517SBill.Taylor@Sun.COM hermon_rsrc_priv_mbox_t *priv;
14929517SBill.Taylor@Sun.COM
14939517SBill.Taylor@Sun.COM ASSERT(state != NULL);
14949517SBill.Taylor@Sun.COM ASSERT(info != NULL);
14959517SBill.Taylor@Sun.COM
14969517SBill.Taylor@Sun.COM rsrc_pool = info->mbi_rsrcpool;
14979517SBill.Taylor@Sun.COM ASSERT(rsrc_pool != NULL);
14989517SBill.Taylor@Sun.COM
14999517SBill.Taylor@Sun.COM /* Allocate and initialize mailbox private structure */
15009517SBill.Taylor@Sun.COM priv = kmem_zalloc(sizeof (hermon_rsrc_priv_mbox_t), KM_SLEEP);
15019517SBill.Taylor@Sun.COM priv->pmb_dip = state->hs_dip;
15029517SBill.Taylor@Sun.COM priv->pmb_devaccattr = state->hs_reg_accattr;
15039517SBill.Taylor@Sun.COM priv->pmb_xfer_mode = DDI_DMA_CONSISTENT;
15049517SBill.Taylor@Sun.COM
15059517SBill.Taylor@Sun.COM /*
15069517SBill.Taylor@Sun.COM * Initialize many of the default DMA attributes. Then set alignment
15079517SBill.Taylor@Sun.COM * and scatter-gather restrictions specific for mailbox memory.
15089517SBill.Taylor@Sun.COM */
15099517SBill.Taylor@Sun.COM hermon_dma_attr_init(state, &priv->pmb_dmaattr);
15109517SBill.Taylor@Sun.COM priv->pmb_dmaattr.dma_attr_align = HERMON_MBOX_ALIGN;
15119517SBill.Taylor@Sun.COM priv->pmb_dmaattr.dma_attr_sgllen = 1;
15129517SBill.Taylor@Sun.COM priv->pmb_dmaattr.dma_attr_flags = 0;
15139517SBill.Taylor@Sun.COM rsrc_pool->rsrc_private = priv;
15149517SBill.Taylor@Sun.COM
15159517SBill.Taylor@Sun.COM ASSERT(rsrc_pool->rsrc_loc == HERMON_IN_SYSMEM);
15169517SBill.Taylor@Sun.COM
15179517SBill.Taylor@Sun.COM rsrc_pool->rsrc_start = NULL;
15189517SBill.Taylor@Sun.COM rsrc_pool->rsrc_vmp = NULL;
15199517SBill.Taylor@Sun.COM
15209517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
15219517SBill.Taylor@Sun.COM }
15229517SBill.Taylor@Sun.COM
15239517SBill.Taylor@Sun.COM
15249517SBill.Taylor@Sun.COM /*
15259517SBill.Taylor@Sun.COM * hermon_rsrc_mbox_fini()
15269517SBill.Taylor@Sun.COM * Context: Only called from attach() and/or detach() path contexts
15279517SBill.Taylor@Sun.COM */
15289517SBill.Taylor@Sun.COM /* ARGSUSED */
15299517SBill.Taylor@Sun.COM static void
hermon_rsrc_mbox_fini(hermon_state_t * state,hermon_rsrc_mbox_info_t * info)15309517SBill.Taylor@Sun.COM hermon_rsrc_mbox_fini(hermon_state_t *state, hermon_rsrc_mbox_info_t *info)
15319517SBill.Taylor@Sun.COM {
15329517SBill.Taylor@Sun.COM hermon_rsrc_pool_info_t *rsrc_pool;
15339517SBill.Taylor@Sun.COM
15349517SBill.Taylor@Sun.COM ASSERT(state != NULL);
15359517SBill.Taylor@Sun.COM ASSERT(info != NULL);
15369517SBill.Taylor@Sun.COM
15379517SBill.Taylor@Sun.COM rsrc_pool = info->mbi_rsrcpool;
15389517SBill.Taylor@Sun.COM ASSERT(rsrc_pool != NULL);
15399517SBill.Taylor@Sun.COM
15409517SBill.Taylor@Sun.COM /* Free up the private struct */
15419517SBill.Taylor@Sun.COM kmem_free(rsrc_pool->rsrc_private, sizeof (hermon_rsrc_priv_mbox_t));
15429517SBill.Taylor@Sun.COM }
15439517SBill.Taylor@Sun.COM
15449517SBill.Taylor@Sun.COM
15459517SBill.Taylor@Sun.COM /*
15469517SBill.Taylor@Sun.COM * hermon_rsrc_hw_entries_init()
15479517SBill.Taylor@Sun.COM * Context: Only called from attach() path context
15489517SBill.Taylor@Sun.COM */
15499517SBill.Taylor@Sun.COM int
hermon_rsrc_hw_entries_init(hermon_state_t * state,hermon_rsrc_hw_entry_info_t * info)15509517SBill.Taylor@Sun.COM hermon_rsrc_hw_entries_init(hermon_state_t *state,
15519517SBill.Taylor@Sun.COM hermon_rsrc_hw_entry_info_t *info)
15529517SBill.Taylor@Sun.COM {
15539517SBill.Taylor@Sun.COM hermon_rsrc_pool_info_t *rsrc_pool;
15549517SBill.Taylor@Sun.COM hermon_rsrc_t *rsvd_rsrc = NULL;
15559517SBill.Taylor@Sun.COM vmem_t *vmp;
15569517SBill.Taylor@Sun.COM uint64_t num_hwentry, max_hwentry, num_prealloc;
15579517SBill.Taylor@Sun.COM int status;
15589517SBill.Taylor@Sun.COM
15599517SBill.Taylor@Sun.COM ASSERT(state != NULL);
15609517SBill.Taylor@Sun.COM ASSERT(info != NULL);
15619517SBill.Taylor@Sun.COM
15629517SBill.Taylor@Sun.COM rsrc_pool = info->hwi_rsrcpool;
15639517SBill.Taylor@Sun.COM ASSERT(rsrc_pool != NULL);
15649517SBill.Taylor@Sun.COM num_hwentry = info->hwi_num;
15659517SBill.Taylor@Sun.COM max_hwentry = info->hwi_max;
15669517SBill.Taylor@Sun.COM num_prealloc = info->hwi_prealloc;
15679517SBill.Taylor@Sun.COM
15689517SBill.Taylor@Sun.COM if (hermon_rsrc_verbose) {
15699517SBill.Taylor@Sun.COM IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entries_init: "
15709517SBill.Taylor@Sun.COM "rsrc_type (0x%x) num (%llx) max (0x%llx) prealloc "
15719517SBill.Taylor@Sun.COM "(0x%llx)", rsrc_pool->rsrc_type, (longlong_t)num_hwentry,
15729517SBill.Taylor@Sun.COM (longlong_t)max_hwentry, (longlong_t)num_prealloc);
15739517SBill.Taylor@Sun.COM }
15749517SBill.Taylor@Sun.COM
15759517SBill.Taylor@Sun.COM /* Make sure number of HW entries makes sense */
15769517SBill.Taylor@Sun.COM if (num_hwentry > max_hwentry) {
15779517SBill.Taylor@Sun.COM return (DDI_FAILURE);
15789517SBill.Taylor@Sun.COM }
15799517SBill.Taylor@Sun.COM
15809517SBill.Taylor@Sun.COM /* Set this pool's rsrc_start from the initial ICM allocation */
15819517SBill.Taylor@Sun.COM if (rsrc_pool->rsrc_start == 0) {
158211972SBill.Taylor@Sun.COM
158311972SBill.Taylor@Sun.COM /* use a ROUND value that works on both 32 and 64-bit kernels */
158411972SBill.Taylor@Sun.COM rsrc_pool->rsrc_start = (void *)(uintptr_t)0x10000000;
15859517SBill.Taylor@Sun.COM
15869517SBill.Taylor@Sun.COM if (hermon_rsrc_verbose) {
15879517SBill.Taylor@Sun.COM IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entries_init:"
15889517SBill.Taylor@Sun.COM " rsrc_type (0x%x) rsrc_start set (0x%lx)",
15899517SBill.Taylor@Sun.COM rsrc_pool->rsrc_type, rsrc_pool->rsrc_start);
15909517SBill.Taylor@Sun.COM }
15919517SBill.Taylor@Sun.COM }
15929517SBill.Taylor@Sun.COM
15939517SBill.Taylor@Sun.COM /*
15949517SBill.Taylor@Sun.COM * Create new vmem arena for the HW entries table if rsrc_quantum
15959517SBill.Taylor@Sun.COM * is non-zero. Otherwise if rsrc_quantum is zero, then these HW
15969517SBill.Taylor@Sun.COM * entries are not going to be dynamically allocatable (i.e. they
15979517SBill.Taylor@Sun.COM * won't be allocated/freed through hermon_rsrc_alloc/free). This
15989517SBill.Taylor@Sun.COM * latter option is used for both ALTC and CMPT resources which
15999517SBill.Taylor@Sun.COM * are managed by hardware.
16009517SBill.Taylor@Sun.COM */
16019517SBill.Taylor@Sun.COM if (rsrc_pool->rsrc_quantum != 0) {
16029517SBill.Taylor@Sun.COM vmp = vmem_create(info->hwi_rsrcname,
16039517SBill.Taylor@Sun.COM (void *)(uintptr_t)rsrc_pool->rsrc_start,
16049517SBill.Taylor@Sun.COM rsrc_pool->rsrc_pool_size, rsrc_pool->rsrc_quantum,
16059517SBill.Taylor@Sun.COM NULL, NULL, NULL, 0, VM_SLEEP);
16069517SBill.Taylor@Sun.COM if (vmp == NULL) {
16079517SBill.Taylor@Sun.COM /* failed to create vmem arena */
16089517SBill.Taylor@Sun.COM return (DDI_FAILURE);
16099517SBill.Taylor@Sun.COM }
16109517SBill.Taylor@Sun.COM rsrc_pool->rsrc_vmp = vmp;
16119517SBill.Taylor@Sun.COM if (hermon_rsrc_verbose) {
16129517SBill.Taylor@Sun.COM IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entries_init:"
16139517SBill.Taylor@Sun.COM " rsrc_type (0x%x) created vmem arena for rsrc",
16149517SBill.Taylor@Sun.COM rsrc_pool->rsrc_type);
16159517SBill.Taylor@Sun.COM }
16169517SBill.Taylor@Sun.COM } else {
16179517SBill.Taylor@Sun.COM /* we do not require a vmem arena */
16189517SBill.Taylor@Sun.COM rsrc_pool->rsrc_vmp = NULL;
16199517SBill.Taylor@Sun.COM if (hermon_rsrc_verbose) {
16209517SBill.Taylor@Sun.COM IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entries_init:"
16219517SBill.Taylor@Sun.COM " rsrc_type (0x%x) vmem arena not required",
16229517SBill.Taylor@Sun.COM rsrc_pool->rsrc_type);
16239517SBill.Taylor@Sun.COM }
16249517SBill.Taylor@Sun.COM }
16259517SBill.Taylor@Sun.COM
16269517SBill.Taylor@Sun.COM /* Allocate hardware reserved resources, if any */
16279517SBill.Taylor@Sun.COM if (num_prealloc != 0) {
16289517SBill.Taylor@Sun.COM status = hermon_rsrc_alloc(state, rsrc_pool->rsrc_type,
16299517SBill.Taylor@Sun.COM num_prealloc, HERMON_SLEEP, &rsvd_rsrc);
16309517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
16319517SBill.Taylor@Sun.COM /* unable to preallocate the reserved entries */
16329517SBill.Taylor@Sun.COM if (rsrc_pool->rsrc_vmp != NULL) {
16339517SBill.Taylor@Sun.COM vmem_destroy(rsrc_pool->rsrc_vmp);
16349517SBill.Taylor@Sun.COM }
16359517SBill.Taylor@Sun.COM return (DDI_FAILURE);
16369517SBill.Taylor@Sun.COM }
16379517SBill.Taylor@Sun.COM }
16389517SBill.Taylor@Sun.COM rsrc_pool->rsrc_private = rsvd_rsrc;
16399517SBill.Taylor@Sun.COM
16409517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
16419517SBill.Taylor@Sun.COM }
16429517SBill.Taylor@Sun.COM
16439517SBill.Taylor@Sun.COM
16449517SBill.Taylor@Sun.COM /*
16459517SBill.Taylor@Sun.COM * hermon_rsrc_hw_entries_fini()
16469517SBill.Taylor@Sun.COM * Context: Only called from attach() and/or detach() path contexts
16479517SBill.Taylor@Sun.COM */
16489517SBill.Taylor@Sun.COM void
hermon_rsrc_hw_entries_fini(hermon_state_t * state,hermon_rsrc_hw_entry_info_t * info)16499517SBill.Taylor@Sun.COM hermon_rsrc_hw_entries_fini(hermon_state_t *state,
16509517SBill.Taylor@Sun.COM hermon_rsrc_hw_entry_info_t *info)
16519517SBill.Taylor@Sun.COM {
16529517SBill.Taylor@Sun.COM hermon_rsrc_pool_info_t *rsrc_pool;
16539517SBill.Taylor@Sun.COM hermon_rsrc_t *rsvd_rsrc;
16549517SBill.Taylor@Sun.COM
16559517SBill.Taylor@Sun.COM ASSERT(state != NULL);
16569517SBill.Taylor@Sun.COM ASSERT(info != NULL);
16579517SBill.Taylor@Sun.COM
16589517SBill.Taylor@Sun.COM rsrc_pool = info->hwi_rsrcpool;
16599517SBill.Taylor@Sun.COM ASSERT(rsrc_pool != NULL);
16609517SBill.Taylor@Sun.COM
16619517SBill.Taylor@Sun.COM /* Free up any "reserved" (i.e. preallocated) HW entries */
16629517SBill.Taylor@Sun.COM rsvd_rsrc = (hermon_rsrc_t *)rsrc_pool->rsrc_private;
16639517SBill.Taylor@Sun.COM if (rsvd_rsrc != NULL) {
16649517SBill.Taylor@Sun.COM hermon_rsrc_free(state, &rsvd_rsrc);
16659517SBill.Taylor@Sun.COM }
16669517SBill.Taylor@Sun.COM
16679517SBill.Taylor@Sun.COM /*
16689517SBill.Taylor@Sun.COM * If we've actually setup a vmem arena for the HW entries, then
16699517SBill.Taylor@Sun.COM * destroy it now
16709517SBill.Taylor@Sun.COM */
16719517SBill.Taylor@Sun.COM if (rsrc_pool->rsrc_vmp != NULL) {
16729517SBill.Taylor@Sun.COM vmem_destroy(rsrc_pool->rsrc_vmp);
16739517SBill.Taylor@Sun.COM }
16749517SBill.Taylor@Sun.COM }
16759517SBill.Taylor@Sun.COM
16769517SBill.Taylor@Sun.COM
16779517SBill.Taylor@Sun.COM /*
16789517SBill.Taylor@Sun.COM * hermon_rsrc_sw_handles_init()
16799517SBill.Taylor@Sun.COM * Context: Only called from attach() path context
16809517SBill.Taylor@Sun.COM */
16819517SBill.Taylor@Sun.COM /* ARGSUSED */
16829517SBill.Taylor@Sun.COM static int
hermon_rsrc_sw_handles_init(hermon_state_t * state,hermon_rsrc_sw_hdl_info_t * info)16839517SBill.Taylor@Sun.COM hermon_rsrc_sw_handles_init(hermon_state_t *state,
16849517SBill.Taylor@Sun.COM hermon_rsrc_sw_hdl_info_t *info)
16859517SBill.Taylor@Sun.COM {
16869517SBill.Taylor@Sun.COM hermon_rsrc_pool_info_t *rsrc_pool;
16879517SBill.Taylor@Sun.COM uint64_t num_swhdl, max_swhdl, prealloc_sz;
16889517SBill.Taylor@Sun.COM
16899517SBill.Taylor@Sun.COM ASSERT(state != NULL);
16909517SBill.Taylor@Sun.COM ASSERT(info != NULL);
16919517SBill.Taylor@Sun.COM
16929517SBill.Taylor@Sun.COM rsrc_pool = info->swi_rsrcpool;
16939517SBill.Taylor@Sun.COM ASSERT(rsrc_pool != NULL);
16949517SBill.Taylor@Sun.COM num_swhdl = info->swi_num;
16959517SBill.Taylor@Sun.COM max_swhdl = info->swi_max;
16969517SBill.Taylor@Sun.COM prealloc_sz = info->swi_prealloc_sz;
16979517SBill.Taylor@Sun.COM
16989517SBill.Taylor@Sun.COM
16999517SBill.Taylor@Sun.COM /* Make sure number of SW handles makes sense */
17009517SBill.Taylor@Sun.COM if (num_swhdl > max_swhdl) {
17019517SBill.Taylor@Sun.COM return (DDI_FAILURE);
17029517SBill.Taylor@Sun.COM }
17039517SBill.Taylor@Sun.COM
17049517SBill.Taylor@Sun.COM /*
17059517SBill.Taylor@Sun.COM * Depending on the flags parameter, create a kmem_cache for some
17069517SBill.Taylor@Sun.COM * number of software handle structures. Note: kmem_cache_create()
17079517SBill.Taylor@Sun.COM * will SLEEP until successful.
17089517SBill.Taylor@Sun.COM */
17099517SBill.Taylor@Sun.COM if (info->swi_flags & HERMON_SWHDL_KMEMCACHE_INIT) {
17109517SBill.Taylor@Sun.COM rsrc_pool->rsrc_private = kmem_cache_create(
17119517SBill.Taylor@Sun.COM info->swi_rsrcname, rsrc_pool->rsrc_quantum, 0,
17129517SBill.Taylor@Sun.COM info->swi_constructor, info->swi_destructor, NULL,
17139517SBill.Taylor@Sun.COM rsrc_pool->rsrc_state, NULL, 0);
17149517SBill.Taylor@Sun.COM }
17159517SBill.Taylor@Sun.COM
17169517SBill.Taylor@Sun.COM
17179517SBill.Taylor@Sun.COM /* Allocate the central list of SW handle pointers */
17189517SBill.Taylor@Sun.COM if (info->swi_flags & HERMON_SWHDL_TABLE_INIT) {
17199517SBill.Taylor@Sun.COM info->swi_table_ptr = kmem_zalloc(num_swhdl * prealloc_sz,
17209517SBill.Taylor@Sun.COM KM_SLEEP);
17219517SBill.Taylor@Sun.COM }
17229517SBill.Taylor@Sun.COM
17239517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
17249517SBill.Taylor@Sun.COM }
17259517SBill.Taylor@Sun.COM
17269517SBill.Taylor@Sun.COM
17279517SBill.Taylor@Sun.COM /*
17289517SBill.Taylor@Sun.COM * hermon_rsrc_sw_handles_fini()
17299517SBill.Taylor@Sun.COM * Context: Only called from attach() and/or detach() path contexts
17309517SBill.Taylor@Sun.COM */
17319517SBill.Taylor@Sun.COM /* ARGSUSED */
17329517SBill.Taylor@Sun.COM static void
hermon_rsrc_sw_handles_fini(hermon_state_t * state,hermon_rsrc_sw_hdl_info_t * info)17339517SBill.Taylor@Sun.COM hermon_rsrc_sw_handles_fini(hermon_state_t *state,
17349517SBill.Taylor@Sun.COM hermon_rsrc_sw_hdl_info_t *info)
17359517SBill.Taylor@Sun.COM {
17369517SBill.Taylor@Sun.COM hermon_rsrc_pool_info_t *rsrc_pool;
17379517SBill.Taylor@Sun.COM uint64_t num_swhdl, prealloc_sz;
17389517SBill.Taylor@Sun.COM
17399517SBill.Taylor@Sun.COM ASSERT(state != NULL);
17409517SBill.Taylor@Sun.COM ASSERT(info != NULL);
17419517SBill.Taylor@Sun.COM
17429517SBill.Taylor@Sun.COM rsrc_pool = info->swi_rsrcpool;
17439517SBill.Taylor@Sun.COM num_swhdl = info->swi_num;
17449517SBill.Taylor@Sun.COM prealloc_sz = info->swi_prealloc_sz;
17459517SBill.Taylor@Sun.COM
17469517SBill.Taylor@Sun.COM /*
17479517SBill.Taylor@Sun.COM * If a "software handle" kmem_cache exists for this resource, then
17489517SBill.Taylor@Sun.COM * destroy it now
17499517SBill.Taylor@Sun.COM */
17509517SBill.Taylor@Sun.COM if (rsrc_pool != NULL) {
17519517SBill.Taylor@Sun.COM kmem_cache_destroy(rsrc_pool->rsrc_private);
17529517SBill.Taylor@Sun.COM }
17539517SBill.Taylor@Sun.COM
17549517SBill.Taylor@Sun.COM /* Free up this central list of SW handle pointers */
17559517SBill.Taylor@Sun.COM if (info->swi_table_ptr != NULL) {
17569517SBill.Taylor@Sun.COM kmem_free(info->swi_table_ptr, num_swhdl * prealloc_sz);
17579517SBill.Taylor@Sun.COM }
17589517SBill.Taylor@Sun.COM }
17599517SBill.Taylor@Sun.COM
17609517SBill.Taylor@Sun.COM
17619517SBill.Taylor@Sun.COM /*
17629517SBill.Taylor@Sun.COM * hermon_rsrc_pd_handles_init()
17639517SBill.Taylor@Sun.COM * Context: Only called from attach() path context
17649517SBill.Taylor@Sun.COM */
17659517SBill.Taylor@Sun.COM static int
hermon_rsrc_pd_handles_init(hermon_state_t * state,hermon_rsrc_sw_hdl_info_t * info)17669517SBill.Taylor@Sun.COM hermon_rsrc_pd_handles_init(hermon_state_t *state,
17679517SBill.Taylor@Sun.COM hermon_rsrc_sw_hdl_info_t *info)
17689517SBill.Taylor@Sun.COM {
17699517SBill.Taylor@Sun.COM hermon_rsrc_pool_info_t *rsrc_pool;
17709517SBill.Taylor@Sun.COM vmem_t *vmp;
17719517SBill.Taylor@Sun.COM char vmem_name[HERMON_RSRC_NAME_MAXLEN];
17729517SBill.Taylor@Sun.COM int status;
17739517SBill.Taylor@Sun.COM
17749517SBill.Taylor@Sun.COM ASSERT(state != NULL);
17759517SBill.Taylor@Sun.COM ASSERT(info != NULL);
17769517SBill.Taylor@Sun.COM
17779517SBill.Taylor@Sun.COM rsrc_pool = info->swi_rsrcpool;
17789517SBill.Taylor@Sun.COM ASSERT(rsrc_pool != NULL);
17799517SBill.Taylor@Sun.COM
17809517SBill.Taylor@Sun.COM /* Initialize the resource pool for software handle table */
17819517SBill.Taylor@Sun.COM status = hermon_rsrc_sw_handles_init(state, info);
17829517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
17839517SBill.Taylor@Sun.COM return (DDI_FAILURE);
17849517SBill.Taylor@Sun.COM }
17859517SBill.Taylor@Sun.COM
17869517SBill.Taylor@Sun.COM /* Build vmem arena name from Hermon instance */
17879517SBill.Taylor@Sun.COM HERMON_RSRC_NAME(vmem_name, HERMON_PDHDL_VMEM);
17889517SBill.Taylor@Sun.COM
17899517SBill.Taylor@Sun.COM /* Create new vmem arena for PD numbers */
17909517SBill.Taylor@Sun.COM vmp = vmem_create(vmem_name, (caddr_t)1, info->swi_num, 1, NULL,
17919517SBill.Taylor@Sun.COM NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER);
17929517SBill.Taylor@Sun.COM if (vmp == NULL) {
17939517SBill.Taylor@Sun.COM /* Unable to create vmem arena */
17949517SBill.Taylor@Sun.COM info->swi_table_ptr = NULL;
17959517SBill.Taylor@Sun.COM hermon_rsrc_sw_handles_fini(state, info);
17969517SBill.Taylor@Sun.COM return (DDI_FAILURE);
17979517SBill.Taylor@Sun.COM }
17989517SBill.Taylor@Sun.COM rsrc_pool->rsrc_vmp = vmp;
17999517SBill.Taylor@Sun.COM
18009517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
18019517SBill.Taylor@Sun.COM }
18029517SBill.Taylor@Sun.COM
18039517SBill.Taylor@Sun.COM
18049517SBill.Taylor@Sun.COM /*
18059517SBill.Taylor@Sun.COM * hermon_rsrc_pd_handles_fini()
18069517SBill.Taylor@Sun.COM * Context: Only called from attach() and/or detach() path contexts
18079517SBill.Taylor@Sun.COM */
18089517SBill.Taylor@Sun.COM static void
hermon_rsrc_pd_handles_fini(hermon_state_t * state,hermon_rsrc_sw_hdl_info_t * info)18099517SBill.Taylor@Sun.COM hermon_rsrc_pd_handles_fini(hermon_state_t *state,
18109517SBill.Taylor@Sun.COM hermon_rsrc_sw_hdl_info_t *info)
18119517SBill.Taylor@Sun.COM {
18129517SBill.Taylor@Sun.COM hermon_rsrc_pool_info_t *rsrc_pool;
18139517SBill.Taylor@Sun.COM
18149517SBill.Taylor@Sun.COM ASSERT(state != NULL);
18159517SBill.Taylor@Sun.COM ASSERT(info != NULL);
18169517SBill.Taylor@Sun.COM
18179517SBill.Taylor@Sun.COM rsrc_pool = info->swi_rsrcpool;
18189517SBill.Taylor@Sun.COM
18199517SBill.Taylor@Sun.COM /* Destroy the specially created UAR scratch table vmem arena */
18209517SBill.Taylor@Sun.COM vmem_destroy(rsrc_pool->rsrc_vmp);
18219517SBill.Taylor@Sun.COM
18229517SBill.Taylor@Sun.COM /* Destroy the "hermon_sw_pd_t" kmem_cache */
18239517SBill.Taylor@Sun.COM hermon_rsrc_sw_handles_fini(state, info);
18249517SBill.Taylor@Sun.COM }
18259517SBill.Taylor@Sun.COM
18269517SBill.Taylor@Sun.COM
18279517SBill.Taylor@Sun.COM /*
18289517SBill.Taylor@Sun.COM * hermon_rsrc_mbox_alloc()
18299517SBill.Taylor@Sun.COM * Context: Only called from attach() path context
18309517SBill.Taylor@Sun.COM */
18319517SBill.Taylor@Sun.COM static int
hermon_rsrc_mbox_alloc(hermon_rsrc_pool_info_t * pool_info,uint_t num,hermon_rsrc_t * hdl)18329517SBill.Taylor@Sun.COM hermon_rsrc_mbox_alloc(hermon_rsrc_pool_info_t *pool_info, uint_t num,
18339517SBill.Taylor@Sun.COM hermon_rsrc_t *hdl)
18349517SBill.Taylor@Sun.COM {
18359517SBill.Taylor@Sun.COM hermon_rsrc_priv_mbox_t *priv;
18369517SBill.Taylor@Sun.COM caddr_t kaddr;
18379517SBill.Taylor@Sun.COM size_t real_len, temp_len;
18389517SBill.Taylor@Sun.COM int status;
18399517SBill.Taylor@Sun.COM
18409517SBill.Taylor@Sun.COM ASSERT(pool_info != NULL);
18419517SBill.Taylor@Sun.COM ASSERT(hdl != NULL);
18429517SBill.Taylor@Sun.COM
18439517SBill.Taylor@Sun.COM /* Get the private pointer for the mailboxes */
18449517SBill.Taylor@Sun.COM priv = pool_info->rsrc_private;
18459517SBill.Taylor@Sun.COM ASSERT(priv != NULL);
18469517SBill.Taylor@Sun.COM
18479517SBill.Taylor@Sun.COM /* Allocate a DMA handle for the mailbox */
18489517SBill.Taylor@Sun.COM status = ddi_dma_alloc_handle(priv->pmb_dip, &priv->pmb_dmaattr,
18499517SBill.Taylor@Sun.COM DDI_DMA_SLEEP, NULL, &hdl->hr_dmahdl);
18509517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
18519517SBill.Taylor@Sun.COM return (DDI_FAILURE);
18529517SBill.Taylor@Sun.COM }
18539517SBill.Taylor@Sun.COM
18549517SBill.Taylor@Sun.COM /* Allocate memory for the mailbox */
1855*12965SWilliam.Taylor@Oracle.COM temp_len = (num << pool_info->rsrc_shift);
18569517SBill.Taylor@Sun.COM status = ddi_dma_mem_alloc(hdl->hr_dmahdl, temp_len,
18579517SBill.Taylor@Sun.COM &priv->pmb_devaccattr, priv->pmb_xfer_mode, DDI_DMA_SLEEP,
18589517SBill.Taylor@Sun.COM NULL, &kaddr, &real_len, &hdl->hr_acchdl);
18599517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
18609517SBill.Taylor@Sun.COM /* No more memory available for mailbox entries */
18619517SBill.Taylor@Sun.COM ddi_dma_free_handle(&hdl->hr_dmahdl);
18629517SBill.Taylor@Sun.COM return (DDI_FAILURE);
18639517SBill.Taylor@Sun.COM }
18649517SBill.Taylor@Sun.COM
18659517SBill.Taylor@Sun.COM hdl->hr_addr = (void *)kaddr;
18669517SBill.Taylor@Sun.COM hdl->hr_len = (uint32_t)real_len;
18679517SBill.Taylor@Sun.COM
18689517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
18699517SBill.Taylor@Sun.COM }
18709517SBill.Taylor@Sun.COM
18719517SBill.Taylor@Sun.COM
18729517SBill.Taylor@Sun.COM /*
18739517SBill.Taylor@Sun.COM * hermon_rsrc_mbox_free()
18749517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
18759517SBill.Taylor@Sun.COM */
18769517SBill.Taylor@Sun.COM static void
hermon_rsrc_mbox_free(hermon_rsrc_t * hdl)1877*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_mbox_free(hermon_rsrc_t *hdl)
18789517SBill.Taylor@Sun.COM {
18799517SBill.Taylor@Sun.COM ASSERT(hdl != NULL);
18809517SBill.Taylor@Sun.COM
18819517SBill.Taylor@Sun.COM /* Use ddi_dma_mem_free() to free up sys memory for mailbox */
18829517SBill.Taylor@Sun.COM ddi_dma_mem_free(&hdl->hr_acchdl);
18839517SBill.Taylor@Sun.COM
18849517SBill.Taylor@Sun.COM /* Free the DMA handle for the mailbox */
18859517SBill.Taylor@Sun.COM ddi_dma_free_handle(&hdl->hr_dmahdl);
18869517SBill.Taylor@Sun.COM }
18879517SBill.Taylor@Sun.COM
18889517SBill.Taylor@Sun.COM
18899517SBill.Taylor@Sun.COM /*
18909517SBill.Taylor@Sun.COM * hermon_rsrc_hw_entry_alloc()
18919517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
18929517SBill.Taylor@Sun.COM */
18939517SBill.Taylor@Sun.COM 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)18949517SBill.Taylor@Sun.COM hermon_rsrc_hw_entry_alloc(hermon_rsrc_pool_info_t *pool_info, uint_t num,
1895*12965SWilliam.Taylor@Oracle.COM uint_t num_align, uint_t sleepflag, hermon_rsrc_t *hdl)
18969517SBill.Taylor@Sun.COM {
18979517SBill.Taylor@Sun.COM void *addr;
18989517SBill.Taylor@Sun.COM uint64_t offset;
18999517SBill.Taylor@Sun.COM uint32_t align;
19009517SBill.Taylor@Sun.COM int status;
19019517SBill.Taylor@Sun.COM int flag;
19029517SBill.Taylor@Sun.COM
19039517SBill.Taylor@Sun.COM ASSERT(pool_info != NULL);
19049517SBill.Taylor@Sun.COM ASSERT(hdl != NULL);
19059517SBill.Taylor@Sun.COM
19069517SBill.Taylor@Sun.COM /*
1907*12965SWilliam.Taylor@Oracle.COM * Use vmem_xalloc() to get a properly aligned pointer (based on
1908*12965SWilliam.Taylor@Oracle.COM * the number requested) to the HW entry(ies). This handles the
1909*12965SWilliam.Taylor@Oracle.COM * cases (for special QPCs and for RDB entries) where we need more
1910*12965SWilliam.Taylor@Oracle.COM * than one and need to ensure that they are properly aligned.
19119517SBill.Taylor@Sun.COM */
1912*12965SWilliam.Taylor@Oracle.COM flag = (sleepflag == HERMON_SLEEP) ? VM_SLEEP : VM_NOSLEEP;
1913*12965SWilliam.Taylor@Oracle.COM hdl->hr_len = (num << pool_info->rsrc_shift);
1914*12965SWilliam.Taylor@Oracle.COM align = (num_align << pool_info->rsrc_shift);
1915*12965SWilliam.Taylor@Oracle.COM
1916*12965SWilliam.Taylor@Oracle.COM addr = vmem_xalloc(pool_info->rsrc_vmp, hdl->hr_len,
1917*12965SWilliam.Taylor@Oracle.COM align, 0, 0, NULL, NULL, flag | VM_FIRSTFIT);
1918*12965SWilliam.Taylor@Oracle.COM
1919*12965SWilliam.Taylor@Oracle.COM if (addr == NULL) {
1920*12965SWilliam.Taylor@Oracle.COM /* No more HW entries available */
1921*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
1922*12965SWilliam.Taylor@Oracle.COM }
1923*12965SWilliam.Taylor@Oracle.COM
1924*12965SWilliam.Taylor@Oracle.COM hdl->hr_acchdl = NULL; /* only used for mbox resources */
1925*12965SWilliam.Taylor@Oracle.COM
1926*12965SWilliam.Taylor@Oracle.COM /* Calculate vaddr and HW table index */
1927*12965SWilliam.Taylor@Oracle.COM offset = (uintptr_t)addr - (uintptr_t)pool_info->rsrc_start;
1928*12965SWilliam.Taylor@Oracle.COM hdl->hr_addr = addr; /* only used for mbox and uarpg resources */
1929*12965SWilliam.Taylor@Oracle.COM hdl->hr_indx = offset >> pool_info->rsrc_shift;
1930*12965SWilliam.Taylor@Oracle.COM
1931*12965SWilliam.Taylor@Oracle.COM if (pool_info->rsrc_loc == HERMON_IN_ICM) {
1932*12965SWilliam.Taylor@Oracle.COM int num_to_hdl;
1933*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_type_t rsrc_type = pool_info->rsrc_type;
1934*12965SWilliam.Taylor@Oracle.COM
1935*12965SWilliam.Taylor@Oracle.COM num_to_hdl = (rsrc_type == HERMON_QPC ||
1936*12965SWilliam.Taylor@Oracle.COM rsrc_type == HERMON_CQC || rsrc_type == HERMON_SRQC);
1937*12965SWilliam.Taylor@Oracle.COM
1938*12965SWilliam.Taylor@Oracle.COM /* confirm ICM is mapped, and allocate if necessary */
1939*12965SWilliam.Taylor@Oracle.COM status = hermon_rsrc_hw_entry_icm_confirm(pool_info, num, hdl,
1940*12965SWilliam.Taylor@Oracle.COM num_to_hdl);
1941*12965SWilliam.Taylor@Oracle.COM if (status != DDI_SUCCESS) {
1942*12965SWilliam.Taylor@Oracle.COM return (DDI_FAILURE);
1943*12965SWilliam.Taylor@Oracle.COM }
1944*12965SWilliam.Taylor@Oracle.COM hdl->hr_addr = NULL; /* not used for ICM resources */
1945*12965SWilliam.Taylor@Oracle.COM }
1946*12965SWilliam.Taylor@Oracle.COM
1947*12965SWilliam.Taylor@Oracle.COM return (DDI_SUCCESS);
1948*12965SWilliam.Taylor@Oracle.COM }
1949*12965SWilliam.Taylor@Oracle.COM
1950*12965SWilliam.Taylor@Oracle.COM
1951*12965SWilliam.Taylor@Oracle.COM /*
1952*12965SWilliam.Taylor@Oracle.COM * hermon_rsrc_hw_entry_reserve()
1953*12965SWilliam.Taylor@Oracle.COM * Context: Can be called from interrupt or base context.
1954*12965SWilliam.Taylor@Oracle.COM */
1955*12965SWilliam.Taylor@Oracle.COM 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)1956*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_hw_entry_reserve(hermon_rsrc_pool_info_t *pool_info, uint_t num,
1957*12965SWilliam.Taylor@Oracle.COM uint_t num_align, uint_t sleepflag, hermon_rsrc_t *hdl)
1958*12965SWilliam.Taylor@Oracle.COM {
1959*12965SWilliam.Taylor@Oracle.COM void *addr;
1960*12965SWilliam.Taylor@Oracle.COM uint64_t offset;
1961*12965SWilliam.Taylor@Oracle.COM uint32_t align;
1962*12965SWilliam.Taylor@Oracle.COM int flag;
1963*12965SWilliam.Taylor@Oracle.COM
1964*12965SWilliam.Taylor@Oracle.COM ASSERT(pool_info != NULL);
1965*12965SWilliam.Taylor@Oracle.COM ASSERT(hdl != NULL);
1966*12965SWilliam.Taylor@Oracle.COM ASSERT(pool_info->rsrc_loc == HERMON_IN_ICM);
19679517SBill.Taylor@Sun.COM
19689517SBill.Taylor@Sun.COM /*
19699517SBill.Taylor@Sun.COM * Use vmem_xalloc() to get a properly aligned pointer (based on
19709517SBill.Taylor@Sun.COM * the number requested) to the HW entry(ies). This handles the
19719517SBill.Taylor@Sun.COM * cases (for special QPCs and for RDB entries) where we need more
19729517SBill.Taylor@Sun.COM * than one and need to ensure that they are properly aligned.
19739517SBill.Taylor@Sun.COM */
19749517SBill.Taylor@Sun.COM flag = (sleepflag == HERMON_SLEEP) ? VM_SLEEP : VM_NOSLEEP;
1975*12965SWilliam.Taylor@Oracle.COM hdl->hr_len = (num << pool_info->rsrc_shift);
1976*12965SWilliam.Taylor@Oracle.COM align = (num_align << pool_info->rsrc_shift);
19779517SBill.Taylor@Sun.COM
19789517SBill.Taylor@Sun.COM addr = vmem_xalloc(pool_info->rsrc_vmp, hdl->hr_len,
19799517SBill.Taylor@Sun.COM align, 0, 0, NULL, NULL, flag | VM_FIRSTFIT);
19809517SBill.Taylor@Sun.COM
19819517SBill.Taylor@Sun.COM if (addr == NULL) {
19829517SBill.Taylor@Sun.COM /* No more HW entries available */
19839517SBill.Taylor@Sun.COM return (DDI_FAILURE);
19849517SBill.Taylor@Sun.COM }
19859517SBill.Taylor@Sun.COM
1986*12965SWilliam.Taylor@Oracle.COM hdl->hr_acchdl = NULL; /* only used for mbox resources */
19879517SBill.Taylor@Sun.COM
19889517SBill.Taylor@Sun.COM /* Calculate vaddr and HW table index */
19899517SBill.Taylor@Sun.COM offset = (uintptr_t)addr - (uintptr_t)pool_info->rsrc_start;
1990*12965SWilliam.Taylor@Oracle.COM hdl->hr_addr = NULL;
19919517SBill.Taylor@Sun.COM hdl->hr_indx = offset >> pool_info->rsrc_shift;
19929517SBill.Taylor@Sun.COM
1993*12965SWilliam.Taylor@Oracle.COM /* ICM will be allocated and mapped if and when it gets used */
19949517SBill.Taylor@Sun.COM
19959517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
19969517SBill.Taylor@Sun.COM }
19979517SBill.Taylor@Sun.COM
19989517SBill.Taylor@Sun.COM
19999517SBill.Taylor@Sun.COM /*
20009517SBill.Taylor@Sun.COM * hermon_rsrc_hw_entry_free()
20019517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
20029517SBill.Taylor@Sun.COM */
20039517SBill.Taylor@Sun.COM static void
hermon_rsrc_hw_entry_free(hermon_rsrc_pool_info_t * pool_info,hermon_rsrc_t * hdl)20049517SBill.Taylor@Sun.COM hermon_rsrc_hw_entry_free(hermon_rsrc_pool_info_t *pool_info,
20059517SBill.Taylor@Sun.COM hermon_rsrc_t *hdl)
20069517SBill.Taylor@Sun.COM {
20079517SBill.Taylor@Sun.COM void *addr;
20089517SBill.Taylor@Sun.COM uint64_t offset;
20099517SBill.Taylor@Sun.COM int status;
20109517SBill.Taylor@Sun.COM
20119517SBill.Taylor@Sun.COM ASSERT(pool_info != NULL);
20129517SBill.Taylor@Sun.COM ASSERT(hdl != NULL);
20139517SBill.Taylor@Sun.COM
20149517SBill.Taylor@Sun.COM /* Calculate the allocated address */
20159517SBill.Taylor@Sun.COM offset = hdl->hr_indx << pool_info->rsrc_shift;
20169517SBill.Taylor@Sun.COM addr = (void *)(uintptr_t)(offset + (uintptr_t)pool_info->rsrc_start);
20179517SBill.Taylor@Sun.COM
20189517SBill.Taylor@Sun.COM /* Use vmem_xfree() to free up the HW table entry */
20199517SBill.Taylor@Sun.COM vmem_xfree(pool_info->rsrc_vmp, addr, hdl->hr_len);
20209517SBill.Taylor@Sun.COM
20219517SBill.Taylor@Sun.COM if (pool_info->rsrc_loc == HERMON_IN_ICM) {
2022*12965SWilliam.Taylor@Oracle.COM int num_to_hdl;
2023*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_type_t rsrc_type = pool_info->rsrc_type;
2024*12965SWilliam.Taylor@Oracle.COM
2025*12965SWilliam.Taylor@Oracle.COM num_to_hdl = (rsrc_type == HERMON_QPC ||
2026*12965SWilliam.Taylor@Oracle.COM rsrc_type == HERMON_CQC || rsrc_type == HERMON_SRQC);
2027*12965SWilliam.Taylor@Oracle.COM
20289517SBill.Taylor@Sun.COM /* free ICM references, and free ICM if required */
2029*12965SWilliam.Taylor@Oracle.COM status = hermon_rsrc_hw_entry_icm_free(pool_info, hdl,
2030*12965SWilliam.Taylor@Oracle.COM num_to_hdl);
20319517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS)
20329517SBill.Taylor@Sun.COM HERMON_WARNING(pool_info->rsrc_state,
20339517SBill.Taylor@Sun.COM "failure in hw_entry_free");
20349517SBill.Taylor@Sun.COM }
20359517SBill.Taylor@Sun.COM }
20369517SBill.Taylor@Sun.COM
20379517SBill.Taylor@Sun.COM /*
20389517SBill.Taylor@Sun.COM * hermon_rsrc_hw_entry_icm_confirm()
20399517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
20409517SBill.Taylor@Sun.COM */
20419517SBill.Taylor@Sun.COM 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)20429517SBill.Taylor@Sun.COM hermon_rsrc_hw_entry_icm_confirm(hermon_rsrc_pool_info_t *pool_info, uint_t num,
2043*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_t *hdl, int num_to_hdl)
20449517SBill.Taylor@Sun.COM {
20459517SBill.Taylor@Sun.COM hermon_state_t *state;
20469517SBill.Taylor@Sun.COM hermon_icm_table_t *icm_table;
20479517SBill.Taylor@Sun.COM uint8_t *bitmap;
20489517SBill.Taylor@Sun.COM hermon_dma_info_t *dma_info;
20499517SBill.Taylor@Sun.COM hermon_rsrc_type_t type;
20509517SBill.Taylor@Sun.COM uint32_t rindx, span_offset;
20519517SBill.Taylor@Sun.COM uint32_t span_avail;
20529517SBill.Taylor@Sun.COM int num_backed;
20539517SBill.Taylor@Sun.COM int status;
20549517SBill.Taylor@Sun.COM uint32_t index1, index2;
20559517SBill.Taylor@Sun.COM
20569517SBill.Taylor@Sun.COM /*
20579517SBill.Taylor@Sun.COM * Utility routine responsible for ensuring that there is memory
20589517SBill.Taylor@Sun.COM * backing the ICM resources allocated via hermon_rsrc_hw_entry_alloc().
20599517SBill.Taylor@Sun.COM * Confirm existing ICM mapping(s) or allocate ICM memory for the
20609517SBill.Taylor@Sun.COM * given hardware resources being allocated, and increment the
20619517SBill.Taylor@Sun.COM * ICM DMA structure(s) reference count.
20629517SBill.Taylor@Sun.COM *
20639517SBill.Taylor@Sun.COM * We may be allocating more objects than can fit in a single span,
20649517SBill.Taylor@Sun.COM * or more than will fit in the remaining contiguous memory (from
20659517SBill.Taylor@Sun.COM * the offset indicated by hdl->ar_indx) in the span in question.
20669517SBill.Taylor@Sun.COM * In either of these cases, we'll be breaking up our allocation
20679517SBill.Taylor@Sun.COM * into multiple spans.
20689517SBill.Taylor@Sun.COM */
20699517SBill.Taylor@Sun.COM state = pool_info->rsrc_state;
20709517SBill.Taylor@Sun.COM type = pool_info->rsrc_type;
20719517SBill.Taylor@Sun.COM icm_table = &state->hs_icm[type];
20729517SBill.Taylor@Sun.COM
20739517SBill.Taylor@Sun.COM rindx = hdl->hr_indx;
20749517SBill.Taylor@Sun.COM hermon_index(index1, index2, rindx, icm_table, span_offset);
20759517SBill.Taylor@Sun.COM
20769517SBill.Taylor@Sun.COM if (hermon_rsrc_verbose) {
20779517SBill.Taylor@Sun.COM IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entry_icm_confirm: "
20789517SBill.Taylor@Sun.COM "type (0x%x) num (0x%x) length (0x%x) index (0x%x, 0x%x): ",
20799517SBill.Taylor@Sun.COM type, num, hdl->hr_len, index1, index2);
20809517SBill.Taylor@Sun.COM }
20819517SBill.Taylor@Sun.COM
20829517SBill.Taylor@Sun.COM mutex_enter(&icm_table->icm_table_lock);
2083*12965SWilliam.Taylor@Oracle.COM hermon_bitmap(bitmap, dma_info, icm_table, index1, num_to_hdl);
20849517SBill.Taylor@Sun.COM while (num) {
20859517SBill.Taylor@Sun.COM #ifndef __lock_lint
20869517SBill.Taylor@Sun.COM while (icm_table->icm_busy) {
20879517SBill.Taylor@Sun.COM cv_wait(&icm_table->icm_table_cv,
20889517SBill.Taylor@Sun.COM &icm_table->icm_table_lock);
20899517SBill.Taylor@Sun.COM }
20909517SBill.Taylor@Sun.COM #endif
20919517SBill.Taylor@Sun.COM if (!HERMON_BMAP_BIT_ISSET(bitmap, index2)) {
20929517SBill.Taylor@Sun.COM /* Allocate ICM for this span */
20939517SBill.Taylor@Sun.COM icm_table->icm_busy = 1;
20949517SBill.Taylor@Sun.COM mutex_exit(&icm_table->icm_table_lock);
20959517SBill.Taylor@Sun.COM status = hermon_icm_alloc(state, type, index1, index2);
20969517SBill.Taylor@Sun.COM mutex_enter(&icm_table->icm_table_lock);
20979517SBill.Taylor@Sun.COM icm_table->icm_busy = 0;
20989517SBill.Taylor@Sun.COM cv_broadcast(&icm_table->icm_table_cv);
20999517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
21009517SBill.Taylor@Sun.COM goto fail_alloc;
21019517SBill.Taylor@Sun.COM }
21029517SBill.Taylor@Sun.COM if (hermon_rsrc_verbose) {
21039517SBill.Taylor@Sun.COM IBTF_DPRINTF_L2("hermon", "hermon_rsrc_"
21049517SBill.Taylor@Sun.COM "hw_entry_icm_confirm: ALLOCATED ICM: "
21059517SBill.Taylor@Sun.COM "type (0x%x) index (0x%x, 0x%x)",
21069517SBill.Taylor@Sun.COM type, index1, index2);
21079517SBill.Taylor@Sun.COM }
21089517SBill.Taylor@Sun.COM }
21099517SBill.Taylor@Sun.COM
21109517SBill.Taylor@Sun.COM /*
21119517SBill.Taylor@Sun.COM * We need to increment the refcnt of this span by the
21129517SBill.Taylor@Sun.COM * number of objects in this resource allocation that are
21139517SBill.Taylor@Sun.COM * backed by this span. Given that the rsrc allocation is
21149517SBill.Taylor@Sun.COM * contiguous, this value will be the number of objects in
21159517SBill.Taylor@Sun.COM * the span from 'span_offset' onward, either up to a max
21169517SBill.Taylor@Sun.COM * of the total number of objects, or the end of the span.
21179517SBill.Taylor@Sun.COM * So, determine the number of objects that can be backed
21189517SBill.Taylor@Sun.COM * by this span ('span_avail'), then determine the number
21199517SBill.Taylor@Sun.COM * of backed resources.
21209517SBill.Taylor@Sun.COM */
21219517SBill.Taylor@Sun.COM span_avail = icm_table->span - span_offset;
21229517SBill.Taylor@Sun.COM if (num > span_avail) {
21239517SBill.Taylor@Sun.COM num_backed = span_avail;
21249517SBill.Taylor@Sun.COM } else {
21259517SBill.Taylor@Sun.COM num_backed = num;
21269517SBill.Taylor@Sun.COM }
21279517SBill.Taylor@Sun.COM
21289517SBill.Taylor@Sun.COM /*
21299517SBill.Taylor@Sun.COM * Now that we know 'num_backed', increment the refcnt,
21309517SBill.Taylor@Sun.COM * decrement the total number, and set 'span_offset' to
21319517SBill.Taylor@Sun.COM * 0 in case we roll over into the next span.
21329517SBill.Taylor@Sun.COM */
21339517SBill.Taylor@Sun.COM dma_info[index2].icm_refcnt += num_backed;
21349517SBill.Taylor@Sun.COM rindx += num_backed;
21359517SBill.Taylor@Sun.COM num -= num_backed;
21369517SBill.Taylor@Sun.COM
21379517SBill.Taylor@Sun.COM if (hermon_rsrc_verbose) {
21389517SBill.Taylor@Sun.COM IBTF_DPRINTF_L2("ALLOC", "ICM type (0x%x) index "
21399517SBill.Taylor@Sun.COM "(0x%x, 0x%x) num_backed (0x%x)",
21409517SBill.Taylor@Sun.COM type, index1, index2, num_backed);
21419517SBill.Taylor@Sun.COM IBTF_DPRINTF_L2("ALLOC", "ICM type (0x%x) refcnt now "
21429517SBill.Taylor@Sun.COM "(0x%x) num_remaining (0x%x)", type,
21439517SBill.Taylor@Sun.COM dma_info[index2].icm_refcnt, num);
21449517SBill.Taylor@Sun.COM }
21459517SBill.Taylor@Sun.COM if (num == 0)
21469517SBill.Taylor@Sun.COM break;
21479517SBill.Taylor@Sun.COM
21489517SBill.Taylor@Sun.COM hermon_index(index1, index2, rindx, icm_table, span_offset);
2149*12965SWilliam.Taylor@Oracle.COM hermon_bitmap(bitmap, dma_info, icm_table, index1, num_to_hdl);
21509517SBill.Taylor@Sun.COM }
21519517SBill.Taylor@Sun.COM mutex_exit(&icm_table->icm_table_lock);
21529517SBill.Taylor@Sun.COM
21539517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
21549517SBill.Taylor@Sun.COM
21559517SBill.Taylor@Sun.COM fail_alloc:
21569517SBill.Taylor@Sun.COM /* JBDB */
21579517SBill.Taylor@Sun.COM if (hermon_rsrc_verbose) {
21589517SBill.Taylor@Sun.COM IBTF_DPRINTF_L2("hermon", "hermon_rsrc_"
21599517SBill.Taylor@Sun.COM "hw_entry_icm_confirm: FAILED ICM ALLOC: "
21609517SBill.Taylor@Sun.COM "type (0x%x) num remaind (0x%x) index (0x%x, 0x%x)"
21619517SBill.Taylor@Sun.COM "refcnt (0x%x)", type, num, index1, index2,
21629517SBill.Taylor@Sun.COM icm_table->icm_dma[index1][index2].icm_refcnt);
21639517SBill.Taylor@Sun.COM }
21649517SBill.Taylor@Sun.COM IBTF_DPRINTF_L2("hermon", "WARNING: "
21659517SBill.Taylor@Sun.COM "unimplemented fail code in hermon_rsrc_hw_entry_icm_alloc\n");
21669517SBill.Taylor@Sun.COM
21679517SBill.Taylor@Sun.COM #if needs_work
21689517SBill.Taylor@Sun.COM /* free refcnt's and any spans we've allocated */
21699517SBill.Taylor@Sun.COM while (index-- != start) {
21709517SBill.Taylor@Sun.COM /*
21719517SBill.Taylor@Sun.COM * JBDB - This is a bit tricky. We need to
21729517SBill.Taylor@Sun.COM * free refcnt's on any spans that we've
21739517SBill.Taylor@Sun.COM * incremented them on, and completely free
21749517SBill.Taylor@Sun.COM * spans that we've allocated. How do we do
21759517SBill.Taylor@Sun.COM * this here? Does it need to be as involved
21769517SBill.Taylor@Sun.COM * as the core of icm_free() below, or can
21779517SBill.Taylor@Sun.COM * we leverage breadcrumbs somehow?
21789517SBill.Taylor@Sun.COM */
21799517SBill.Taylor@Sun.COM HERMON_WARNING(state, "unable to allocate ICM memory: "
21809517SBill.Taylor@Sun.COM "UNIMPLEMENTED HANDLING!!");
21819517SBill.Taylor@Sun.COM }
21829517SBill.Taylor@Sun.COM #else
21839517SBill.Taylor@Sun.COM cmn_err(CE_WARN,
21849517SBill.Taylor@Sun.COM "unimplemented fail code in hermon_rsrc_hw_entry_icm_alloc\n");
21859517SBill.Taylor@Sun.COM #endif
21869517SBill.Taylor@Sun.COM mutex_exit(&icm_table->icm_table_lock);
21879517SBill.Taylor@Sun.COM
21889517SBill.Taylor@Sun.COM HERMON_WARNING(state, "unable to allocate ICM memory");
21899517SBill.Taylor@Sun.COM return (DDI_FAILURE);
21909517SBill.Taylor@Sun.COM }
21919517SBill.Taylor@Sun.COM
21929517SBill.Taylor@Sun.COM /*
21939517SBill.Taylor@Sun.COM * hermon_rsrc_hw_entry_icm_free()
21949517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
21959517SBill.Taylor@Sun.COM */
21969517SBill.Taylor@Sun.COM static int
hermon_rsrc_hw_entry_icm_free(hermon_rsrc_pool_info_t * pool_info,hermon_rsrc_t * hdl,int num_to_hdl)21979517SBill.Taylor@Sun.COM hermon_rsrc_hw_entry_icm_free(hermon_rsrc_pool_info_t *pool_info,
2198*12965SWilliam.Taylor@Oracle.COM hermon_rsrc_t *hdl, int num_to_hdl)
21999517SBill.Taylor@Sun.COM {
22009517SBill.Taylor@Sun.COM hermon_state_t *state;
22019517SBill.Taylor@Sun.COM hermon_icm_table_t *icm_table;
22029517SBill.Taylor@Sun.COM uint8_t *bitmap;
22039517SBill.Taylor@Sun.COM hermon_dma_info_t *dma_info;
22049517SBill.Taylor@Sun.COM hermon_rsrc_type_t type;
22059517SBill.Taylor@Sun.COM uint32_t span_offset;
22069517SBill.Taylor@Sun.COM uint32_t span_remain;
22079517SBill.Taylor@Sun.COM int num_freed;
22089517SBill.Taylor@Sun.COM int num;
22099517SBill.Taylor@Sun.COM uint32_t index1, index2, rindx;
22109517SBill.Taylor@Sun.COM
22119517SBill.Taylor@Sun.COM /*
22129517SBill.Taylor@Sun.COM * Utility routine responsible for freeing references to ICM
22139517SBill.Taylor@Sun.COM * DMA spans, and freeing the ICM memory if necessary.
22149517SBill.Taylor@Sun.COM *
22159517SBill.Taylor@Sun.COM * We may have allocated objects in a single contiguous resource
22169517SBill.Taylor@Sun.COM * allocation that reside in a number of spans, at any given
22179517SBill.Taylor@Sun.COM * starting offset within a span. We therefore must determine
22189517SBill.Taylor@Sun.COM * where this allocation starts, and then determine if we need
22199517SBill.Taylor@Sun.COM * to free objects in more than one span.
22209517SBill.Taylor@Sun.COM */
22219517SBill.Taylor@Sun.COM state = pool_info->rsrc_state;
22229517SBill.Taylor@Sun.COM type = pool_info->rsrc_type;
22239517SBill.Taylor@Sun.COM icm_table = &state->hs_icm[type];
22249517SBill.Taylor@Sun.COM
22259517SBill.Taylor@Sun.COM rindx = hdl->hr_indx;
22269517SBill.Taylor@Sun.COM hermon_index(index1, index2, rindx, icm_table, span_offset);
2227*12965SWilliam.Taylor@Oracle.COM hermon_bitmap(bitmap, dma_info, icm_table, index1, num_to_hdl);
22289517SBill.Taylor@Sun.COM
22299517SBill.Taylor@Sun.COM /* determine the number of ICM objects in this allocation */
22309517SBill.Taylor@Sun.COM num = hdl->hr_len >> pool_info->rsrc_shift;
22319517SBill.Taylor@Sun.COM
22329517SBill.Taylor@Sun.COM if (hermon_rsrc_verbose) {
22339517SBill.Taylor@Sun.COM IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entry_icm_free: "
22349517SBill.Taylor@Sun.COM "type (0x%x) num (0x%x) length (0x%x) index (0x%x, 0x%x)",
22359517SBill.Taylor@Sun.COM type, num, hdl->hr_len, index1, index2);
22369517SBill.Taylor@Sun.COM }
22379517SBill.Taylor@Sun.COM mutex_enter(&icm_table->icm_table_lock);
22389517SBill.Taylor@Sun.COM while (num) {
22399517SBill.Taylor@Sun.COM /*
22409517SBill.Taylor@Sun.COM * As with the ICM confirm code above, we need to
22419517SBill.Taylor@Sun.COM * decrement the ICM span(s) by the number of
22429517SBill.Taylor@Sun.COM * resources being freed. So, determine the number
22439517SBill.Taylor@Sun.COM * of objects that are backed in this span from
22449517SBill.Taylor@Sun.COM * 'span_offset' onward, and set 'num_freed' to
22459517SBill.Taylor@Sun.COM * the smaller of either that number ('span_remain'),
22469517SBill.Taylor@Sun.COM * or the total number of objects being freed.
22479517SBill.Taylor@Sun.COM */
22489517SBill.Taylor@Sun.COM span_remain = icm_table->span - span_offset;
22499517SBill.Taylor@Sun.COM if (num > span_remain) {
22509517SBill.Taylor@Sun.COM num_freed = span_remain;
22519517SBill.Taylor@Sun.COM } else {
22529517SBill.Taylor@Sun.COM num_freed = num;
22539517SBill.Taylor@Sun.COM }
22549517SBill.Taylor@Sun.COM
22559517SBill.Taylor@Sun.COM /*
22569517SBill.Taylor@Sun.COM * Now that we know 'num_freed', decrement the refcnt,
22579517SBill.Taylor@Sun.COM * decrement the total number, and set 'span_offset' to
22589517SBill.Taylor@Sun.COM * 0 in case we roll over into the next span.
22599517SBill.Taylor@Sun.COM */
22609517SBill.Taylor@Sun.COM dma_info[index2].icm_refcnt -= num_freed;
22619517SBill.Taylor@Sun.COM num -= num_freed;
22629517SBill.Taylor@Sun.COM rindx += num_freed;
22639517SBill.Taylor@Sun.COM
22649517SBill.Taylor@Sun.COM if (hermon_rsrc_verbose) {
22659517SBill.Taylor@Sun.COM IBTF_DPRINTF_L2("FREE", "ICM type (0x%x) index "
22669517SBill.Taylor@Sun.COM "(0x%x, 0x%x) num_freed (0x%x)", type,
22679517SBill.Taylor@Sun.COM index1, index2, num_freed);
22689517SBill.Taylor@Sun.COM IBTF_DPRINTF_L2("FREE", "ICM type (0x%x) refcnt now "
22699517SBill.Taylor@Sun.COM "(0x%x) num remaining (0x%x)", type,
22709517SBill.Taylor@Sun.COM icm_table->icm_dma[index1][index2].icm_refcnt, num);
22719517SBill.Taylor@Sun.COM }
22729517SBill.Taylor@Sun.COM
22739517SBill.Taylor@Sun.COM #if HERMON_ICM_FREE_ENABLED
22749517SBill.Taylor@Sun.COM /* If we've freed the last object in this span, free it */
22759517SBill.Taylor@Sun.COM if ((index1 != 0 || index2 != 0) &&
22769517SBill.Taylor@Sun.COM (dma_info[index2].icm_refcnt == 0)) {
22779517SBill.Taylor@Sun.COM if (hermon_rsrc_verbose) {
22789517SBill.Taylor@Sun.COM IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entry"
22799517SBill.Taylor@Sun.COM "_icm_free: freeing ICM type (0x%x) index"
22809517SBill.Taylor@Sun.COM " (0x%x, 0x%x)", type, index1, index2);
22819517SBill.Taylor@Sun.COM }
22829517SBill.Taylor@Sun.COM hermon_icm_free(state, type, index1, index2);
22839517SBill.Taylor@Sun.COM }
22849517SBill.Taylor@Sun.COM #endif
22859517SBill.Taylor@Sun.COM if (num == 0)
22869517SBill.Taylor@Sun.COM break;
22879517SBill.Taylor@Sun.COM
22889517SBill.Taylor@Sun.COM hermon_index(index1, index2, rindx, icm_table, span_offset);
2289*12965SWilliam.Taylor@Oracle.COM hermon_bitmap(bitmap, dma_info, icm_table, index1, num_to_hdl);
22909517SBill.Taylor@Sun.COM }
22919517SBill.Taylor@Sun.COM mutex_exit(&icm_table->icm_table_lock);
22929517SBill.Taylor@Sun.COM
22939517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
22949517SBill.Taylor@Sun.COM }
22959517SBill.Taylor@Sun.COM
22969517SBill.Taylor@Sun.COM
22979517SBill.Taylor@Sun.COM
22989517SBill.Taylor@Sun.COM /*
22999517SBill.Taylor@Sun.COM * hermon_rsrc_swhdl_alloc()
23009517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
23019517SBill.Taylor@Sun.COM */
23029517SBill.Taylor@Sun.COM static int
hermon_rsrc_swhdl_alloc(hermon_rsrc_pool_info_t * pool_info,uint_t sleepflag,hermon_rsrc_t * hdl)23039517SBill.Taylor@Sun.COM hermon_rsrc_swhdl_alloc(hermon_rsrc_pool_info_t *pool_info, uint_t sleepflag,
23049517SBill.Taylor@Sun.COM hermon_rsrc_t *hdl)
23059517SBill.Taylor@Sun.COM {
23069517SBill.Taylor@Sun.COM void *addr;
23079517SBill.Taylor@Sun.COM int flag;
23089517SBill.Taylor@Sun.COM
23099517SBill.Taylor@Sun.COM ASSERT(pool_info != NULL);
23109517SBill.Taylor@Sun.COM ASSERT(hdl != NULL);
23119517SBill.Taylor@Sun.COM
23129517SBill.Taylor@Sun.COM /* Allocate the software handle structure */
23139517SBill.Taylor@Sun.COM flag = (sleepflag == HERMON_SLEEP) ? KM_SLEEP : KM_NOSLEEP;
23149517SBill.Taylor@Sun.COM addr = kmem_cache_alloc(pool_info->rsrc_private, flag);
23159517SBill.Taylor@Sun.COM if (addr == NULL) {
23169517SBill.Taylor@Sun.COM return (DDI_FAILURE);
23179517SBill.Taylor@Sun.COM }
23189517SBill.Taylor@Sun.COM hdl->hr_len = pool_info->rsrc_quantum;
23199517SBill.Taylor@Sun.COM hdl->hr_addr = addr;
23209517SBill.Taylor@Sun.COM
23219517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
23229517SBill.Taylor@Sun.COM }
23239517SBill.Taylor@Sun.COM
23249517SBill.Taylor@Sun.COM
23259517SBill.Taylor@Sun.COM /*
23269517SBill.Taylor@Sun.COM * hermon_rsrc_swhdl_free()
23279517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
23289517SBill.Taylor@Sun.COM */
23299517SBill.Taylor@Sun.COM static void
hermon_rsrc_swhdl_free(hermon_rsrc_pool_info_t * pool_info,hermon_rsrc_t * hdl)23309517SBill.Taylor@Sun.COM hermon_rsrc_swhdl_free(hermon_rsrc_pool_info_t *pool_info, hermon_rsrc_t *hdl)
23319517SBill.Taylor@Sun.COM {
23329517SBill.Taylor@Sun.COM ASSERT(pool_info != NULL);
23339517SBill.Taylor@Sun.COM ASSERT(hdl != NULL);
23349517SBill.Taylor@Sun.COM
23359517SBill.Taylor@Sun.COM /* Free the software handle structure */
23369517SBill.Taylor@Sun.COM kmem_cache_free(pool_info->rsrc_private, hdl->hr_addr);
23379517SBill.Taylor@Sun.COM }
23389517SBill.Taylor@Sun.COM
23399517SBill.Taylor@Sun.COM
23409517SBill.Taylor@Sun.COM /*
23419517SBill.Taylor@Sun.COM * hermon_rsrc_pdhdl_alloc()
23429517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
23439517SBill.Taylor@Sun.COM */
23449517SBill.Taylor@Sun.COM static int
hermon_rsrc_pdhdl_alloc(hermon_rsrc_pool_info_t * pool_info,uint_t sleepflag,hermon_rsrc_t * hdl)23459517SBill.Taylor@Sun.COM hermon_rsrc_pdhdl_alloc(hermon_rsrc_pool_info_t *pool_info, uint_t sleepflag,
23469517SBill.Taylor@Sun.COM hermon_rsrc_t *hdl)
23479517SBill.Taylor@Sun.COM {
23489517SBill.Taylor@Sun.COM hermon_pdhdl_t addr;
23499517SBill.Taylor@Sun.COM void *tmpaddr;
23509517SBill.Taylor@Sun.COM int flag, status;
23519517SBill.Taylor@Sun.COM
23529517SBill.Taylor@Sun.COM ASSERT(pool_info != NULL);
23539517SBill.Taylor@Sun.COM ASSERT(hdl != NULL);
23549517SBill.Taylor@Sun.COM
23559517SBill.Taylor@Sun.COM /* Allocate the software handle */
23569517SBill.Taylor@Sun.COM status = hermon_rsrc_swhdl_alloc(pool_info, sleepflag, hdl);
23579517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) {
23589517SBill.Taylor@Sun.COM return (DDI_FAILURE);
23599517SBill.Taylor@Sun.COM }
23609517SBill.Taylor@Sun.COM addr = (hermon_pdhdl_t)hdl->hr_addr;
23619517SBill.Taylor@Sun.COM _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*addr))
23629517SBill.Taylor@Sun.COM
23639517SBill.Taylor@Sun.COM /* Allocate a PD number for the handle */
23649517SBill.Taylor@Sun.COM flag = (sleepflag == HERMON_SLEEP) ? VM_SLEEP : VM_NOSLEEP;
23659517SBill.Taylor@Sun.COM tmpaddr = vmem_alloc(pool_info->rsrc_vmp, 1, flag);
23669517SBill.Taylor@Sun.COM if (tmpaddr == NULL) {
23679517SBill.Taylor@Sun.COM /* No more PD number entries available */
23689517SBill.Taylor@Sun.COM hermon_rsrc_swhdl_free(pool_info, hdl);
23699517SBill.Taylor@Sun.COM return (DDI_FAILURE);
23709517SBill.Taylor@Sun.COM }
23719517SBill.Taylor@Sun.COM addr->pd_pdnum = (uint32_t)(uintptr_t)tmpaddr;
23729517SBill.Taylor@Sun.COM addr->pd_rsrcp = hdl;
23739517SBill.Taylor@Sun.COM hdl->hr_indx = addr->pd_pdnum;
23749517SBill.Taylor@Sun.COM
23759517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
23769517SBill.Taylor@Sun.COM }
23779517SBill.Taylor@Sun.COM
23789517SBill.Taylor@Sun.COM
23799517SBill.Taylor@Sun.COM /*
23809517SBill.Taylor@Sun.COM * hermon_rsrc_pdhdl_free()
23819517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
23829517SBill.Taylor@Sun.COM */
23839517SBill.Taylor@Sun.COM static void
hermon_rsrc_pdhdl_free(hermon_rsrc_pool_info_t * pool_info,hermon_rsrc_t * hdl)23849517SBill.Taylor@Sun.COM hermon_rsrc_pdhdl_free(hermon_rsrc_pool_info_t *pool_info, hermon_rsrc_t *hdl)
23859517SBill.Taylor@Sun.COM {
23869517SBill.Taylor@Sun.COM ASSERT(pool_info != NULL);
23879517SBill.Taylor@Sun.COM ASSERT(hdl != NULL);
23889517SBill.Taylor@Sun.COM
23899517SBill.Taylor@Sun.COM /* Use vmem_free() to free up the PD number */
23909517SBill.Taylor@Sun.COM vmem_free(pool_info->rsrc_vmp, (void *)(uintptr_t)hdl->hr_indx, 1);
23919517SBill.Taylor@Sun.COM
23929517SBill.Taylor@Sun.COM /* Free the software handle structure */
23939517SBill.Taylor@Sun.COM hermon_rsrc_swhdl_free(pool_info, hdl);
23949517SBill.Taylor@Sun.COM }
23959517SBill.Taylor@Sun.COM
23969517SBill.Taylor@Sun.COM
23979517SBill.Taylor@Sun.COM /*
23989517SBill.Taylor@Sun.COM * hermon_rsrc_pdhdl_constructor()
23999517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
24009517SBill.Taylor@Sun.COM */
24019517SBill.Taylor@Sun.COM /* ARGSUSED */
24029517SBill.Taylor@Sun.COM static int
hermon_rsrc_pdhdl_constructor(void * pd,void * priv,int flags)24039517SBill.Taylor@Sun.COM hermon_rsrc_pdhdl_constructor(void *pd, void *priv, int flags)
24049517SBill.Taylor@Sun.COM {
24059517SBill.Taylor@Sun.COM hermon_pdhdl_t pdhdl;
24069517SBill.Taylor@Sun.COM hermon_state_t *state;
24079517SBill.Taylor@Sun.COM
24089517SBill.Taylor@Sun.COM pdhdl = (hermon_pdhdl_t)pd;
24099517SBill.Taylor@Sun.COM state = (hermon_state_t *)priv;
24109517SBill.Taylor@Sun.COM
24119517SBill.Taylor@Sun.COM mutex_init(&pdhdl->pd_lock, NULL, MUTEX_DRIVER,
24129517SBill.Taylor@Sun.COM DDI_INTR_PRI(state->hs_intrmsi_pri));
24139517SBill.Taylor@Sun.COM
24149517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
24159517SBill.Taylor@Sun.COM }
24169517SBill.Taylor@Sun.COM
24179517SBill.Taylor@Sun.COM
24189517SBill.Taylor@Sun.COM /*
24199517SBill.Taylor@Sun.COM * hermon_rsrc_pdhdl_destructor()
24209517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
24219517SBill.Taylor@Sun.COM */
24229517SBill.Taylor@Sun.COM /* ARGSUSED */
24239517SBill.Taylor@Sun.COM static void
hermon_rsrc_pdhdl_destructor(void * pd,void * priv)24249517SBill.Taylor@Sun.COM hermon_rsrc_pdhdl_destructor(void *pd, void *priv)
24259517SBill.Taylor@Sun.COM {
24269517SBill.Taylor@Sun.COM hermon_pdhdl_t pdhdl;
24279517SBill.Taylor@Sun.COM
24289517SBill.Taylor@Sun.COM pdhdl = (hermon_pdhdl_t)pd;
24299517SBill.Taylor@Sun.COM
24309517SBill.Taylor@Sun.COM mutex_destroy(&pdhdl->pd_lock);
24319517SBill.Taylor@Sun.COM }
24329517SBill.Taylor@Sun.COM
24339517SBill.Taylor@Sun.COM
24349517SBill.Taylor@Sun.COM /*
24359517SBill.Taylor@Sun.COM * hermon_rsrc_cqhdl_constructor()
24369517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
24379517SBill.Taylor@Sun.COM */
24389517SBill.Taylor@Sun.COM /* ARGSUSED */
24399517SBill.Taylor@Sun.COM static int
hermon_rsrc_cqhdl_constructor(void * cq,void * priv,int flags)24409517SBill.Taylor@Sun.COM hermon_rsrc_cqhdl_constructor(void *cq, void *priv, int flags)
24419517SBill.Taylor@Sun.COM {
24429517SBill.Taylor@Sun.COM hermon_cqhdl_t cqhdl;
24439517SBill.Taylor@Sun.COM hermon_state_t *state;
24449517SBill.Taylor@Sun.COM
24459517SBill.Taylor@Sun.COM cqhdl = (hermon_cqhdl_t)cq;
24469517SBill.Taylor@Sun.COM state = (hermon_state_t *)priv;
24479517SBill.Taylor@Sun.COM
24489517SBill.Taylor@Sun.COM mutex_init(&cqhdl->cq_lock, NULL, MUTEX_DRIVER,
24499517SBill.Taylor@Sun.COM DDI_INTR_PRI(state->hs_intrmsi_pri));
24509517SBill.Taylor@Sun.COM
24519517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
24529517SBill.Taylor@Sun.COM }
24539517SBill.Taylor@Sun.COM
24549517SBill.Taylor@Sun.COM
24559517SBill.Taylor@Sun.COM /*
24569517SBill.Taylor@Sun.COM * hermon_rsrc_cqhdl_destructor()
24579517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
24589517SBill.Taylor@Sun.COM */
24599517SBill.Taylor@Sun.COM /* ARGSUSED */
24609517SBill.Taylor@Sun.COM static void
hermon_rsrc_cqhdl_destructor(void * cq,void * priv)24619517SBill.Taylor@Sun.COM hermon_rsrc_cqhdl_destructor(void *cq, void *priv)
24629517SBill.Taylor@Sun.COM {
24639517SBill.Taylor@Sun.COM hermon_cqhdl_t cqhdl;
24649517SBill.Taylor@Sun.COM
24659517SBill.Taylor@Sun.COM cqhdl = (hermon_cqhdl_t)cq;
24669517SBill.Taylor@Sun.COM
24679517SBill.Taylor@Sun.COM mutex_destroy(&cqhdl->cq_lock);
24689517SBill.Taylor@Sun.COM }
24699517SBill.Taylor@Sun.COM
24709517SBill.Taylor@Sun.COM
24719517SBill.Taylor@Sun.COM /*
24729517SBill.Taylor@Sun.COM * hermon_rsrc_qphdl_constructor()
24739517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
24749517SBill.Taylor@Sun.COM */
24759517SBill.Taylor@Sun.COM /* ARGSUSED */
24769517SBill.Taylor@Sun.COM static int
hermon_rsrc_qphdl_constructor(void * qp,void * priv,int flags)24779517SBill.Taylor@Sun.COM hermon_rsrc_qphdl_constructor(void *qp, void *priv, int flags)
24789517SBill.Taylor@Sun.COM {
24799517SBill.Taylor@Sun.COM hermon_qphdl_t qphdl;
24809517SBill.Taylor@Sun.COM hermon_state_t *state;
24819517SBill.Taylor@Sun.COM
24829517SBill.Taylor@Sun.COM qphdl = (hermon_qphdl_t)qp;
24839517SBill.Taylor@Sun.COM state = (hermon_state_t *)priv;
24849517SBill.Taylor@Sun.COM
24859517SBill.Taylor@Sun.COM mutex_init(&qphdl->qp_lock, NULL, MUTEX_DRIVER,
24869517SBill.Taylor@Sun.COM DDI_INTR_PRI(state->hs_intrmsi_pri));
24879517SBill.Taylor@Sun.COM
24889517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
24899517SBill.Taylor@Sun.COM }
24909517SBill.Taylor@Sun.COM
24919517SBill.Taylor@Sun.COM
24929517SBill.Taylor@Sun.COM /*
24939517SBill.Taylor@Sun.COM * hermon_rsrc_qphdl_destructor()
24949517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
24959517SBill.Taylor@Sun.COM */
24969517SBill.Taylor@Sun.COM /* ARGSUSED */
24979517SBill.Taylor@Sun.COM static void
hermon_rsrc_qphdl_destructor(void * qp,void * priv)24989517SBill.Taylor@Sun.COM hermon_rsrc_qphdl_destructor(void *qp, void *priv)
24999517SBill.Taylor@Sun.COM {
25009517SBill.Taylor@Sun.COM hermon_qphdl_t qphdl;
25019517SBill.Taylor@Sun.COM
25029517SBill.Taylor@Sun.COM qphdl = (hermon_qphdl_t)qp;
25039517SBill.Taylor@Sun.COM
25049517SBill.Taylor@Sun.COM mutex_destroy(&qphdl->qp_lock);
25059517SBill.Taylor@Sun.COM }
25069517SBill.Taylor@Sun.COM
25079517SBill.Taylor@Sun.COM
25089517SBill.Taylor@Sun.COM /*
25099517SBill.Taylor@Sun.COM * hermon_rsrc_srqhdl_constructor()
25109517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
25119517SBill.Taylor@Sun.COM */
25129517SBill.Taylor@Sun.COM /* ARGSUSED */
25139517SBill.Taylor@Sun.COM static int
hermon_rsrc_srqhdl_constructor(void * srq,void * priv,int flags)25149517SBill.Taylor@Sun.COM hermon_rsrc_srqhdl_constructor(void *srq, void *priv, int flags)
25159517SBill.Taylor@Sun.COM {
25169517SBill.Taylor@Sun.COM hermon_srqhdl_t srqhdl;
25179517SBill.Taylor@Sun.COM hermon_state_t *state;
25189517SBill.Taylor@Sun.COM
25199517SBill.Taylor@Sun.COM srqhdl = (hermon_srqhdl_t)srq;
25209517SBill.Taylor@Sun.COM state = (hermon_state_t *)priv;
25219517SBill.Taylor@Sun.COM
25229517SBill.Taylor@Sun.COM mutex_init(&srqhdl->srq_lock, NULL, MUTEX_DRIVER,
25239517SBill.Taylor@Sun.COM DDI_INTR_PRI(state->hs_intrmsi_pri));
25249517SBill.Taylor@Sun.COM
25259517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
25269517SBill.Taylor@Sun.COM }
25279517SBill.Taylor@Sun.COM
25289517SBill.Taylor@Sun.COM
25299517SBill.Taylor@Sun.COM /*
25309517SBill.Taylor@Sun.COM * hermon_rsrc_srqhdl_destructor()
25319517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
25329517SBill.Taylor@Sun.COM */
25339517SBill.Taylor@Sun.COM /* ARGSUSED */
25349517SBill.Taylor@Sun.COM static void
hermon_rsrc_srqhdl_destructor(void * srq,void * priv)25359517SBill.Taylor@Sun.COM hermon_rsrc_srqhdl_destructor(void *srq, void *priv)
25369517SBill.Taylor@Sun.COM {
25379517SBill.Taylor@Sun.COM hermon_srqhdl_t srqhdl;
25389517SBill.Taylor@Sun.COM
25399517SBill.Taylor@Sun.COM srqhdl = (hermon_srqhdl_t)srq;
25409517SBill.Taylor@Sun.COM
25419517SBill.Taylor@Sun.COM mutex_destroy(&srqhdl->srq_lock);
25429517SBill.Taylor@Sun.COM }
25439517SBill.Taylor@Sun.COM
25449517SBill.Taylor@Sun.COM
25459517SBill.Taylor@Sun.COM /*
25469517SBill.Taylor@Sun.COM * hermon_rsrc_refcnt_constructor()
25479517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
25489517SBill.Taylor@Sun.COM */
25499517SBill.Taylor@Sun.COM /* ARGSUSED */
25509517SBill.Taylor@Sun.COM static int
hermon_rsrc_refcnt_constructor(void * rc,void * priv,int flags)25519517SBill.Taylor@Sun.COM hermon_rsrc_refcnt_constructor(void *rc, void *priv, int flags)
25529517SBill.Taylor@Sun.COM {
25539517SBill.Taylor@Sun.COM hermon_sw_refcnt_t *refcnt;
25549517SBill.Taylor@Sun.COM hermon_state_t *state;
25559517SBill.Taylor@Sun.COM
25569517SBill.Taylor@Sun.COM refcnt = (hermon_sw_refcnt_t *)rc;
25579517SBill.Taylor@Sun.COM state = (hermon_state_t *)priv;
25589517SBill.Taylor@Sun.COM
25599517SBill.Taylor@Sun.COM mutex_init(&refcnt->swrc_lock, NULL, MUTEX_DRIVER,
25609517SBill.Taylor@Sun.COM DDI_INTR_PRI(state->hs_intrmsi_pri));
25619517SBill.Taylor@Sun.COM
25629517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
25639517SBill.Taylor@Sun.COM }
25649517SBill.Taylor@Sun.COM
25659517SBill.Taylor@Sun.COM
25669517SBill.Taylor@Sun.COM /*
25679517SBill.Taylor@Sun.COM * hermon_rsrc_refcnt_destructor()
25689517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
25699517SBill.Taylor@Sun.COM */
25709517SBill.Taylor@Sun.COM /* ARGSUSED */
25719517SBill.Taylor@Sun.COM static void
hermon_rsrc_refcnt_destructor(void * rc,void * priv)25729517SBill.Taylor@Sun.COM hermon_rsrc_refcnt_destructor(void *rc, void *priv)
25739517SBill.Taylor@Sun.COM {
25749517SBill.Taylor@Sun.COM hermon_sw_refcnt_t *refcnt;
25759517SBill.Taylor@Sun.COM
25769517SBill.Taylor@Sun.COM refcnt = (hermon_sw_refcnt_t *)rc;
25779517SBill.Taylor@Sun.COM
25789517SBill.Taylor@Sun.COM mutex_destroy(&refcnt->swrc_lock);
25799517SBill.Taylor@Sun.COM }
25809517SBill.Taylor@Sun.COM
25819517SBill.Taylor@Sun.COM
25829517SBill.Taylor@Sun.COM /*
25839517SBill.Taylor@Sun.COM * hermon_rsrc_ahhdl_constructor()
25849517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
25859517SBill.Taylor@Sun.COM */
25869517SBill.Taylor@Sun.COM /* ARGSUSED */
25879517SBill.Taylor@Sun.COM static int
hermon_rsrc_ahhdl_constructor(void * ah,void * priv,int flags)25889517SBill.Taylor@Sun.COM hermon_rsrc_ahhdl_constructor(void *ah, void *priv, int flags)
25899517SBill.Taylor@Sun.COM {
25909517SBill.Taylor@Sun.COM hermon_ahhdl_t ahhdl;
25919517SBill.Taylor@Sun.COM hermon_state_t *state;
25929517SBill.Taylor@Sun.COM
25939517SBill.Taylor@Sun.COM ahhdl = (hermon_ahhdl_t)ah;
25949517SBill.Taylor@Sun.COM state = (hermon_state_t *)priv;
25959517SBill.Taylor@Sun.COM
25969517SBill.Taylor@Sun.COM mutex_init(&ahhdl->ah_lock, NULL, MUTEX_DRIVER,
25979517SBill.Taylor@Sun.COM DDI_INTR_PRI(state->hs_intrmsi_pri));
25989517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
25999517SBill.Taylor@Sun.COM }
26009517SBill.Taylor@Sun.COM
26019517SBill.Taylor@Sun.COM
26029517SBill.Taylor@Sun.COM /*
26039517SBill.Taylor@Sun.COM * hermon_rsrc_ahhdl_destructor()
26049517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
26059517SBill.Taylor@Sun.COM */
26069517SBill.Taylor@Sun.COM /* ARGSUSED */
26079517SBill.Taylor@Sun.COM static void
hermon_rsrc_ahhdl_destructor(void * ah,void * priv)26089517SBill.Taylor@Sun.COM hermon_rsrc_ahhdl_destructor(void *ah, void *priv)
26099517SBill.Taylor@Sun.COM {
26109517SBill.Taylor@Sun.COM hermon_ahhdl_t ahhdl;
26119517SBill.Taylor@Sun.COM
26129517SBill.Taylor@Sun.COM ahhdl = (hermon_ahhdl_t)ah;
26139517SBill.Taylor@Sun.COM
26149517SBill.Taylor@Sun.COM mutex_destroy(&ahhdl->ah_lock);
26159517SBill.Taylor@Sun.COM }
26169517SBill.Taylor@Sun.COM
26179517SBill.Taylor@Sun.COM
26189517SBill.Taylor@Sun.COM /*
26199517SBill.Taylor@Sun.COM * hermon_rsrc_mrhdl_constructor()
26209517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
26219517SBill.Taylor@Sun.COM */
26229517SBill.Taylor@Sun.COM /* ARGSUSED */
26239517SBill.Taylor@Sun.COM static int
hermon_rsrc_mrhdl_constructor(void * mr,void * priv,int flags)26249517SBill.Taylor@Sun.COM hermon_rsrc_mrhdl_constructor(void *mr, void *priv, int flags)
26259517SBill.Taylor@Sun.COM {
26269517SBill.Taylor@Sun.COM hermon_mrhdl_t mrhdl;
26279517SBill.Taylor@Sun.COM hermon_state_t *state;
26289517SBill.Taylor@Sun.COM
26299517SBill.Taylor@Sun.COM mrhdl = (hermon_mrhdl_t)mr;
26309517SBill.Taylor@Sun.COM state = (hermon_state_t *)priv;
26319517SBill.Taylor@Sun.COM
26329517SBill.Taylor@Sun.COM mutex_init(&mrhdl->mr_lock, NULL, MUTEX_DRIVER,
26339517SBill.Taylor@Sun.COM DDI_INTR_PRI(state->hs_intrmsi_pri));
26349517SBill.Taylor@Sun.COM
26359517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
26369517SBill.Taylor@Sun.COM }
26379517SBill.Taylor@Sun.COM
26389517SBill.Taylor@Sun.COM
26399517SBill.Taylor@Sun.COM /*
26409517SBill.Taylor@Sun.COM * hermon_rsrc_mrhdl_destructor()
26419517SBill.Taylor@Sun.COM * Context: Can be called from interrupt or base context.
26429517SBill.Taylor@Sun.COM */
26439517SBill.Taylor@Sun.COM /* ARGSUSED */
26449517SBill.Taylor@Sun.COM static void
hermon_rsrc_mrhdl_destructor(void * mr,void * priv)26459517SBill.Taylor@Sun.COM hermon_rsrc_mrhdl_destructor(void *mr, void *priv)
26469517SBill.Taylor@Sun.COM {
26479517SBill.Taylor@Sun.COM hermon_mrhdl_t mrhdl;
26489517SBill.Taylor@Sun.COM
26499517SBill.Taylor@Sun.COM mrhdl = (hermon_mrhdl_t)mr;
26509517SBill.Taylor@Sun.COM
26519517SBill.Taylor@Sun.COM mutex_destroy(&mrhdl->mr_lock);
26529517SBill.Taylor@Sun.COM }
26539517SBill.Taylor@Sun.COM
26549517SBill.Taylor@Sun.COM
26559517SBill.Taylor@Sun.COM /*
26569517SBill.Taylor@Sun.COM * hermon_rsrc_mcg_entry_get_size()
26579517SBill.Taylor@Sun.COM */
26589517SBill.Taylor@Sun.COM static int
hermon_rsrc_mcg_entry_get_size(hermon_state_t * state,uint_t * mcg_size_shift)26599517SBill.Taylor@Sun.COM hermon_rsrc_mcg_entry_get_size(hermon_state_t *state, uint_t *mcg_size_shift)
26609517SBill.Taylor@Sun.COM {
26619517SBill.Taylor@Sun.COM uint_t num_qp_per_mcg, max_qp_per_mcg, log2;
26629517SBill.Taylor@Sun.COM
26639517SBill.Taylor@Sun.COM /*
26649517SBill.Taylor@Sun.COM * Round the configured number of QP per MCG to next larger
26659517SBill.Taylor@Sun.COM * power-of-2 size and update.
26669517SBill.Taylor@Sun.COM */
26679517SBill.Taylor@Sun.COM num_qp_per_mcg = state->hs_cfg_profile->cp_num_qp_per_mcg + 8;
26689517SBill.Taylor@Sun.COM log2 = highbit(num_qp_per_mcg);
26699517SBill.Taylor@Sun.COM if ((num_qp_per_mcg & (num_qp_per_mcg - 1)) == 0) {
26709517SBill.Taylor@Sun.COM log2 = log2 - 1;
26719517SBill.Taylor@Sun.COM }
26729517SBill.Taylor@Sun.COM state->hs_cfg_profile->cp_num_qp_per_mcg = (1 << log2) - 8;
26739517SBill.Taylor@Sun.COM
26749517SBill.Taylor@Sun.COM /* Now make sure number of QP per MCG makes sense */
26759517SBill.Taylor@Sun.COM num_qp_per_mcg = state->hs_cfg_profile->cp_num_qp_per_mcg;
26769517SBill.Taylor@Sun.COM max_qp_per_mcg = (1 << state->hs_devlim.log_max_qp_mcg);
26779517SBill.Taylor@Sun.COM if (num_qp_per_mcg > max_qp_per_mcg) {
26789517SBill.Taylor@Sun.COM return (DDI_FAILURE);
26799517SBill.Taylor@Sun.COM }
26809517SBill.Taylor@Sun.COM
26819517SBill.Taylor@Sun.COM /* Return the (shift) size of an individual MCG HW entry */
26829517SBill.Taylor@Sun.COM *mcg_size_shift = log2 + 2;
26839517SBill.Taylor@Sun.COM
26849517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
26859517SBill.Taylor@Sun.COM }
2686