19e39c5baSBill Taylor /*
29e39c5baSBill Taylor * CDDL HEADER START
39e39c5baSBill Taylor *
49e39c5baSBill Taylor * The contents of this file are subject to the terms of the
59e39c5baSBill Taylor * Common Development and Distribution License (the "License").
69e39c5baSBill Taylor * You may not use this file except in compliance with the License.
79e39c5baSBill Taylor *
89e39c5baSBill Taylor * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99e39c5baSBill Taylor * or http://www.opensolaris.org/os/licensing.
109e39c5baSBill Taylor * See the License for the specific language governing permissions
119e39c5baSBill Taylor * and limitations under the License.
129e39c5baSBill Taylor *
139e39c5baSBill Taylor * When distributing Covered Code, include this CDDL HEADER in each
149e39c5baSBill Taylor * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159e39c5baSBill Taylor * If applicable, add the following below this CDDL HEADER, with the
169e39c5baSBill Taylor * fields enclosed by brackets "[]" replaced with your own identifying
179e39c5baSBill Taylor * information: Portions Copyright [yyyy] [name of copyright owner]
189e39c5baSBill Taylor *
199e39c5baSBill Taylor * CDDL HEADER END
209e39c5baSBill Taylor */
219e39c5baSBill Taylor
229e39c5baSBill Taylor /*
239e39c5baSBill Taylor * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
249e39c5baSBill Taylor * Use is subject to license terms.
259e39c5baSBill Taylor */
269e39c5baSBill Taylor
279e39c5baSBill Taylor /*
289e39c5baSBill Taylor * tavor_rsrc.c
299e39c5baSBill Taylor * Tavor Resource Management Routines
309e39c5baSBill Taylor *
319e39c5baSBill Taylor * Implements all the routines necessary for setup, teardown, and
329e39c5baSBill Taylor * alloc/free of all Tavor resources, including those that are managed
339e39c5baSBill Taylor * by Tavor hardware or which live in Tavor's direct attached DDR memory.
349e39c5baSBill Taylor */
359e39c5baSBill Taylor
36de710d24SJosef 'Jeff' Sipek #include <sys/sysmacros.h>
379e39c5baSBill Taylor #include <sys/types.h>
389e39c5baSBill Taylor #include <sys/conf.h>
399e39c5baSBill Taylor #include <sys/ddi.h>
409e39c5baSBill Taylor #include <sys/sunddi.h>
419e39c5baSBill Taylor #include <sys/modctl.h>
429e39c5baSBill Taylor #include <sys/vmem.h>
439e39c5baSBill Taylor #include <sys/bitmap.h>
449e39c5baSBill Taylor
459e39c5baSBill Taylor #include <sys/ib/adapters/tavor/tavor.h>
469e39c5baSBill Taylor
479e39c5baSBill Taylor /*
489e39c5baSBill Taylor * The following routines are used for initializing and destroying
499e39c5baSBill Taylor * the resource pools used by the Tavor resource allocation routines.
509e39c5baSBill Taylor * They consist of four classes of object:
519e39c5baSBill Taylor *
529e39c5baSBill Taylor * Mailboxes: The "In" and "Out" mailbox types are used by the Tavor
539e39c5baSBill Taylor * command interface routines. Mailboxes are used to pass information
549e39c5baSBill Taylor * back and forth to the Tavor firmware. Either type of mailbox may
559e39c5baSBill Taylor * be allocated from Tavor's direct attached DDR memory or from system
569e39c5baSBill Taylor * memory (although currently all "In" mailboxes are in DDR and all "out"
579e39c5baSBill Taylor * mailboxes come from system memory.
589e39c5baSBill Taylor *
599e39c5baSBill Taylor * HW entry objects: These objects represent resources required by the Tavor
609e39c5baSBill Taylor * hardware. These objects include things like Queue Pair contexts (QPC),
619e39c5baSBill Taylor * Completion Queue contexts (CQC), Event Queue contexts (EQC), RDB (for
629e39c5baSBill Taylor * supporting RDMA Read/Atomic), Multicast Group entries (MCG), Memory
639e39c5baSBill Taylor * Protection Table entries (MPT), Memory Translation Table entries (MTT).
649e39c5baSBill Taylor *
659e39c5baSBill Taylor * What these objects all have in common is that they are each required
669e39c5baSBill Taylor * to come from DDR memory, they are always allocated from tables, and
679e39c5baSBill Taylor * they are not to be directly accessed (read or written) by driver
689e39c5baSBill Taylor * software.
699e39c5baSBill Taylor * One notable exceptions to this rule are the Extended QP contexts (EQPC),
709e39c5baSBill Taylor * and the UAR scratch area (UAR_SCR), both of which are not directly
719e39c5baSBill Taylor * accessible through the Tavor resource allocation routines, but both
729e39c5baSBill Taylor * of which are also required to reside in DDR memory and are not to be
739e39c5baSBill Taylor * manipulated by driver software (they are privately managed by Tavor
749e39c5baSBill Taylor * hardware).
759e39c5baSBill Taylor * The other notable exceptions are the UAR pages (UAR_PG) which are
769e39c5baSBill Taylor * allocated from the UAR address space rather than DDR, and the UD
779e39c5baSBill Taylor * address vectors (UDAV) which are similar to the common object types
789e39c5baSBill Taylor * with the major difference being that UDAVs _are_ directly read and
799e39c5baSBill Taylor * written by driver software.
809e39c5baSBill Taylor *
819e39c5baSBill Taylor * SW handle objects: These objects represent resources required by Tavor
829e39c5baSBill Taylor * driver software. They are primarily software tracking structures,
839e39c5baSBill Taylor * which are allocated from system memory (using kmem_cache). Several of
849e39c5baSBill Taylor * the objects have both a "constructor" and "destructor" method
859e39c5baSBill Taylor * associated with them (see below).
869e39c5baSBill Taylor *
879e39c5baSBill Taylor * Protection Domain (PD) handle objects: These objects are very much like
889e39c5baSBill Taylor * a SW handle object with the notable difference that all PD handle
899e39c5baSBill Taylor * objects have an actual Protection Domain number (PD) associated with
909e39c5baSBill Taylor * them (and the PD number is allocated/managed through a separate
919e39c5baSBill Taylor * vmem_arena specifically set aside for this purpose.
929e39c5baSBill Taylor */
939e39c5baSBill Taylor
949e39c5baSBill Taylor static int tavor_rsrc_mbox_init(tavor_state_t *state,
959e39c5baSBill Taylor tavor_rsrc_mbox_info_t *info);
969e39c5baSBill Taylor static void tavor_rsrc_mbox_fini(tavor_state_t *state,
979e39c5baSBill Taylor tavor_rsrc_mbox_info_t *info);
989e39c5baSBill Taylor
999e39c5baSBill Taylor static int tavor_rsrc_hw_entries_init(tavor_state_t *state,
1009e39c5baSBill Taylor tavor_rsrc_hw_entry_info_t *info);
1019e39c5baSBill Taylor static void tavor_rsrc_hw_entries_fini(tavor_state_t *state,
1029e39c5baSBill Taylor tavor_rsrc_hw_entry_info_t *info);
1039e39c5baSBill Taylor
1049e39c5baSBill Taylor static int tavor_rsrc_sw_handles_init(tavor_state_t *state,
1059e39c5baSBill Taylor tavor_rsrc_sw_hdl_info_t *info);
1069e39c5baSBill Taylor static void tavor_rsrc_sw_handles_fini(tavor_state_t *state,
1079e39c5baSBill Taylor tavor_rsrc_sw_hdl_info_t *info);
1089e39c5baSBill Taylor
1099e39c5baSBill Taylor static int tavor_rsrc_pd_handles_init(tavor_state_t *state,
1109e39c5baSBill Taylor tavor_rsrc_sw_hdl_info_t *info);
1119e39c5baSBill Taylor static void tavor_rsrc_pd_handles_fini(tavor_state_t *state,
1129e39c5baSBill Taylor tavor_rsrc_sw_hdl_info_t *info);
1139e39c5baSBill Taylor
1149e39c5baSBill Taylor /*
1159e39c5baSBill Taylor * The following routines are used for allocating and freeing the specific
1169e39c5baSBill Taylor * types of objects described above from their associated resource pools.
1179e39c5baSBill Taylor */
1189e39c5baSBill Taylor static int tavor_rsrc_mbox_alloc(tavor_rsrc_pool_info_t *pool_info,
1199e39c5baSBill Taylor uint_t num, tavor_rsrc_t *hdl);
1209e39c5baSBill Taylor static void tavor_rsrc_mbox_free(tavor_rsrc_pool_info_t *pool_info,
1219e39c5baSBill Taylor tavor_rsrc_t *hdl);
1229e39c5baSBill Taylor
1239e39c5baSBill Taylor static int tavor_rsrc_hw_entry_alloc(tavor_rsrc_pool_info_t *pool_info,
1249e39c5baSBill Taylor uint_t num, uint_t num_align, ddi_acc_handle_t acc_handle,
1259e39c5baSBill Taylor uint_t sleepflag, tavor_rsrc_t *hdl);
1269e39c5baSBill Taylor static void tavor_rsrc_hw_entry_free(tavor_rsrc_pool_info_t *pool_info,
1279e39c5baSBill Taylor tavor_rsrc_t *hdl);
1289e39c5baSBill Taylor
1299e39c5baSBill Taylor static int tavor_rsrc_swhdl_alloc(tavor_rsrc_pool_info_t *pool_info,
1309e39c5baSBill Taylor uint_t sleepflag, tavor_rsrc_t *hdl);
1319e39c5baSBill Taylor static void tavor_rsrc_swhdl_free(tavor_rsrc_pool_info_t *pool_info,
1329e39c5baSBill Taylor tavor_rsrc_t *hdl);
1339e39c5baSBill Taylor
1349e39c5baSBill Taylor static int tavor_rsrc_pdhdl_alloc(tavor_rsrc_pool_info_t *pool_info,
1359e39c5baSBill Taylor uint_t sleepflag, tavor_rsrc_t *hdl);
1369e39c5baSBill Taylor static void tavor_rsrc_pdhdl_free(tavor_rsrc_pool_info_t *pool_info,
1379e39c5baSBill Taylor tavor_rsrc_t *hdl);
1389e39c5baSBill Taylor
1399e39c5baSBill Taylor /*
1409e39c5baSBill Taylor * The following routines are the constructors and destructors for several
1419e39c5baSBill Taylor * of the SW handle type objects. For certain types of SW handles objects
1429e39c5baSBill Taylor * (all of which are implemented using kmem_cache), we need to do some
1439e39c5baSBill Taylor * special field initialization (specifically, mutex_init/destroy). These
1449e39c5baSBill Taylor * routines enable that init and teardown.
1459e39c5baSBill Taylor */
1469e39c5baSBill Taylor static int tavor_rsrc_pdhdl_constructor(void *pd, void *priv, int flags);
1479e39c5baSBill Taylor static void tavor_rsrc_pdhdl_destructor(void *pd, void *state);
1489e39c5baSBill Taylor static int tavor_rsrc_cqhdl_constructor(void *cq, void *priv, int flags);
1499e39c5baSBill Taylor static void tavor_rsrc_cqhdl_destructor(void *cq, void *state);
1509e39c5baSBill Taylor static int tavor_rsrc_qphdl_constructor(void *cq, void *priv, int flags);
1519e39c5baSBill Taylor static void tavor_rsrc_qphdl_destructor(void *cq, void *state);
1529e39c5baSBill Taylor static int tavor_rsrc_srqhdl_constructor(void *srq, void *priv, int flags);
1539e39c5baSBill Taylor static void tavor_rsrc_srqhdl_destructor(void *srq, void *state);
1549e39c5baSBill Taylor static int tavor_rsrc_refcnt_constructor(void *rc, void *priv, int flags);
1559e39c5baSBill Taylor static void tavor_rsrc_refcnt_destructor(void *rc, void *state);
1569e39c5baSBill Taylor static int tavor_rsrc_ahhdl_constructor(void *ah, void *priv, int flags);
1579e39c5baSBill Taylor static void tavor_rsrc_ahhdl_destructor(void *ah, void *state);
1589e39c5baSBill Taylor static int tavor_rsrc_mrhdl_constructor(void *mr, void *priv, int flags);
1599e39c5baSBill Taylor static void tavor_rsrc_mrhdl_destructor(void *mr, void *state);
1609e39c5baSBill Taylor
1619e39c5baSBill Taylor /*
1629e39c5baSBill Taylor * Special routine to calculate and return the size of a MCG object based
1639e39c5baSBill Taylor * on current driver configuration (specifically, the number of QP per MCG
1649e39c5baSBill Taylor * that has been configured.
1659e39c5baSBill Taylor */
1669e39c5baSBill Taylor static int tavor_rsrc_mcg_entry_get_size(tavor_state_t *state,
1679e39c5baSBill Taylor uint_t *mcg_size_shift);
1689e39c5baSBill Taylor
1699e39c5baSBill Taylor
1709e39c5baSBill Taylor /*
1719e39c5baSBill Taylor * tavor_rsrc_alloc()
1729e39c5baSBill Taylor *
1739e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
1749e39c5baSBill Taylor * The "sleepflag" parameter is used by all object allocators to
1759e39c5baSBill Taylor * determine whether to SLEEP for resources or not.
1769e39c5baSBill Taylor */
1779e39c5baSBill Taylor int
tavor_rsrc_alloc(tavor_state_t * state,tavor_rsrc_type_t rsrc,uint_t num,uint_t sleepflag,tavor_rsrc_t ** hdl)1789e39c5baSBill Taylor tavor_rsrc_alloc(tavor_state_t *state, tavor_rsrc_type_t rsrc, uint_t num,
1799e39c5baSBill Taylor uint_t sleepflag, tavor_rsrc_t **hdl)
1809e39c5baSBill Taylor {
1819e39c5baSBill Taylor tavor_rsrc_pool_info_t *rsrc_pool;
1829e39c5baSBill Taylor tavor_rsrc_t *tmp_rsrc_hdl;
1839e39c5baSBill Taylor int flag, status = DDI_FAILURE;
1849e39c5baSBill Taylor
1859e39c5baSBill Taylor ASSERT(state != NULL);
1869e39c5baSBill Taylor ASSERT(hdl != NULL);
1879e39c5baSBill Taylor
1889e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[rsrc];
1899e39c5baSBill Taylor ASSERT(rsrc_pool != NULL);
1909e39c5baSBill Taylor
1919e39c5baSBill Taylor /*
1929e39c5baSBill Taylor * Allocate space for the object used to track the resource handle
1939e39c5baSBill Taylor */
1949e39c5baSBill Taylor flag = (sleepflag == TAVOR_SLEEP) ? KM_SLEEP : KM_NOSLEEP;
1959e39c5baSBill Taylor tmp_rsrc_hdl = (tavor_rsrc_t *)kmem_cache_alloc(state->ts_rsrc_cache,
1969e39c5baSBill Taylor flag);
1979e39c5baSBill Taylor if (tmp_rsrc_hdl == NULL) {
1989e39c5baSBill Taylor return (DDI_FAILURE);
1999e39c5baSBill Taylor }
2009e39c5baSBill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*tmp_rsrc_hdl))
2019e39c5baSBill Taylor
2029e39c5baSBill Taylor /*
2039e39c5baSBill Taylor * Set rsrc_hdl type. This is later used by the tavor_rsrc_free call
2049e39c5baSBill Taylor * to know what type of resource is being freed.
2059e39c5baSBill Taylor */
2069e39c5baSBill Taylor tmp_rsrc_hdl->rsrc_type = rsrc;
2079e39c5baSBill Taylor
2089e39c5baSBill Taylor /*
2099e39c5baSBill Taylor * Depending on resource type, call the appropriate alloc routine
2109e39c5baSBill Taylor */
2119e39c5baSBill Taylor switch (rsrc_pool->rsrc_type) {
2129e39c5baSBill Taylor case TAVOR_IN_MBOX:
2139e39c5baSBill Taylor case TAVOR_OUT_MBOX:
2149e39c5baSBill Taylor case TAVOR_INTR_IN_MBOX:
2159e39c5baSBill Taylor case TAVOR_INTR_OUT_MBOX:
2169e39c5baSBill Taylor status = tavor_rsrc_mbox_alloc(rsrc_pool, num, tmp_rsrc_hdl);
2179e39c5baSBill Taylor break;
2189e39c5baSBill Taylor
2199e39c5baSBill Taylor case TAVOR_QPC:
2209e39c5baSBill Taylor case TAVOR_CQC:
2219e39c5baSBill Taylor case TAVOR_SRQC:
2229e39c5baSBill Taylor case TAVOR_EQC:
2239e39c5baSBill Taylor case TAVOR_RDB:
2249e39c5baSBill Taylor /*
2259e39c5baSBill Taylor * Because these objects are NOT accessed by Tavor driver
2269e39c5baSBill Taylor * software, we set the acc_handle parameter to zero. But
2279e39c5baSBill Taylor * if they are allocated in multiples, we specify here that
2289e39c5baSBill Taylor * they must be aligned on a more restrictive boundary.
2299e39c5baSBill Taylor */
2309e39c5baSBill Taylor status = tavor_rsrc_hw_entry_alloc(rsrc_pool, num, num, 0,
2319e39c5baSBill Taylor sleepflag, tmp_rsrc_hdl);
2329e39c5baSBill Taylor break;
2339e39c5baSBill Taylor
2349e39c5baSBill Taylor case TAVOR_MPT:
2359e39c5baSBill Taylor /*
2369e39c5baSBill Taylor * Because these MPT objects are sometimes accessed by Tavor
2379e39c5baSBill Taylor * driver software (FMR), we set the acc_handle parameter. But
2389e39c5baSBill Taylor * if they are allocated in multiples, we specify here that
2399e39c5baSBill Taylor * they must be aligned on a more restrictive boundary.
2409e39c5baSBill Taylor */
2419e39c5baSBill Taylor status = tavor_rsrc_hw_entry_alloc(rsrc_pool, num, num,
2429e39c5baSBill Taylor state->ts_reg_ddrhdl, sleepflag, tmp_rsrc_hdl);
2439e39c5baSBill Taylor break;
2449e39c5baSBill Taylor
2459e39c5baSBill Taylor case TAVOR_MCG:
2469e39c5baSBill Taylor /*
2479e39c5baSBill Taylor * Tavor MCG entries are also NOT accessed by Tavor driver
2489e39c5baSBill Taylor * software, but because MCG entries do not have the same
2499e39c5baSBill Taylor * alignnment restrictions we loosen the constraint here.
2509e39c5baSBill Taylor */
2519e39c5baSBill Taylor status = tavor_rsrc_hw_entry_alloc(rsrc_pool, num, 1, 0,
2529e39c5baSBill Taylor sleepflag, tmp_rsrc_hdl);
2539e39c5baSBill Taylor break;
2549e39c5baSBill Taylor
2559e39c5baSBill Taylor case TAVOR_MTT:
2569e39c5baSBill Taylor case TAVOR_UDAV:
2579e39c5baSBill Taylor /*
2589e39c5baSBill Taylor * Because MTT segments are among the few HW resources that
2599e39c5baSBill Taylor * may be allocated in odd numbers, we specify a less
2609e39c5baSBill Taylor * restrictive alignment than for the above resources.
2619e39c5baSBill Taylor *
2629e39c5baSBill Taylor * Also because both UDAV and MTT segment objects are read
2639e39c5baSBill Taylor * and/or written by Tavor driver software, we set the
2649e39c5baSBill Taylor * acc_handle parameter to point to the ddi_acc_handle_t for
2659e39c5baSBill Taylor * the Tavor DDR memory.
2669e39c5baSBill Taylor */
2679e39c5baSBill Taylor status = tavor_rsrc_hw_entry_alloc(rsrc_pool, num, 1,
2689e39c5baSBill Taylor state->ts_reg_ddrhdl, sleepflag, tmp_rsrc_hdl);
2699e39c5baSBill Taylor break;
2709e39c5baSBill Taylor
2719e39c5baSBill Taylor case TAVOR_UARPG:
2729e39c5baSBill Taylor /*
2739e39c5baSBill Taylor * Because UAR pages are written by Tavor driver software (for
2749e39c5baSBill Taylor * doorbells), we set the acc_handle parameter to point to
2759e39c5baSBill Taylor * the ddi_acc_handle_t for the Tavor UAR memory.
2769e39c5baSBill Taylor */
2779e39c5baSBill Taylor status = tavor_rsrc_hw_entry_alloc(rsrc_pool, num, 1,
2789e39c5baSBill Taylor state->ts_reg_uarhdl, sleepflag, tmp_rsrc_hdl);
2799e39c5baSBill Taylor break;
2809e39c5baSBill Taylor
2819e39c5baSBill Taylor case TAVOR_MRHDL:
2829e39c5baSBill Taylor case TAVOR_EQHDL:
2839e39c5baSBill Taylor case TAVOR_CQHDL:
2849e39c5baSBill Taylor case TAVOR_SRQHDL:
2859e39c5baSBill Taylor case TAVOR_AHHDL:
2869e39c5baSBill Taylor case TAVOR_QPHDL:
2879e39c5baSBill Taylor case TAVOR_REFCNT:
2889e39c5baSBill Taylor status = tavor_rsrc_swhdl_alloc(rsrc_pool, sleepflag,
2899e39c5baSBill Taylor tmp_rsrc_hdl);
2909e39c5baSBill Taylor break;
2919e39c5baSBill Taylor
2929e39c5baSBill Taylor case TAVOR_PDHDL:
2939e39c5baSBill Taylor status = tavor_rsrc_pdhdl_alloc(rsrc_pool, sleepflag,
2949e39c5baSBill Taylor tmp_rsrc_hdl);
2959e39c5baSBill Taylor break;
2969e39c5baSBill Taylor
2979e39c5baSBill Taylor default:
2989e39c5baSBill Taylor TAVOR_WARNING(state, "unexpected resource type in alloc");
2999e39c5baSBill Taylor break;
3009e39c5baSBill Taylor }
3019e39c5baSBill Taylor
3029e39c5baSBill Taylor /*
3039e39c5baSBill Taylor * If the resource allocation failed, then free the special resource
3049e39c5baSBill Taylor * tracking structure and return failure. Otherwise return the
3059e39c5baSBill Taylor * handle for the resource tracking structure.
3069e39c5baSBill Taylor */
3079e39c5baSBill Taylor if (status != DDI_SUCCESS) {
3089e39c5baSBill Taylor kmem_cache_free(state->ts_rsrc_cache, tmp_rsrc_hdl);
3099e39c5baSBill Taylor tmp_rsrc_hdl = NULL;
3109e39c5baSBill Taylor return (DDI_FAILURE);
3119e39c5baSBill Taylor } else {
3129e39c5baSBill Taylor *hdl = tmp_rsrc_hdl;
3139e39c5baSBill Taylor return (DDI_SUCCESS);
3149e39c5baSBill Taylor }
3159e39c5baSBill Taylor }
3169e39c5baSBill Taylor
3179e39c5baSBill Taylor
3189e39c5baSBill Taylor /*
3199e39c5baSBill Taylor * tavor_rsrc_free()
3209e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
3219e39c5baSBill Taylor */
3229e39c5baSBill Taylor void
tavor_rsrc_free(tavor_state_t * state,tavor_rsrc_t ** hdl)3239e39c5baSBill Taylor tavor_rsrc_free(tavor_state_t *state, tavor_rsrc_t **hdl)
3249e39c5baSBill Taylor {
3259e39c5baSBill Taylor tavor_rsrc_pool_info_t *rsrc_pool;
3269e39c5baSBill Taylor
3279e39c5baSBill Taylor ASSERT(state != NULL);
3289e39c5baSBill Taylor ASSERT(hdl != NULL);
3299e39c5baSBill Taylor
3309e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[(*hdl)->rsrc_type];
3319e39c5baSBill Taylor ASSERT(rsrc_pool != NULL);
3329e39c5baSBill Taylor
3339e39c5baSBill Taylor /*
3349e39c5baSBill Taylor * Depending on resource type, call the appropriate free routine
3359e39c5baSBill Taylor */
3369e39c5baSBill Taylor switch (rsrc_pool->rsrc_type) {
3379e39c5baSBill Taylor case TAVOR_IN_MBOX:
3389e39c5baSBill Taylor case TAVOR_OUT_MBOX:
3399e39c5baSBill Taylor case TAVOR_INTR_IN_MBOX:
3409e39c5baSBill Taylor case TAVOR_INTR_OUT_MBOX:
3419e39c5baSBill Taylor tavor_rsrc_mbox_free(rsrc_pool, *hdl);
3429e39c5baSBill Taylor break;
3439e39c5baSBill Taylor
3449e39c5baSBill Taylor case TAVOR_QPC:
3459e39c5baSBill Taylor case TAVOR_CQC:
3469e39c5baSBill Taylor case TAVOR_SRQC:
3479e39c5baSBill Taylor case TAVOR_EQC:
3489e39c5baSBill Taylor case TAVOR_RDB:
3499e39c5baSBill Taylor case TAVOR_MCG:
3509e39c5baSBill Taylor case TAVOR_MPT:
3519e39c5baSBill Taylor case TAVOR_MTT:
3529e39c5baSBill Taylor case TAVOR_UDAV:
3539e39c5baSBill Taylor case TAVOR_UARPG:
3549e39c5baSBill Taylor tavor_rsrc_hw_entry_free(rsrc_pool, *hdl);
3559e39c5baSBill Taylor break;
3569e39c5baSBill Taylor
3579e39c5baSBill Taylor case TAVOR_MRHDL:
3589e39c5baSBill Taylor case TAVOR_EQHDL:
3599e39c5baSBill Taylor case TAVOR_CQHDL:
3609e39c5baSBill Taylor case TAVOR_SRQHDL:
3619e39c5baSBill Taylor case TAVOR_AHHDL:
3629e39c5baSBill Taylor case TAVOR_QPHDL:
3639e39c5baSBill Taylor case TAVOR_REFCNT:
3649e39c5baSBill Taylor tavor_rsrc_swhdl_free(rsrc_pool, *hdl);
3659e39c5baSBill Taylor break;
3669e39c5baSBill Taylor
3679e39c5baSBill Taylor case TAVOR_PDHDL:
3689e39c5baSBill Taylor tavor_rsrc_pdhdl_free(rsrc_pool, *hdl);
3699e39c5baSBill Taylor break;
3709e39c5baSBill Taylor
3719e39c5baSBill Taylor default:
3729e39c5baSBill Taylor TAVOR_WARNING(state, "unexpected resource type in free");
3739e39c5baSBill Taylor break;
3749e39c5baSBill Taylor }
3759e39c5baSBill Taylor
3769e39c5baSBill Taylor /*
3779e39c5baSBill Taylor * Free the special resource tracking structure, set the handle to
3789e39c5baSBill Taylor * NULL, and return.
3799e39c5baSBill Taylor */
3809e39c5baSBill Taylor kmem_cache_free(state->ts_rsrc_cache, *hdl);
3819e39c5baSBill Taylor *hdl = NULL;
3829e39c5baSBill Taylor }
3839e39c5baSBill Taylor
3849e39c5baSBill Taylor
3859e39c5baSBill Taylor /*
3869e39c5baSBill Taylor * tavor_rsrc_init_phase1()
3879e39c5baSBill Taylor *
3889e39c5baSBill Taylor * Completes the first phase of Tavor resource/configuration init.
3899e39c5baSBill Taylor * This involves creating the kmem_cache for the "tavor_rsrc_t"
3909e39c5baSBill Taylor * structs, allocating the space for the resource pool handles,
3919e39c5baSBill Taylor * and setting up the "Out" mailboxes.
3929e39c5baSBill Taylor *
3939e39c5baSBill Taylor * When this function completes, the Tavor driver is ready to
3949e39c5baSBill Taylor * post the following commands which return information only in the
3959e39c5baSBill Taylor * "Out" mailbox: QUERY_DDR, QUERY_FW, QUERY_DEV_LIM, and QUERY_ADAPTER
3969e39c5baSBill Taylor * If any of these commands are to be posted at this time, they must be
3979e39c5baSBill Taylor * done so only when "spinning" (as the outstanding command list and
3989e39c5baSBill Taylor * EQ setup code has not yet run)
3999e39c5baSBill Taylor *
4009e39c5baSBill Taylor * Context: Only called from attach() path context
4019e39c5baSBill Taylor */
4029e39c5baSBill Taylor int
tavor_rsrc_init_phase1(tavor_state_t * state)4039e39c5baSBill Taylor tavor_rsrc_init_phase1(tavor_state_t *state)
4049e39c5baSBill Taylor {
4059e39c5baSBill Taylor tavor_rsrc_pool_info_t *rsrc_pool;
4069e39c5baSBill Taylor tavor_rsrc_mbox_info_t mbox_info;
4079e39c5baSBill Taylor tavor_rsrc_cleanup_level_t cleanup;
4089e39c5baSBill Taylor tavor_cfg_profile_t *cfgprof;
4099e39c5baSBill Taylor uint64_t num, size;
4109e39c5baSBill Taylor int status;
411*2570281cSToomas Soome char *rsrc_name;
4129e39c5baSBill Taylor
4139e39c5baSBill Taylor ASSERT(state != NULL);
4149e39c5baSBill Taylor
4159e39c5baSBill Taylor /* This is where Phase 1 of resource initialization begins */
4169e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL0;
4179e39c5baSBill Taylor
4189e39c5baSBill Taylor /* Build kmem cache name from Tavor instance */
4199e39c5baSBill Taylor rsrc_name = (char *)kmem_zalloc(TAVOR_RSRC_NAME_MAXLEN, KM_SLEEP);
4209e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_RSRC_CACHE);
4219e39c5baSBill Taylor
4229e39c5baSBill Taylor /*
4239e39c5baSBill Taylor * Create the kmem_cache for "tavor_rsrc_t" structures
4249e39c5baSBill Taylor * (kmem_cache_create will SLEEP until successful)
4259e39c5baSBill Taylor */
4269e39c5baSBill Taylor state->ts_rsrc_cache = kmem_cache_create(rsrc_name,
4279e39c5baSBill Taylor sizeof (tavor_rsrc_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
4289e39c5baSBill Taylor
4299e39c5baSBill Taylor /*
4309e39c5baSBill Taylor * Allocate an array of tavor_rsrc_pool_info_t's (used in all
4319e39c5baSBill Taylor * subsequent resource allocations)
4329e39c5baSBill Taylor */
4339e39c5baSBill Taylor state->ts_rsrc_hdl = kmem_zalloc(TAVOR_NUM_RESOURCES *
4349e39c5baSBill Taylor sizeof (tavor_rsrc_pool_info_t), KM_SLEEP);
4359e39c5baSBill Taylor
4369e39c5baSBill Taylor cfgprof = state->ts_cfg_profile;
4379e39c5baSBill Taylor
4389e39c5baSBill Taylor /*
4399e39c5baSBill Taylor * Initialize the resource pool for "Out" mailboxes. Notice that
4409e39c5baSBill Taylor * the number of "Out" mailboxes, their size, and their location
4419e39c5baSBill Taylor * (DDR or system memory) is configurable. By default, however,
4429e39c5baSBill Taylor * all "Out" mailboxes are located in system memory only (because
4439e39c5baSBill Taylor * they are primarily read from and never written to)
4449e39c5baSBill Taylor */
4459e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_outmbox);
4469e39c5baSBill Taylor size = ((uint64_t)1 << cfgprof->cp_log_outmbox_size);
4479e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_OUT_MBOX];
4489e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_OUT_MBOX;
4499e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_SYSMEM;
4509e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (size * num);
4519e39c5baSBill Taylor rsrc_pool->rsrc_shift = cfgprof->cp_log_outmbox_size;
4529e39c5baSBill Taylor rsrc_pool->rsrc_quantum = size;
4539e39c5baSBill Taylor rsrc_pool->rsrc_align = TAVOR_MBOX_ALIGN;
4549e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
4559e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_DDR_OUTMBOX_VMEM);
4569e39c5baSBill Taylor mbox_info.mbi_num = num;
4579e39c5baSBill Taylor mbox_info.mbi_size = size;
4589e39c5baSBill Taylor mbox_info.mbi_rsrcpool = rsrc_pool;
4599e39c5baSBill Taylor mbox_info.mbi_rsrcname = rsrc_name;
4609e39c5baSBill Taylor status = tavor_rsrc_mbox_init(state, &mbox_info);
4619e39c5baSBill Taylor if (status != DDI_SUCCESS) {
4629e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
4639e39c5baSBill Taylor goto rsrcinitp1_fail;
4649e39c5baSBill Taylor }
4659e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL1;
4669e39c5baSBill Taylor
4679e39c5baSBill Taylor /*
4689e39c5baSBill Taylor * Initialize the Tavor "Out" mailbox list. This step actually uses
4699e39c5baSBill Taylor * the tavor_rsrc_alloc() for TAVOR_OUT_MBOX to preallocate the
4709e39c5baSBill Taylor * "Out" mailboxes, bind them for DMA access, and arrange them into
4719e39c5baSBill Taylor * an easily accessed fast-allocation mechanism (see tavor_cmd.c
4729e39c5baSBill Taylor * for more details)
4739e39c5baSBill Taylor */
4749e39c5baSBill Taylor status = tavor_outmbox_list_init(state);
4759e39c5baSBill Taylor if (status != DDI_SUCCESS) {
4769e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
4779e39c5baSBill Taylor goto rsrcinitp1_fail;
4789e39c5baSBill Taylor }
4799e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL2;
4809e39c5baSBill Taylor
4819e39c5baSBill Taylor /*
4829e39c5baSBill Taylor * Initialize the resource pool for interrupt "Out" mailboxes. Notice
4839e39c5baSBill Taylor * that the number of interrupt "Out" mailboxes, their size, and their
4849e39c5baSBill Taylor * location (DDR or system memory) is configurable. By default,
4859e39c5baSBill Taylor * however, all interrupt "Out" mailboxes are located in system memory
4869e39c5baSBill Taylor * only (because they are primarily read from and never written to)
4879e39c5baSBill Taylor */
4889e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_intr_outmbox);
4899e39c5baSBill Taylor size = ((uint64_t)1 << cfgprof->cp_log_outmbox_size);
4909e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_INTR_OUT_MBOX];
4919e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_INTR_OUT_MBOX;
4929e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_SYSMEM;
4939e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (size * num);
4949e39c5baSBill Taylor rsrc_pool->rsrc_shift = cfgprof->cp_log_outmbox_size;
4959e39c5baSBill Taylor rsrc_pool->rsrc_quantum = size;
4969e39c5baSBill Taylor rsrc_pool->rsrc_align = TAVOR_MBOX_ALIGN;
4979e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
4989e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_DDR_INTR_OUTMBOX_VMEM);
4999e39c5baSBill Taylor mbox_info.mbi_num = num;
5009e39c5baSBill Taylor mbox_info.mbi_size = size;
5019e39c5baSBill Taylor mbox_info.mbi_rsrcpool = rsrc_pool;
5029e39c5baSBill Taylor mbox_info.mbi_rsrcname = rsrc_name;
5039e39c5baSBill Taylor status = tavor_rsrc_mbox_init(state, &mbox_info);
5049e39c5baSBill Taylor if (status != DDI_SUCCESS) {
5059e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
5069e39c5baSBill Taylor goto rsrcinitp1_fail;
5079e39c5baSBill Taylor }
5089e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL3;
5099e39c5baSBill Taylor
5109e39c5baSBill Taylor /*
5119e39c5baSBill Taylor * Initialize the Tavor "Out" mailbox list. This step actually uses
5129e39c5baSBill Taylor * the tavor_rsrc_alloc() for TAVOR_OUT_MBOX to preallocate the
5139e39c5baSBill Taylor * "Out" mailboxes, bind them for DMA access, and arrange them into
5149e39c5baSBill Taylor * an easily accessed fast-allocation mechanism (see tavor_cmd.c
5159e39c5baSBill Taylor * for more details)
5169e39c5baSBill Taylor */
5179e39c5baSBill Taylor status = tavor_intr_outmbox_list_init(state);
5189e39c5baSBill Taylor if (status != DDI_SUCCESS) {
5199e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
5209e39c5baSBill Taylor goto rsrcinitp1_fail;
5219e39c5baSBill Taylor }
5229e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_PHASE1_COMPLETE;
5239e39c5baSBill Taylor
5249e39c5baSBill Taylor kmem_free(rsrc_name, TAVOR_RSRC_NAME_MAXLEN);
5259e39c5baSBill Taylor return (DDI_SUCCESS);
5269e39c5baSBill Taylor
5279e39c5baSBill Taylor rsrcinitp1_fail:
5289e39c5baSBill Taylor kmem_free(rsrc_name, TAVOR_RSRC_NAME_MAXLEN);
5299e39c5baSBill Taylor return (status);
5309e39c5baSBill Taylor }
5319e39c5baSBill Taylor
5329e39c5baSBill Taylor
5339e39c5baSBill Taylor /*
5349e39c5baSBill Taylor * tavor_rsrc_init_phase2()
5359e39c5baSBill Taylor * Context: Only called from attach() path context
5369e39c5baSBill Taylor */
5379e39c5baSBill Taylor int
tavor_rsrc_init_phase2(tavor_state_t * state)5389e39c5baSBill Taylor tavor_rsrc_init_phase2(tavor_state_t *state)
5399e39c5baSBill Taylor {
5409e39c5baSBill Taylor tavor_rsrc_sw_hdl_info_t hdl_info;
5419e39c5baSBill Taylor tavor_rsrc_hw_entry_info_t entry_info;
5429e39c5baSBill Taylor tavor_rsrc_mbox_info_t mbox_info;
5439e39c5baSBill Taylor tavor_rsrc_pool_info_t *rsrc_pool;
5449e39c5baSBill Taylor tavor_rsrc_cleanup_level_t cleanup;
5459e39c5baSBill Taylor tavor_cfg_profile_t *cfgprof;
5469e39c5baSBill Taylor uint64_t num, max, size, num_prealloc;
5479e39c5baSBill Taylor uint64_t ddr_size, fw_size;
5489e39c5baSBill Taylor uint_t mcg_size, mcg_size_shift;
5499e39c5baSBill Taylor uint_t uarscr_size, mttsegment_sz;
5509e39c5baSBill Taylor int status;
551*2570281cSToomas Soome char *rsrc_name;
5529e39c5baSBill Taylor
5539e39c5baSBill Taylor ASSERT(state != NULL);
5549e39c5baSBill Taylor
5559e39c5baSBill Taylor /* Phase 2 initialization begins where Phase 1 left off */
5569e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_PHASE1_COMPLETE;
5579e39c5baSBill Taylor
5589e39c5baSBill Taylor /*
5599e39c5baSBill Taylor * Calculate the extent of the DDR size and portion of which that
5609e39c5baSBill Taylor * is already reserved for Tavor firmware. (Note: this information
5619e39c5baSBill Taylor * is available because the QUERY_DDR and QUERY_FW commands have
5629e39c5baSBill Taylor * been posted to Tavor firmware prior to calling this routine)
5639e39c5baSBill Taylor */
5649e39c5baSBill Taylor ddr_size = state->ts_ddr.ddr_endaddr - state->ts_ddr.ddr_baseaddr + 1;
5659e39c5baSBill Taylor fw_size = state->ts_fw.fw_endaddr - state->ts_fw.fw_baseaddr + 1;
5669e39c5baSBill Taylor
5679e39c5baSBill Taylor /* Build the DDR vmem arena name from Tavor instance */
5689e39c5baSBill Taylor rsrc_name = (char *)kmem_zalloc(TAVOR_RSRC_NAME_MAXLEN, KM_SLEEP);
5699e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_DDR_VMEM);
5709e39c5baSBill Taylor
5719e39c5baSBill Taylor /*
5729e39c5baSBill Taylor * Do a vmem_create for the entire DDR range (not including the
5739e39c5baSBill Taylor * portion consumed by Tavor firmware). This creates the vmem arena
5749e39c5baSBill Taylor * from which all other DDR objects (specifically, tables of HW
5759e39c5baSBill Taylor * entries) will be allocated.
5769e39c5baSBill Taylor */
5779e39c5baSBill Taylor state->ts_ddrvmem = vmem_create(rsrc_name,
5789e39c5baSBill Taylor (void *)(uintptr_t)state->ts_ddr.ddr_baseaddr, (ddr_size - fw_size),
5799e39c5baSBill Taylor sizeof (uint64_t), NULL, NULL, NULL, 0, VM_SLEEP);
5809e39c5baSBill Taylor if (state->ts_ddrvmem == NULL) {
5819e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
5829e39c5baSBill Taylor goto rsrcinitp2_fail;
5839e39c5baSBill Taylor }
5849e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL5;
5859e39c5baSBill Taylor
5869e39c5baSBill Taylor /*
5879e39c5baSBill Taylor * Initialize the resource pools for all objects that exist in
5889e39c5baSBill Taylor * Tavor DDR memory. This includes ("In") mailboxes, context tables
5899e39c5baSBill Taylor * (QPC, CQC, EQC, etc...), and other miscellaneous HW objects.
5909e39c5baSBill Taylor */
5919e39c5baSBill Taylor cfgprof = state->ts_cfg_profile;
5929e39c5baSBill Taylor
5939e39c5baSBill Taylor /*
5949e39c5baSBill Taylor * Initialize the resource pool for the MPT table entries. Notice
5959e39c5baSBill Taylor * that the number of MPTs is configurable. The configured value must
5969e39c5baSBill Taylor * be less that the maximum value (obtained from the QUERY_DEV_LIM
5979e39c5baSBill Taylor * command) or the initialization will fail. Note also that a certain
5989e39c5baSBill Taylor * number of MPTs must be set aside for Tavor firmware use.
5999e39c5baSBill Taylor */
6009e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_mpt);
6019e39c5baSBill Taylor max = ((uint64_t)1 << state->ts_devlim.log_max_mpt);
6029e39c5baSBill Taylor num_prealloc = ((uint64_t)1 << state->ts_devlim.log_rsvd_mpt);
6039e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_MPT];
6049e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_MPT;
6059e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_DDR;
6069e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (TAVOR_MPT_SIZE * num);
6079e39c5baSBill Taylor rsrc_pool->rsrc_shift = TAVOR_MPT_SIZE_SHIFT;
6089e39c5baSBill Taylor rsrc_pool->rsrc_quantum = TAVOR_MPT_SIZE;
6099e39c5baSBill Taylor rsrc_pool->rsrc_align = (TAVOR_MPT_SIZE * num);
6109e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
6119e39c5baSBill Taylor rsrc_pool->rsrc_start = NULL;
6129e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_DDR_MPT_VMEM);
6139e39c5baSBill Taylor entry_info.hwi_num = num;
6149e39c5baSBill Taylor entry_info.hwi_max = max;
6159e39c5baSBill Taylor entry_info.hwi_prealloc = num_prealloc;
6169e39c5baSBill Taylor entry_info.hwi_rsrcpool = rsrc_pool;
6179e39c5baSBill Taylor entry_info.hwi_rsrcname = rsrc_name;
6189e39c5baSBill Taylor status = tavor_rsrc_hw_entries_init(state, &entry_info);
6199e39c5baSBill Taylor if (status != DDI_SUCCESS) {
6209e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
6219e39c5baSBill Taylor goto rsrcinitp2_fail;
6229e39c5baSBill Taylor }
6239e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL6;
6249e39c5baSBill Taylor
6259e39c5baSBill Taylor /*
6269e39c5baSBill Taylor * Initialize the resource pool for the MTT table entries. Notice
6279e39c5baSBill Taylor * that the number of MTTs is configurable. The configured value must
6289e39c5baSBill Taylor * be less that the maximum value (obtained from the QUERY_DEV_LIM
6299e39c5baSBill Taylor * command) or the initialization will fail. Note also that a certain
6309e39c5baSBill Taylor * number of MTT segments must be set aside for Tavor firmware use.
6319e39c5baSBill Taylor */
6329e39c5baSBill Taylor mttsegment_sz = (TAVOR_MTTSEG_SIZE << TAVOR_MTT_SIZE_SHIFT);
6339e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_mttseg);
6349e39c5baSBill Taylor max = ((uint64_t)1 << state->ts_devlim.log_max_mttseg);
6359e39c5baSBill Taylor num_prealloc = ((uint64_t)1 << state->ts_devlim.log_rsvd_mttseg);
6369e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_MTT];
6379e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_MTT;
6389e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_DDR;
6399e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (TAVOR_MTT_SIZE * num);
6409e39c5baSBill Taylor rsrc_pool->rsrc_shift = TAVOR_MTT_SIZE_SHIFT;
6419e39c5baSBill Taylor rsrc_pool->rsrc_quantum = mttsegment_sz;
6429e39c5baSBill Taylor rsrc_pool->rsrc_align = (TAVOR_MTT_SIZE * num);
6439e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
6449e39c5baSBill Taylor rsrc_pool->rsrc_start = NULL;
6459e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_DDR_MTT_VMEM);
6469e39c5baSBill Taylor entry_info.hwi_num = num;
6479e39c5baSBill Taylor entry_info.hwi_max = max;
6489e39c5baSBill Taylor entry_info.hwi_prealloc = num_prealloc;
6499e39c5baSBill Taylor entry_info.hwi_rsrcpool = rsrc_pool;
6509e39c5baSBill Taylor entry_info.hwi_rsrcname = rsrc_name;
6519e39c5baSBill Taylor status = tavor_rsrc_hw_entries_init(state, &entry_info);
6529e39c5baSBill Taylor if (status != DDI_SUCCESS) {
6539e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
6549e39c5baSBill Taylor goto rsrcinitp2_fail;
6559e39c5baSBill Taylor }
6569e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL7;
6579e39c5baSBill Taylor
6589e39c5baSBill Taylor /*
6599e39c5baSBill Taylor * Initialize the resource pool for the QPC table entries. Notice
6609e39c5baSBill Taylor * that the number of QPs is configurable. The configured value must
6619e39c5baSBill Taylor * be less that the maximum value (obtained from the QUERY_DEV_LIM
6629e39c5baSBill Taylor * command) or the initialization will fail. Note also that a certain
6639e39c5baSBill Taylor * number of QP contexts must be set aside for Tavor firmware use.
6649e39c5baSBill Taylor */
6659e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_qp);
6669e39c5baSBill Taylor max = ((uint64_t)1 << state->ts_devlim.log_max_qp);
6679e39c5baSBill Taylor num_prealloc = ((uint64_t)1 << state->ts_devlim.log_rsvd_qp);
6689e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_QPC];
6699e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_QPC;
6709e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_DDR;
6719e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (TAVOR_QPC_SIZE * num);
6729e39c5baSBill Taylor rsrc_pool->rsrc_shift = TAVOR_QPC_SIZE_SHIFT;
6739e39c5baSBill Taylor rsrc_pool->rsrc_quantum = TAVOR_QPC_SIZE;
6749e39c5baSBill Taylor rsrc_pool->rsrc_align = (TAVOR_QPC_SIZE * num);
6759e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
6769e39c5baSBill Taylor rsrc_pool->rsrc_start = NULL;
6779e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_DDR_QPC_VMEM);
6789e39c5baSBill Taylor entry_info.hwi_num = num;
6799e39c5baSBill Taylor entry_info.hwi_max = max;
6809e39c5baSBill Taylor entry_info.hwi_prealloc = num_prealloc;
6819e39c5baSBill Taylor entry_info.hwi_rsrcpool = rsrc_pool;
6829e39c5baSBill Taylor entry_info.hwi_rsrcname = rsrc_name;
6839e39c5baSBill Taylor status = tavor_rsrc_hw_entries_init(state, &entry_info);
6849e39c5baSBill Taylor if (status != DDI_SUCCESS) {
6859e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
6869e39c5baSBill Taylor goto rsrcinitp2_fail;
6879e39c5baSBill Taylor }
6889e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL8;
6899e39c5baSBill Taylor
6909e39c5baSBill Taylor /*
6919e39c5baSBill Taylor * Initialize the resource pool for the RDB table entries. Notice
6929e39c5baSBill Taylor * that the number of RDBs is configurable. The configured value must
6939e39c5baSBill Taylor * be less that the maximum value (obtained from the QUERY_DEV_LIM
6949e39c5baSBill Taylor * command) or the initialization will fail.
6959e39c5baSBill Taylor */
6969e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_rdb);
6979e39c5baSBill Taylor max = ((uint64_t)1 << state->ts_devlim.log_max_ra_glob);
6989e39c5baSBill Taylor num_prealloc = 0;
6999e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_RDB];
7009e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_RDB;
7019e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_DDR;
7029e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (TAVOR_RDB_SIZE * num);
7039e39c5baSBill Taylor rsrc_pool->rsrc_shift = TAVOR_RDB_SIZE_SHIFT;
7049e39c5baSBill Taylor rsrc_pool->rsrc_quantum = TAVOR_RDB_SIZE;
7059e39c5baSBill Taylor rsrc_pool->rsrc_align = (TAVOR_RDB_SIZE * num);
7069e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
7079e39c5baSBill Taylor rsrc_pool->rsrc_start = NULL;
7089e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_DDR_RDB_VMEM);
7099e39c5baSBill Taylor entry_info.hwi_num = num;
7109e39c5baSBill Taylor entry_info.hwi_max = max;
7119e39c5baSBill Taylor entry_info.hwi_prealloc = num_prealloc;
7129e39c5baSBill Taylor entry_info.hwi_rsrcpool = rsrc_pool;
7139e39c5baSBill Taylor entry_info.hwi_rsrcname = rsrc_name;
7149e39c5baSBill Taylor status = tavor_rsrc_hw_entries_init(state, &entry_info);
7159e39c5baSBill Taylor if (status != DDI_SUCCESS) {
7169e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
7179e39c5baSBill Taylor goto rsrcinitp2_fail;
7189e39c5baSBill Taylor }
7199e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL9;
7209e39c5baSBill Taylor
7219e39c5baSBill Taylor /*
7229e39c5baSBill Taylor * Initialize the resource pool for the CQC table entries. Notice
7239e39c5baSBill Taylor * that the number of CQs is configurable. The configured value must
7249e39c5baSBill Taylor * be less that the maximum value (obtained from the QUERY_DEV_LIM
7259e39c5baSBill Taylor * command) or the initialization will fail. Note also that a certain
7269e39c5baSBill Taylor * number of CQ contexts must be set aside for Tavor firmware use.
7279e39c5baSBill Taylor */
7289e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_cq);
7299e39c5baSBill Taylor max = ((uint64_t)1 << state->ts_devlim.log_max_cq);
7309e39c5baSBill Taylor num_prealloc = ((uint64_t)1 << state->ts_devlim.log_rsvd_cq);
7319e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_CQC];
7329e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_CQC;
7339e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_DDR;
7349e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (TAVOR_CQC_SIZE * num);
7359e39c5baSBill Taylor rsrc_pool->rsrc_shift = TAVOR_CQC_SIZE_SHIFT;
7369e39c5baSBill Taylor rsrc_pool->rsrc_quantum = TAVOR_CQC_SIZE;
7379e39c5baSBill Taylor rsrc_pool->rsrc_align = (TAVOR_CQC_SIZE * num);
7389e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
7399e39c5baSBill Taylor rsrc_pool->rsrc_start = NULL;
7409e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_DDR_CQC_VMEM);
7419e39c5baSBill Taylor entry_info.hwi_num = num;
7429e39c5baSBill Taylor entry_info.hwi_max = max;
7439e39c5baSBill Taylor entry_info.hwi_prealloc = num_prealloc;
7449e39c5baSBill Taylor entry_info.hwi_rsrcpool = rsrc_pool;
7459e39c5baSBill Taylor entry_info.hwi_rsrcname = rsrc_name;
7469e39c5baSBill Taylor status = tavor_rsrc_hw_entries_init(state, &entry_info);
7479e39c5baSBill Taylor if (status != DDI_SUCCESS) {
7489e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
7499e39c5baSBill Taylor goto rsrcinitp2_fail;
7509e39c5baSBill Taylor }
7519e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL10;
7529e39c5baSBill Taylor
7539e39c5baSBill Taylor /*
7549e39c5baSBill Taylor * Initialize the resource pool for the Extended QPC table entries.
7559e39c5baSBill Taylor * Notice that the number of EQPCs must be the same as the number
7569e39c5baSBill Taylor * of QP contexts. So the initialization is constructed in a
7579e39c5baSBill Taylor * similar way as above (for TAVOR_QPC). One notable difference
7589e39c5baSBill Taylor * here, however, is that by setting the rsrc_quantum field to
7599e39c5baSBill Taylor * zero (indicating a zero-sized object) we indicate that the
7609e39c5baSBill Taylor * object is not allocatable. The EQPC table is, in fact, managed
7619e39c5baSBill Taylor * internally by the hardware and it is, therefore, unnecessary to
7629e39c5baSBill Taylor * initialize an additional vmem_arena for this type of object.
7639e39c5baSBill Taylor */
7649e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_qp);
7659e39c5baSBill Taylor max = ((uint64_t)1 << state->ts_devlim.log_max_qp);
7669e39c5baSBill Taylor num_prealloc = 0;
7679e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_EQPC];
7689e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_EQPC;
7699e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_DDR;
7709e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (TAVOR_EQPC_SIZE * num);
7719e39c5baSBill Taylor rsrc_pool->rsrc_shift = 0;
7729e39c5baSBill Taylor rsrc_pool->rsrc_quantum = 0;
7739e39c5baSBill Taylor rsrc_pool->rsrc_align = TAVOR_EQPC_SIZE;
7749e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
7759e39c5baSBill Taylor rsrc_pool->rsrc_start = NULL;
7769e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_DDR_EQPC_VMEM);
7779e39c5baSBill Taylor entry_info.hwi_num = num;
7789e39c5baSBill Taylor entry_info.hwi_max = max;
7799e39c5baSBill Taylor entry_info.hwi_prealloc = num_prealloc;
7809e39c5baSBill Taylor entry_info.hwi_rsrcpool = rsrc_pool;
7819e39c5baSBill Taylor entry_info.hwi_rsrcname = rsrc_name;
7829e39c5baSBill Taylor status = tavor_rsrc_hw_entries_init(state, &entry_info);
7839e39c5baSBill Taylor if (status != DDI_SUCCESS) {
7849e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
7859e39c5baSBill Taylor goto rsrcinitp2_fail;
7869e39c5baSBill Taylor }
7879e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL11;
7889e39c5baSBill Taylor
7899e39c5baSBill Taylor /*
7909e39c5baSBill Taylor * Initialize the resource pool for the UD address vector table
7919e39c5baSBill Taylor * entries. Notice that the number of UDAVs is configurable. The
7929e39c5baSBill Taylor * configured value must be less that the maximum value (obtained
7939e39c5baSBill Taylor * from the QUERY_DEV_LIM command) or the initialization will fail.
7949e39c5baSBill Taylor */
7959e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_ah);
7969e39c5baSBill Taylor max = ((uint64_t)1 << state->ts_devlim.log_max_av);
7979e39c5baSBill Taylor num_prealloc = 0;
7989e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_UDAV];
7999e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_UDAV;
8009e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_DDR;
8019e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (TAVOR_UDAV_SIZE * num);
8029e39c5baSBill Taylor rsrc_pool->rsrc_shift = TAVOR_UDAV_SIZE_SHIFT;
8039e39c5baSBill Taylor rsrc_pool->rsrc_quantum = TAVOR_UDAV_SIZE;
8049e39c5baSBill Taylor rsrc_pool->rsrc_align = TAVOR_UDAV_SIZE;
8059e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
8069e39c5baSBill Taylor rsrc_pool->rsrc_start = NULL;
8079e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_DDR_UDAV_VMEM);
8089e39c5baSBill Taylor entry_info.hwi_num = num;
8099e39c5baSBill Taylor entry_info.hwi_max = max;
8109e39c5baSBill Taylor entry_info.hwi_prealloc = num_prealloc;
8119e39c5baSBill Taylor entry_info.hwi_rsrcpool = rsrc_pool;
8129e39c5baSBill Taylor entry_info.hwi_rsrcname = rsrc_name;
8139e39c5baSBill Taylor status = tavor_rsrc_hw_entries_init(state, &entry_info);
8149e39c5baSBill Taylor if (status != DDI_SUCCESS) {
8159e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
8169e39c5baSBill Taylor goto rsrcinitp2_fail;
8179e39c5baSBill Taylor }
8189e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL12;
8199e39c5baSBill Taylor
8209e39c5baSBill Taylor /*
8219e39c5baSBill Taylor * Initialize the resource pool for the UAR scratch table entries.
8229e39c5baSBill Taylor * Notice that the number of UARSCRs is configurable. The configured
8239e39c5baSBill Taylor * value must be less that the maximum value (obtained from the
8249e39c5baSBill Taylor * QUERY_DEV_LIM command) or the initialization will fail.
8259e39c5baSBill Taylor * Like the EQPCs above, UARSCR objects are not allocatable. The
8269e39c5baSBill Taylor * UARSCR table is also managed internally by the hardware and it
8279e39c5baSBill Taylor * is, therefore, unnecessary to initialize an additional vmem_arena
8289e39c5baSBill Taylor * for this type of object. We indicate this by setting the
8299e39c5baSBill Taylor * rsrc_quantum field to zero (indicating a zero-sized object).
8309e39c5baSBill Taylor */
8319e39c5baSBill Taylor uarscr_size = state->ts_devlim.uarscr_entry_sz;
8329e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_uar);
8339e39c5baSBill Taylor max = ((uint64_t)1 << (state->ts_devlim.log_max_uar_sz + 20 -
8349e39c5baSBill Taylor PAGESHIFT));
8359e39c5baSBill Taylor num_prealloc = 0;
8369e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_UAR_SCR];
8379e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_UAR_SCR;
8389e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_DDR;
8399e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (uarscr_size * num);
8409e39c5baSBill Taylor rsrc_pool->rsrc_shift = 0;
8419e39c5baSBill Taylor rsrc_pool->rsrc_quantum = 0;
8429e39c5baSBill Taylor rsrc_pool->rsrc_align = uarscr_size;
8439e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
8449e39c5baSBill Taylor rsrc_pool->rsrc_start = NULL;
8459e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_DDR_UARSCR_VMEM);
8469e39c5baSBill Taylor entry_info.hwi_num = num;
8479e39c5baSBill Taylor entry_info.hwi_max = max;
8489e39c5baSBill Taylor entry_info.hwi_prealloc = num_prealloc;
8499e39c5baSBill Taylor entry_info.hwi_rsrcpool = rsrc_pool;
8509e39c5baSBill Taylor entry_info.hwi_rsrcname = rsrc_name;
8519e39c5baSBill Taylor status = tavor_rsrc_hw_entries_init(state, &entry_info);
8529e39c5baSBill Taylor if (status != DDI_SUCCESS) {
8539e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
8549e39c5baSBill Taylor goto rsrcinitp2_fail;
8559e39c5baSBill Taylor }
8569e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL13;
8579e39c5baSBill Taylor
8589e39c5baSBill Taylor /*
8599e39c5baSBill Taylor * Initialize the resource pool for the SRQC table entries. Notice
8609e39c5baSBill Taylor * that the number of SRQs is configurable. The configured value must
8619e39c5baSBill Taylor * be less that the maximum value (obtained from the QUERY_DEV_LIM
8629e39c5baSBill Taylor * command) or the initialization will fail. Note also that a certain
8639e39c5baSBill Taylor * number of SRQ contexts must be set aside for Tavor firmware use.
8649e39c5baSBill Taylor *
8659e39c5baSBill Taylor * Note: We only allocate these resources if SRQ is enabled in the
8669e39c5baSBill Taylor * config profile; see below.
8679e39c5baSBill Taylor */
8689e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_srq);
8699e39c5baSBill Taylor max = ((uint64_t)1 << state->ts_devlim.log_max_srq);
8709e39c5baSBill Taylor num_prealloc = ((uint64_t)1 << state->ts_devlim.log_rsvd_srq);
8719e39c5baSBill Taylor
8729e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_SRQC];
8739e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_SRQC;
8749e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_DDR;
8759e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (TAVOR_SRQC_SIZE * num);
8769e39c5baSBill Taylor rsrc_pool->rsrc_shift = TAVOR_SRQC_SIZE_SHIFT;
8779e39c5baSBill Taylor rsrc_pool->rsrc_quantum = TAVOR_SRQC_SIZE;
8789e39c5baSBill Taylor rsrc_pool->rsrc_align = (TAVOR_SRQC_SIZE * num);
8799e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
8809e39c5baSBill Taylor rsrc_pool->rsrc_start = NULL;
8819e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_DDR_SRQC_VMEM);
8829e39c5baSBill Taylor entry_info.hwi_num = num;
8839e39c5baSBill Taylor entry_info.hwi_max = max;
8849e39c5baSBill Taylor entry_info.hwi_prealloc = num_prealloc;
8859e39c5baSBill Taylor entry_info.hwi_rsrcpool = rsrc_pool;
8869e39c5baSBill Taylor entry_info.hwi_rsrcname = rsrc_name;
8879e39c5baSBill Taylor
8889e39c5baSBill Taylor /*
8899e39c5baSBill Taylor * SRQ support is configurable. Only if SRQ is enabled (the default)
8909e39c5baSBill Taylor * do we actually try to configure these resources. Otherwise, we
8919e39c5baSBill Taylor * simply set the cleanup level and continue on to the next resource
8929e39c5baSBill Taylor */
8939e39c5baSBill Taylor if (state->ts_cfg_profile->cp_srq_enable != 0) {
8949e39c5baSBill Taylor status = tavor_rsrc_hw_entries_init(state, &entry_info);
8959e39c5baSBill Taylor if (status != DDI_SUCCESS) {
8969e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
8979e39c5baSBill Taylor goto rsrcinitp2_fail;
8989e39c5baSBill Taylor }
8999e39c5baSBill Taylor }
9009e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL14;
9019e39c5baSBill Taylor
9029e39c5baSBill Taylor /*
9039e39c5baSBill Taylor * Initialize the resource pool for "In" mailboxes. Notice that
9049e39c5baSBill Taylor * the number of "In" mailboxes, their size, and their location
9059e39c5baSBill Taylor * (DDR or system memory) is configurable. By default, however,
9069e39c5baSBill Taylor * all "In" mailboxes are located in system memory only (because
9079e39c5baSBill Taylor * they are primarily written to and rarely read from)
9089e39c5baSBill Taylor */
9099e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_inmbox);
9109e39c5baSBill Taylor size = ((uint64_t)1 << cfgprof->cp_log_inmbox_size);
9119e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_IN_MBOX];
9129e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_IN_MBOX;
9139e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_DDR;
9149e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (size * num);
9159e39c5baSBill Taylor rsrc_pool->rsrc_shift = cfgprof->cp_log_inmbox_size;
9169e39c5baSBill Taylor rsrc_pool->rsrc_quantum = size;
9179e39c5baSBill Taylor rsrc_pool->rsrc_align = TAVOR_MBOX_ALIGN;
9189e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
9199e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_DDR_INMBOX_VMEM);
9209e39c5baSBill Taylor mbox_info.mbi_num = num;
9219e39c5baSBill Taylor mbox_info.mbi_size = size;
9229e39c5baSBill Taylor mbox_info.mbi_rsrcpool = rsrc_pool;
9239e39c5baSBill Taylor mbox_info.mbi_rsrcname = rsrc_name;
9249e39c5baSBill Taylor status = tavor_rsrc_mbox_init(state, &mbox_info);
9259e39c5baSBill Taylor if (status != DDI_SUCCESS) {
9269e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
9279e39c5baSBill Taylor goto rsrcinitp2_fail;
9289e39c5baSBill Taylor }
9299e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL15;
9309e39c5baSBill Taylor
9319e39c5baSBill Taylor /*
9329e39c5baSBill Taylor * Initialize the Tavor "In" mailbox list. This step actually uses
9339e39c5baSBill Taylor * the tavor_rsrc_alloc() for TAVOR_IN_MBOX to preallocate the
9349e39c5baSBill Taylor * "In" mailboxes, bind them for DMA access, and arrange them into
9359e39c5baSBill Taylor * an easily accessed fast-allocation mechanism (see tavor_cmd.c
9369e39c5baSBill Taylor * for more details)
9379e39c5baSBill Taylor */
9389e39c5baSBill Taylor status = tavor_inmbox_list_init(state);
9399e39c5baSBill Taylor if (status != DDI_SUCCESS) {
9409e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
9419e39c5baSBill Taylor goto rsrcinitp2_fail;
9429e39c5baSBill Taylor }
9439e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL16;
9449e39c5baSBill Taylor
9459e39c5baSBill Taylor /*
9469e39c5baSBill Taylor * Initialize the resource pool for interrupt "In" mailboxes. Notice
9479e39c5baSBill Taylor * that the number of interrupt "In" mailboxes, their size, and their
9489e39c5baSBill Taylor * location (DDR or system memory) is configurable. By default,
9499e39c5baSBill Taylor * however, all interrupt "In" mailboxes are located in system memory
9509e39c5baSBill Taylor * only (because they are primarily written to and rarely read from)
9519e39c5baSBill Taylor */
9529e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_intr_inmbox);
9539e39c5baSBill Taylor size = ((uint64_t)1 << cfgprof->cp_log_inmbox_size);
9549e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_INTR_IN_MBOX];
9559e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_INTR_IN_MBOX;
9569e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_DDR;
9579e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (size * num);
9589e39c5baSBill Taylor rsrc_pool->rsrc_shift = cfgprof->cp_log_inmbox_size;
9599e39c5baSBill Taylor rsrc_pool->rsrc_quantum = size;
9609e39c5baSBill Taylor rsrc_pool->rsrc_align = TAVOR_MBOX_ALIGN;
9619e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
9629e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_DDR_INTR_INMBOX_VMEM);
9639e39c5baSBill Taylor mbox_info.mbi_num = num;
9649e39c5baSBill Taylor mbox_info.mbi_size = size;
9659e39c5baSBill Taylor mbox_info.mbi_rsrcpool = rsrc_pool;
9669e39c5baSBill Taylor mbox_info.mbi_rsrcname = rsrc_name;
9679e39c5baSBill Taylor status = tavor_rsrc_mbox_init(state, &mbox_info);
9689e39c5baSBill Taylor if (status != DDI_SUCCESS) {
9699e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
9709e39c5baSBill Taylor goto rsrcinitp2_fail;
9719e39c5baSBill Taylor }
9729e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL17;
9739e39c5baSBill Taylor
9749e39c5baSBill Taylor /*
9759e39c5baSBill Taylor * Initialize the Tavor interrupt "In" mailbox list. This step
9769e39c5baSBill Taylor * actually uses the tavor_rsrc_alloc() for TAVOR_IN_MBOX to
9779e39c5baSBill Taylor * preallocate the interrupt "In" mailboxes, bind them for DMA access,
9789e39c5baSBill Taylor * and arrange them into an easily accessed fast-allocation mechanism
9799e39c5baSBill Taylor * (see tavor_cmd.c for more details)
9809e39c5baSBill Taylor */
9819e39c5baSBill Taylor status = tavor_intr_inmbox_list_init(state);
9829e39c5baSBill Taylor if (status != DDI_SUCCESS) {
9839e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
9849e39c5baSBill Taylor goto rsrcinitp2_fail;
9859e39c5baSBill Taylor }
9869e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL18;
9879e39c5baSBill Taylor
9889e39c5baSBill Taylor /*
9899e39c5baSBill Taylor * Initialize the Tavor command handling interfaces. This step
9909e39c5baSBill Taylor * sets up the outstanding command tracking mechanism for easy access
9919e39c5baSBill Taylor * and fast allocation (see tavor_cmd.c for more details).
9929e39c5baSBill Taylor */
9939e39c5baSBill Taylor status = tavor_outstanding_cmdlist_init(state);
9949e39c5baSBill Taylor if (status != DDI_SUCCESS) {
9959e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
9969e39c5baSBill Taylor goto rsrcinitp2_fail;
9979e39c5baSBill Taylor }
9989e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL19;
9999e39c5baSBill Taylor
10009e39c5baSBill Taylor /*
10019e39c5baSBill Taylor * Calculate (and validate) the size of Multicast Group (MCG) entries
10029e39c5baSBill Taylor */
10039e39c5baSBill Taylor status = tavor_rsrc_mcg_entry_get_size(state, &mcg_size_shift);
10049e39c5baSBill Taylor if (status != DDI_SUCCESS) {
10059e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
10069e39c5baSBill Taylor goto rsrcinitp2_fail;
10079e39c5baSBill Taylor }
10089e39c5baSBill Taylor mcg_size = TAVOR_MCGMEM_SZ(state);
10099e39c5baSBill Taylor
10109e39c5baSBill Taylor /*
10119e39c5baSBill Taylor * Initialize the resource pool for the MCG table entries. Notice
10129e39c5baSBill Taylor * that the number of MCGs is configurable. The configured value must
10139e39c5baSBill Taylor * be less that the maximum value (obtained from the QUERY_DEV_LIM
10149e39c5baSBill Taylor * command) or the initialization will fail. Note also that a certain
10159e39c5baSBill Taylor * number of MCGs must be set aside for Tavor firmware use (they
10169e39c5baSBill Taylor * correspond to the number of MCGs used by the internal hash
10179e39c5baSBill Taylor * function.
10189e39c5baSBill Taylor */
10199e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_mcg);
10209e39c5baSBill Taylor max = ((uint64_t)1 << state->ts_devlim.log_max_mcg);
10219e39c5baSBill Taylor num_prealloc = ((uint64_t)1 << cfgprof->cp_log_num_mcg_hash);
10229e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_MCG];
10239e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_MCG;
10249e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_DDR;
10259e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (mcg_size * num);
10269e39c5baSBill Taylor rsrc_pool->rsrc_shift = mcg_size_shift;
10279e39c5baSBill Taylor rsrc_pool->rsrc_quantum = mcg_size;
10289e39c5baSBill Taylor rsrc_pool->rsrc_align = mcg_size;
10299e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
10309e39c5baSBill Taylor rsrc_pool->rsrc_start = NULL;
10319e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_DDR_MCG_VMEM);
10329e39c5baSBill Taylor entry_info.hwi_num = num;
10339e39c5baSBill Taylor entry_info.hwi_max = max;
10349e39c5baSBill Taylor entry_info.hwi_prealloc = num_prealloc;
10359e39c5baSBill Taylor entry_info.hwi_rsrcpool = rsrc_pool;
10369e39c5baSBill Taylor entry_info.hwi_rsrcname = rsrc_name;
10379e39c5baSBill Taylor status = tavor_rsrc_hw_entries_init(state, &entry_info);
10389e39c5baSBill Taylor if (status != DDI_SUCCESS) {
10399e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
10409e39c5baSBill Taylor goto rsrcinitp2_fail;
10419e39c5baSBill Taylor }
10429e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL20;
10439e39c5baSBill Taylor
10449e39c5baSBill Taylor /*
10459e39c5baSBill Taylor * Initialize the resource pool for the EQC table entries. Notice
10469e39c5baSBill Taylor * that the number of EQs is hardcoded. The hardcoded value should
10479e39c5baSBill Taylor * be less that the maximum value (obtained from the QUERY_DEV_LIM
10489e39c5baSBill Taylor * command) or the initialization will fail.
10499e39c5baSBill Taylor */
10509e39c5baSBill Taylor num = TAVOR_NUM_EQ;
10519e39c5baSBill Taylor max = ((uint64_t)1 << state->ts_devlim.log_max_eq);
10529e39c5baSBill Taylor num_prealloc = 0;
10539e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_EQC];
10549e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_EQC;
10559e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_DDR;
10569e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (TAVOR_EQC_SIZE * num);
10579e39c5baSBill Taylor rsrc_pool->rsrc_shift = TAVOR_EQC_SIZE_SHIFT;
10589e39c5baSBill Taylor rsrc_pool->rsrc_quantum = TAVOR_EQC_SIZE;
10599e39c5baSBill Taylor rsrc_pool->rsrc_align = (TAVOR_EQC_SIZE * num);
10609e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
10619e39c5baSBill Taylor rsrc_pool->rsrc_start = NULL;
10629e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_DDR_EQC_VMEM);
10639e39c5baSBill Taylor entry_info.hwi_num = num;
10649e39c5baSBill Taylor entry_info.hwi_max = max;
10659e39c5baSBill Taylor entry_info.hwi_prealloc = num_prealloc;
10669e39c5baSBill Taylor entry_info.hwi_rsrcpool = rsrc_pool;
10679e39c5baSBill Taylor entry_info.hwi_rsrcname = rsrc_name;
10689e39c5baSBill Taylor status = tavor_rsrc_hw_entries_init(state, &entry_info);
10699e39c5baSBill Taylor if (status != DDI_SUCCESS) {
10709e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
10719e39c5baSBill Taylor goto rsrcinitp2_fail;
10729e39c5baSBill Taylor }
10739e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL21;
10749e39c5baSBill Taylor
10759e39c5baSBill Taylor /*
10769e39c5baSBill Taylor * Initialize the resource pools for all objects that exist in
10779e39c5baSBill Taylor * system memory. This includes PD handles, MR handle, EQ handles,
10789e39c5baSBill Taylor * QP handles, etc. These objects are almost entirely managed using
10799e39c5baSBill Taylor * kmem_cache routines. (See comment above for more detail)
10809e39c5baSBill Taylor */
10819e39c5baSBill Taylor
10829e39c5baSBill Taylor /*
10839e39c5baSBill Taylor * Initialize the resource pool for the PD handles. Notice
10849e39c5baSBill Taylor * that the number of PDHDLs is configurable. The configured value
10859e39c5baSBill Taylor * must be less that the maximum value (obtained from the QUERY_DEV_LIM
10869e39c5baSBill Taylor * command) or the initialization will fail. Note also that the PD
10879e39c5baSBill Taylor * handle has constructor and destructor methods associated with it.
10889e39c5baSBill Taylor */
10899e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_PDHDL];
10909e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_PDHDL;
10919e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_SYSMEM;
10929e39c5baSBill Taylor rsrc_pool->rsrc_quantum = sizeof (struct tavor_sw_pd_s);
10939e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
10949e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_PDHDL_CACHE);
10959e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_pd);
10969e39c5baSBill Taylor hdl_info.swi_max = ((uint64_t)1 << state->ts_devlim.log_max_pd);
10979e39c5baSBill Taylor hdl_info.swi_rsrcpool = rsrc_pool;
10989e39c5baSBill Taylor hdl_info.swi_constructor = tavor_rsrc_pdhdl_constructor;
10999e39c5baSBill Taylor hdl_info.swi_destructor = tavor_rsrc_pdhdl_destructor;
11009e39c5baSBill Taylor hdl_info.swi_rsrcname = rsrc_name;
11019e39c5baSBill Taylor hdl_info.swi_flags = TAVOR_SWHDL_KMEMCACHE_INIT;
11029e39c5baSBill Taylor status = tavor_rsrc_pd_handles_init(state, &hdl_info);
11039e39c5baSBill Taylor if (status != DDI_SUCCESS) {
11049e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
11059e39c5baSBill Taylor goto rsrcinitp2_fail;
11069e39c5baSBill Taylor }
11079e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL22;
11089e39c5baSBill Taylor
11099e39c5baSBill Taylor /*
11109e39c5baSBill Taylor * Initialize the resource pool for the MR handles. Notice
11119e39c5baSBill Taylor * that the number of MRHDLs is configurable. The configured value
11129e39c5baSBill Taylor * must be less that the maximum value (obtained from the QUERY_DEV_LIM
11139e39c5baSBill Taylor * command) or the initialization will fail.
11149e39c5baSBill Taylor */
11159e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_MRHDL];
11169e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_MRHDL;
11179e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_SYSMEM;
11189e39c5baSBill Taylor rsrc_pool->rsrc_quantum = sizeof (struct tavor_sw_mr_s);
11199e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
11209e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_MRHDL_CACHE);
11219e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_mpt);
11229e39c5baSBill Taylor hdl_info.swi_max = ((uint64_t)1 << state->ts_devlim.log_max_mpt);
11239e39c5baSBill Taylor hdl_info.swi_rsrcpool = rsrc_pool;
11249e39c5baSBill Taylor hdl_info.swi_constructor = tavor_rsrc_mrhdl_constructor;
11259e39c5baSBill Taylor hdl_info.swi_destructor = tavor_rsrc_mrhdl_destructor;
11269e39c5baSBill Taylor hdl_info.swi_rsrcname = rsrc_name;
11279e39c5baSBill Taylor hdl_info.swi_flags = TAVOR_SWHDL_KMEMCACHE_INIT;
11289e39c5baSBill Taylor status = tavor_rsrc_sw_handles_init(state, &hdl_info);
11299e39c5baSBill Taylor if (status != DDI_SUCCESS) {
11309e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
11319e39c5baSBill Taylor goto rsrcinitp2_fail;
11329e39c5baSBill Taylor }
11339e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL23;
11349e39c5baSBill Taylor
11359e39c5baSBill Taylor /*
11369e39c5baSBill Taylor * Initialize the resource pool for the EQ handles. Notice
11379e39c5baSBill Taylor * that the number of EQHDLs is hardcoded. The hardcoded value
11389e39c5baSBill Taylor * should be less that the maximum value (obtained from the
11399e39c5baSBill Taylor * QUERY_DEV_LIM command) or the initialization will fail.
11409e39c5baSBill Taylor */
11419e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_EQHDL];
11429e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_EQHDL;
11439e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_SYSMEM;
11449e39c5baSBill Taylor rsrc_pool->rsrc_quantum = sizeof (struct tavor_sw_eq_s);
11459e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
11469e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_EQHDL_CACHE);
11479e39c5baSBill Taylor hdl_info.swi_num = TAVOR_NUM_EQ;
11489e39c5baSBill Taylor hdl_info.swi_max = ((uint64_t)1 << state->ts_devlim.log_max_eq);
11499e39c5baSBill Taylor hdl_info.swi_rsrcpool = rsrc_pool;
11509e39c5baSBill Taylor hdl_info.swi_constructor = NULL;
11519e39c5baSBill Taylor hdl_info.swi_destructor = NULL;
11529e39c5baSBill Taylor hdl_info.swi_rsrcname = rsrc_name;
11539e39c5baSBill Taylor hdl_info.swi_flags = TAVOR_SWHDL_KMEMCACHE_INIT;
11549e39c5baSBill Taylor status = tavor_rsrc_sw_handles_init(state, &hdl_info);
11559e39c5baSBill Taylor if (status != DDI_SUCCESS) {
11569e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
11579e39c5baSBill Taylor goto rsrcinitp2_fail;
11589e39c5baSBill Taylor }
11599e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL24;
11609e39c5baSBill Taylor
11619e39c5baSBill Taylor /*
11629e39c5baSBill Taylor * Initialize the resource pool for the CQ handles. Notice
11639e39c5baSBill Taylor * that the number of CQHDLs is configurable. The configured value
11649e39c5baSBill Taylor * must be less that the maximum value (obtained from the QUERY_DEV_LIM
11659e39c5baSBill Taylor * command) or the initialization will fail. Note also that the CQ
11669e39c5baSBill Taylor * handle has constructor and destructor methods associated with it.
11679e39c5baSBill Taylor */
11689e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_CQHDL];
11699e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_CQHDL;
11709e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_SYSMEM;
11719e39c5baSBill Taylor rsrc_pool->rsrc_quantum = sizeof (struct tavor_sw_cq_s);
11729e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
11739e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_CQHDL_CACHE);
11749e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_cq);
11759e39c5baSBill Taylor hdl_info.swi_max = ((uint64_t)1 << state->ts_devlim.log_max_cq);
11769e39c5baSBill Taylor hdl_info.swi_rsrcpool = rsrc_pool;
11779e39c5baSBill Taylor hdl_info.swi_constructor = tavor_rsrc_cqhdl_constructor;
11789e39c5baSBill Taylor hdl_info.swi_destructor = tavor_rsrc_cqhdl_destructor;
11799e39c5baSBill Taylor hdl_info.swi_rsrcname = rsrc_name;
11809e39c5baSBill Taylor hdl_info.swi_flags = (TAVOR_SWHDL_KMEMCACHE_INIT |
11819e39c5baSBill Taylor TAVOR_SWHDL_TABLE_INIT);
11829e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (tavor_cqhdl_t);
11839e39c5baSBill Taylor status = tavor_rsrc_sw_handles_init(state, &hdl_info);
11849e39c5baSBill Taylor if (status != DDI_SUCCESS) {
11859e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
11869e39c5baSBill Taylor goto rsrcinitp2_fail;
11879e39c5baSBill Taylor }
11889e39c5baSBill Taylor
11899e39c5baSBill Taylor /*
11909e39c5baSBill Taylor * Save away the pointer to the central list of CQ handle pointers
11919e39c5baSBill Taylor * This this is used as a mechanism to enable fast CQnumber-to-CQhandle
11929e39c5baSBill Taylor * lookup during EQ event processing. The table is a list of
11939e39c5baSBill Taylor * tavor_cqhdl_t allocated by the above routine because of the
11949e39c5baSBill Taylor * TAVOR_SWHDL_TABLE_INIT flag. The table has as many tavor_cqhdl_t
11959e39c5baSBill Taylor * as the number of CQs.
11969e39c5baSBill Taylor */
11979e39c5baSBill Taylor state->ts_cqhdl = hdl_info.swi_table_ptr;
11989e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL25;
11999e39c5baSBill Taylor
12009e39c5baSBill Taylor /*
12019e39c5baSBill Taylor * Initialize the resource pool for the SRQ handles. Notice
12029e39c5baSBill Taylor * that the number of SRQHDLs is configurable. The configured value
12039e39c5baSBill Taylor * must be less that the maximum value (obtained from the QUERY_DEV_LIM
12049e39c5baSBill Taylor * command) or the initialization will fail. Note also that the SRQ
12059e39c5baSBill Taylor * handle has constructor and destructor methods associated with it.
12069e39c5baSBill Taylor *
12079e39c5baSBill Taylor * Note: We only allocate these resources if SRQ is enabled in the
12089e39c5baSBill Taylor * config profile; see below.
12099e39c5baSBill Taylor */
12109e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_SRQHDL];
12119e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_SRQHDL;
12129e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_SYSMEM;
12139e39c5baSBill Taylor rsrc_pool->rsrc_quantum = sizeof (struct tavor_sw_srq_s);
12149e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
12159e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_SRQHDL_CACHE);
12169e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_srq);
12179e39c5baSBill Taylor hdl_info.swi_max = ((uint64_t)1 << state->ts_devlim.log_max_srq);
12189e39c5baSBill Taylor hdl_info.swi_rsrcpool = rsrc_pool;
12199e39c5baSBill Taylor hdl_info.swi_constructor = tavor_rsrc_srqhdl_constructor;
12209e39c5baSBill Taylor hdl_info.swi_destructor = tavor_rsrc_srqhdl_destructor;
12219e39c5baSBill Taylor hdl_info.swi_rsrcname = rsrc_name;
12229e39c5baSBill Taylor hdl_info.swi_flags = (TAVOR_SWHDL_KMEMCACHE_INIT |
12239e39c5baSBill Taylor TAVOR_SWHDL_TABLE_INIT);
12249e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (tavor_srqhdl_t);
12259e39c5baSBill Taylor
12269e39c5baSBill Taylor /*
12279e39c5baSBill Taylor * SRQ support is configurable. Only if SRQ is enabled (the default)
12289e39c5baSBill Taylor * do we actually try to configure these resources. Otherwise, we
12299e39c5baSBill Taylor * simply set the cleanup level and continue on to the next resource
12309e39c5baSBill Taylor */
12319e39c5baSBill Taylor if (state->ts_cfg_profile->cp_srq_enable != 0) {
12329e39c5baSBill Taylor status = tavor_rsrc_sw_handles_init(state, &hdl_info);
12339e39c5baSBill Taylor if (status != DDI_SUCCESS) {
12349e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
12359e39c5baSBill Taylor goto rsrcinitp2_fail;
12369e39c5baSBill Taylor }
12379e39c5baSBill Taylor
12389e39c5baSBill Taylor /*
12399e39c5baSBill Taylor * Save away the pointer to the central list of SRQ handle
12409e39c5baSBill Taylor * pointers This this is used as a mechanism to enable fast
12419e39c5baSBill Taylor * SRQnumber-to-SRQhandle lookup. The table is a list of
12429e39c5baSBill Taylor * tavor_srqhdl_t allocated by the above routine because of the
12439e39c5baSBill Taylor * TAVOR_SWHDL_TABLE_INIT flag. The table has as many
12449e39c5baSBill Taylor * tavor_srqhdl_t as the number of SRQs.
12459e39c5baSBill Taylor */
12469e39c5baSBill Taylor state->ts_srqhdl = hdl_info.swi_table_ptr;
12479e39c5baSBill Taylor }
12489e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL26;
12499e39c5baSBill Taylor
12509e39c5baSBill Taylor /*
12519e39c5baSBill Taylor * Initialize the resource pool for the address handles. Notice
12529e39c5baSBill Taylor * that the number of AHHDLs is configurable. The configured value
12539e39c5baSBill Taylor * must be less that the maximum value (obtained from the QUERY_DEV_LIM
12549e39c5baSBill Taylor * command) or the initialization will fail.
12559e39c5baSBill Taylor */
12569e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_AHHDL];
12579e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_AHHDL;
12589e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_SYSMEM;
12599e39c5baSBill Taylor rsrc_pool->rsrc_quantum = sizeof (struct tavor_sw_ah_s);
12609e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
12619e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_AHHDL_CACHE);
12629e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_ah);
12639e39c5baSBill Taylor hdl_info.swi_max = ((uint64_t)1 << state->ts_devlim.log_max_av);
12649e39c5baSBill Taylor hdl_info.swi_rsrcpool = rsrc_pool;
12659e39c5baSBill Taylor hdl_info.swi_constructor = tavor_rsrc_ahhdl_constructor;
12669e39c5baSBill Taylor hdl_info.swi_destructor = tavor_rsrc_ahhdl_destructor;
12679e39c5baSBill Taylor hdl_info.swi_rsrcname = rsrc_name;
12689e39c5baSBill Taylor hdl_info.swi_flags = TAVOR_SWHDL_KMEMCACHE_INIT;
12699e39c5baSBill Taylor status = tavor_rsrc_sw_handles_init(state, &hdl_info);
12709e39c5baSBill Taylor if (status != DDI_SUCCESS) {
12719e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
12729e39c5baSBill Taylor goto rsrcinitp2_fail;
12739e39c5baSBill Taylor }
12749e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL27;
12759e39c5baSBill Taylor
12769e39c5baSBill Taylor /*
12779e39c5baSBill Taylor * Initialize the resource pool for the QP handles. Notice
12789e39c5baSBill Taylor * that the number of QPHDLs is configurable. The configured value
12799e39c5baSBill Taylor * must be less that the maximum value (obtained from the QUERY_DEV_LIM
12809e39c5baSBill Taylor * command) or the initialization will fail. Note also that the QP
12819e39c5baSBill Taylor * handle has constructor and destructor methods associated with it.
12829e39c5baSBill Taylor */
12839e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_QPHDL];
12849e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_QPHDL;
12859e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_SYSMEM;
12869e39c5baSBill Taylor rsrc_pool->rsrc_quantum = sizeof (struct tavor_sw_qp_s);
12879e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
12889e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_QPHDL_CACHE);
12899e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_qp);
12909e39c5baSBill Taylor hdl_info.swi_max = ((uint64_t)1 << state->ts_devlim.log_max_qp);
12919e39c5baSBill Taylor hdl_info.swi_rsrcpool = rsrc_pool;
12929e39c5baSBill Taylor hdl_info.swi_constructor = tavor_rsrc_qphdl_constructor;
12939e39c5baSBill Taylor hdl_info.swi_destructor = tavor_rsrc_qphdl_destructor;
12949e39c5baSBill Taylor hdl_info.swi_rsrcname = rsrc_name;
12959e39c5baSBill Taylor hdl_info.swi_flags = (TAVOR_SWHDL_KMEMCACHE_INIT |
12969e39c5baSBill Taylor TAVOR_SWHDL_TABLE_INIT);
12979e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (tavor_qphdl_t);
12989e39c5baSBill Taylor status = tavor_rsrc_sw_handles_init(state, &hdl_info);
12999e39c5baSBill Taylor if (status != DDI_SUCCESS) {
13009e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
13019e39c5baSBill Taylor goto rsrcinitp2_fail;
13029e39c5baSBill Taylor }
13039e39c5baSBill Taylor
13049e39c5baSBill Taylor /*
13059e39c5baSBill Taylor * Save away the pointer to the central list of QP handle pointers
13069e39c5baSBill Taylor * This this is used as a mechanism to enable fast QPnumber-to-QPhandle
13079e39c5baSBill Taylor * lookup during CQ event processing. The table is a list of
13089e39c5baSBill Taylor * tavor_qphdl_t allocated by the above routine because of the
13099e39c5baSBill Taylor * TAVOR_SWHDL_TABLE_INIT flag. The table has as many tavor_qphdl_t
13109e39c5baSBill Taylor * as the number of QPs.
13119e39c5baSBill Taylor */
13129e39c5baSBill Taylor state->ts_qphdl = hdl_info.swi_table_ptr;
13139e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL28;
13149e39c5baSBill Taylor
13159e39c5baSBill Taylor /*
13169e39c5baSBill Taylor * Initialize the resource pool for the reference count handles.
13179e39c5baSBill Taylor * Notice that the number of REFCNTs is configurable, but it's value
13189e39c5baSBill Taylor * is set to the number of MPTs. Since REFCNTs are used to support
13199e39c5baSBill Taylor * shared memory regions, it is possible that we might require as
13209e39c5baSBill Taylor * one REFCNT for every MPT.
13219e39c5baSBill Taylor */
13229e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_REFCNT];
13239e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_REFCNT;
13249e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_SYSMEM;
13259e39c5baSBill Taylor rsrc_pool->rsrc_quantum = sizeof (tavor_sw_refcnt_t);
13269e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
13279e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_REFCNT_CACHE);
13289e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_mpt);
13299e39c5baSBill Taylor hdl_info.swi_max = ((uint64_t)1 << state->ts_devlim.log_max_mpt);
13309e39c5baSBill Taylor hdl_info.swi_rsrcpool = rsrc_pool;
13319e39c5baSBill Taylor hdl_info.swi_constructor = tavor_rsrc_refcnt_constructor;
13329e39c5baSBill Taylor hdl_info.swi_destructor = tavor_rsrc_refcnt_destructor;
13339e39c5baSBill Taylor hdl_info.swi_rsrcname = rsrc_name;
13349e39c5baSBill Taylor hdl_info.swi_flags = TAVOR_SWHDL_KMEMCACHE_INIT;
13359e39c5baSBill Taylor status = tavor_rsrc_sw_handles_init(state, &hdl_info);
13369e39c5baSBill Taylor if (status != DDI_SUCCESS) {
13379e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
13389e39c5baSBill Taylor goto rsrcinitp2_fail;
13399e39c5baSBill Taylor }
13409e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL29;
13419e39c5baSBill Taylor
13429e39c5baSBill Taylor /*
13439e39c5baSBill Taylor * Initialize the resource pool for the MCG handles. Notice that for
13449e39c5baSBill Taylor * these MCG handles, we are allocating a table of structures (used to
13459e39c5baSBill Taylor * keep track of the MCG entries that are being written to hardware
13469e39c5baSBill Taylor * and to speed up multicast attach/detach operations).
13479e39c5baSBill Taylor */
13489e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_mcg);
13499e39c5baSBill Taylor hdl_info.swi_max = ((uint64_t)1 << state->ts_devlim.log_max_mcg);
13509e39c5baSBill Taylor hdl_info.swi_flags = TAVOR_SWHDL_TABLE_INIT;
13519e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (struct tavor_sw_mcg_list_s);
13529e39c5baSBill Taylor status = tavor_rsrc_sw_handles_init(state, &hdl_info);
13539e39c5baSBill Taylor if (status != DDI_SUCCESS) {
13549e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
13559e39c5baSBill Taylor goto rsrcinitp2_fail;
13569e39c5baSBill Taylor }
13579e39c5baSBill Taylor state->ts_mcghdl = hdl_info.swi_table_ptr;
13589e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_LEVEL30;
13599e39c5baSBill Taylor
13609e39c5baSBill Taylor /*
13619e39c5baSBill Taylor * Initialize the resource pools for all objects that exist in
13629e39c5baSBill Taylor * UAR memory. The only objects that are allocated from UAR memory
13639e39c5baSBill Taylor * are the UAR pages which are used for holding Tavor hardware's
13649e39c5baSBill Taylor * doorbell registers.
13659e39c5baSBill Taylor */
13669e39c5baSBill Taylor
13679e39c5baSBill Taylor /*
13689e39c5baSBill Taylor * Initialize the resource pool for the UAR pages. Notice
13699e39c5baSBill Taylor * that the number of UARPGs is configurable. The configured value
13709e39c5baSBill Taylor * must be less that the maximum value (obtained from the QUERY_DEV_LIM
13719e39c5baSBill Taylor * command) or the initialization will fail. Note also that by
13729e39c5baSBill Taylor * specifying the rsrc_start parameter in advance, we direct the
13739e39c5baSBill Taylor * initialization routine not to attempt to allocated space from the
13749e39c5baSBill Taylor * Tavor DDR vmem_arena.
13759e39c5baSBill Taylor */
13769e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_uar);
13779e39c5baSBill Taylor max = ((uint64_t)1 << (state->ts_devlim.log_max_uar_sz + 20 -
13789e39c5baSBill Taylor PAGESHIFT));
13799e39c5baSBill Taylor num_prealloc = 0;
13809e39c5baSBill Taylor rsrc_pool = &state->ts_rsrc_hdl[TAVOR_UARPG];
13819e39c5baSBill Taylor rsrc_pool->rsrc_type = TAVOR_UARPG;
13829e39c5baSBill Taylor rsrc_pool->rsrc_loc = TAVOR_IN_UAR;
13839e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (num << PAGESHIFT);
13849e39c5baSBill Taylor rsrc_pool->rsrc_shift = PAGESHIFT;
13859e39c5baSBill Taylor rsrc_pool->rsrc_quantum = PAGESIZE;
13869e39c5baSBill Taylor rsrc_pool->rsrc_align = PAGESIZE;
13879e39c5baSBill Taylor rsrc_pool->rsrc_state = state;
13889e39c5baSBill Taylor rsrc_pool->rsrc_start = (void *)state->ts_reg_uar_baseaddr;
13899e39c5baSBill Taylor TAVOR_RSRC_NAME(rsrc_name, TAVOR_UAR_VMEM);
13909e39c5baSBill Taylor entry_info.hwi_num = num;
13919e39c5baSBill Taylor entry_info.hwi_max = max;
13929e39c5baSBill Taylor entry_info.hwi_prealloc = num_prealloc;
13939e39c5baSBill Taylor entry_info.hwi_rsrcpool = rsrc_pool;
13949e39c5baSBill Taylor entry_info.hwi_rsrcname = rsrc_name;
13959e39c5baSBill Taylor status = tavor_rsrc_hw_entries_init(state, &entry_info);
13969e39c5baSBill Taylor if (status != DDI_SUCCESS) {
13979e39c5baSBill Taylor tavor_rsrc_fini(state, cleanup);
13989e39c5baSBill Taylor goto rsrcinitp2_fail;
13999e39c5baSBill Taylor }
14009e39c5baSBill Taylor cleanup = TAVOR_RSRC_CLEANUP_ALL;
14019e39c5baSBill Taylor
14029e39c5baSBill Taylor kmem_free(rsrc_name, TAVOR_RSRC_NAME_MAXLEN);
14039e39c5baSBill Taylor return (DDI_SUCCESS);
14049e39c5baSBill Taylor
14059e39c5baSBill Taylor rsrcinitp2_fail:
14069e39c5baSBill Taylor kmem_free(rsrc_name, TAVOR_RSRC_NAME_MAXLEN);
14079e39c5baSBill Taylor return (status);
14089e39c5baSBill Taylor }
14099e39c5baSBill Taylor
14109e39c5baSBill Taylor
14119e39c5baSBill Taylor /*
14129e39c5baSBill Taylor * tavor_rsrc_fini()
14139e39c5baSBill Taylor * Context: Only called from attach() and/or detach() path contexts
14149e39c5baSBill Taylor */
14159e39c5baSBill Taylor void
tavor_rsrc_fini(tavor_state_t * state,tavor_rsrc_cleanup_level_t clean)14169e39c5baSBill Taylor tavor_rsrc_fini(tavor_state_t *state, tavor_rsrc_cleanup_level_t clean)
14179e39c5baSBill Taylor {
14189e39c5baSBill Taylor tavor_rsrc_sw_hdl_info_t hdl_info;
14199e39c5baSBill Taylor tavor_rsrc_hw_entry_info_t entry_info;
14209e39c5baSBill Taylor tavor_rsrc_mbox_info_t mbox_info;
14219e39c5baSBill Taylor tavor_cfg_profile_t *cfgprof;
14229e39c5baSBill Taylor
14239e39c5baSBill Taylor ASSERT(state != NULL);
14249e39c5baSBill Taylor
14259e39c5baSBill Taylor cfgprof = state->ts_cfg_profile;
14269e39c5baSBill Taylor
14279e39c5baSBill Taylor switch (clean) {
14289e39c5baSBill Taylor /*
14299e39c5baSBill Taylor * If we add more resources that need to be cleaned up here, we should
14309e39c5baSBill Taylor * ensure that TAVOR_RSRC_CLEANUP_ALL is still the first entry (i.e.
14319e39c5baSBill Taylor * corresponds to the last resource allocated).
14329e39c5baSBill Taylor */
14339e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_ALL:
14349e39c5baSBill Taylor /* Cleanup the UAR page resource pool */
14359e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_UARPG];
14369e39c5baSBill Taylor tavor_rsrc_hw_entries_fini(state, &entry_info);
14379e39c5baSBill Taylor /* FALLTHROUGH */
14389e39c5baSBill Taylor
14399e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL30:
14409e39c5baSBill Taylor /* Cleanup the central MCG handle pointers list */
14419e39c5baSBill Taylor hdl_info.swi_rsrcpool = NULL;
14429e39c5baSBill Taylor hdl_info.swi_table_ptr = state->ts_mcghdl;
14439e39c5baSBill Taylor hdl_info.swi_num =
14449e39c5baSBill Taylor ((uint64_t)1 << cfgprof->cp_log_num_mcg);
14459e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (struct tavor_sw_mcg_list_s);
14469e39c5baSBill Taylor tavor_rsrc_sw_handles_fini(state, &hdl_info);
14479e39c5baSBill Taylor /* FALLTHROUGH */
14489e39c5baSBill Taylor
14499e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL29:
14509e39c5baSBill Taylor /* Cleanup the reference count resource pool */
14519e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_REFCNT];
14529e39c5baSBill Taylor hdl_info.swi_table_ptr = NULL;
14539e39c5baSBill Taylor tavor_rsrc_sw_handles_fini(state, &hdl_info);
14549e39c5baSBill Taylor /* FALLTHROUGH */
14559e39c5baSBill Taylor
14569e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL28:
14579e39c5baSBill Taylor /* Cleanup the QP handle resource pool */
14589e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_QPHDL];
14599e39c5baSBill Taylor hdl_info.swi_table_ptr = state->ts_qphdl;
14609e39c5baSBill Taylor hdl_info.swi_num =
14619e39c5baSBill Taylor ((uint64_t)1 << cfgprof->cp_log_num_qp);
14629e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (tavor_qphdl_t);
14639e39c5baSBill Taylor tavor_rsrc_sw_handles_fini(state, &hdl_info);
14649e39c5baSBill Taylor /* FALLTHROUGH */
14659e39c5baSBill Taylor
14669e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL27:
14679e39c5baSBill Taylor /* Cleanup the address handle resource pool */
14689e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_AHHDL];
14699e39c5baSBill Taylor hdl_info.swi_table_ptr = NULL;
14709e39c5baSBill Taylor tavor_rsrc_sw_handles_fini(state, &hdl_info);
14719e39c5baSBill Taylor /* FALLTHROUGH */
14729e39c5baSBill Taylor
14739e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL26:
14749e39c5baSBill Taylor /*
14759e39c5baSBill Taylor * Cleanup the SRQ handle resource pool.
14769e39c5baSBill Taylor *
14779e39c5baSBill Taylor * Note: We only clean up if SRQ is enabled. Otherwise we
14789e39c5baSBill Taylor * simply fallthrough to the next resource cleanup.
14799e39c5baSBill Taylor */
14809e39c5baSBill Taylor if (state->ts_cfg_profile->cp_srq_enable != 0) {
14819e39c5baSBill Taylor hdl_info.swi_rsrcpool =
14829e39c5baSBill Taylor &state->ts_rsrc_hdl[TAVOR_SRQHDL];
14839e39c5baSBill Taylor hdl_info.swi_table_ptr = state->ts_srqhdl;
14849e39c5baSBill Taylor hdl_info.swi_num =
14859e39c5baSBill Taylor ((uint64_t)1 << cfgprof->cp_log_num_srq);
14869e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (tavor_srqhdl_t);
14879e39c5baSBill Taylor tavor_rsrc_sw_handles_fini(state, &hdl_info);
14889e39c5baSBill Taylor }
14899e39c5baSBill Taylor /* FALLTHROUGH */
14909e39c5baSBill Taylor
14919e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL25:
14929e39c5baSBill Taylor /* Cleanup the CQ handle resource pool */
14939e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_CQHDL];
14949e39c5baSBill Taylor hdl_info.swi_table_ptr = state->ts_cqhdl;
14959e39c5baSBill Taylor hdl_info.swi_num =
14969e39c5baSBill Taylor ((uint64_t)1 << cfgprof->cp_log_num_cq);
14979e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (tavor_cqhdl_t);
14989e39c5baSBill Taylor tavor_rsrc_sw_handles_fini(state, &hdl_info);
14999e39c5baSBill Taylor /* FALLTHROUGH */
15009e39c5baSBill Taylor
15019e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL24:
15029e39c5baSBill Taylor /* Cleanup the EQ handle resource pool */
15039e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_EQHDL];
15049e39c5baSBill Taylor hdl_info.swi_table_ptr = NULL;
15059e39c5baSBill Taylor tavor_rsrc_sw_handles_fini(state, &hdl_info);
15069e39c5baSBill Taylor /* FALLTHROUGH */
15079e39c5baSBill Taylor
15089e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL23:
15099e39c5baSBill Taylor /* Cleanup the MR handle resource pool */
15109e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_MRHDL];
15119e39c5baSBill Taylor hdl_info.swi_table_ptr = NULL;
15129e39c5baSBill Taylor tavor_rsrc_sw_handles_fini(state, &hdl_info);
15139e39c5baSBill Taylor /* FALLTHROUGH */
15149e39c5baSBill Taylor
15159e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL22:
15169e39c5baSBill Taylor /* Cleanup the PD handle resource pool */
15179e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_PDHDL];
15189e39c5baSBill Taylor hdl_info.swi_table_ptr = NULL;
15199e39c5baSBill Taylor tavor_rsrc_pd_handles_fini(state, &hdl_info);
15209e39c5baSBill Taylor /* FALLTHROUGH */
15219e39c5baSBill Taylor
15229e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL21:
15239e39c5baSBill Taylor /* Cleanup the EQC table resource pool */
15249e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_EQC];
15259e39c5baSBill Taylor tavor_rsrc_hw_entries_fini(state, &entry_info);
15269e39c5baSBill Taylor /* FALLTHROUGH */
15279e39c5baSBill Taylor
15289e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL20:
15299e39c5baSBill Taylor /* Cleanup the MCG table resource pool */
15309e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_MCG];
15319e39c5baSBill Taylor tavor_rsrc_hw_entries_fini(state, &entry_info);
15329e39c5baSBill Taylor /* FALLTHROUGH */
15339e39c5baSBill Taylor
15349e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL19:
15359e39c5baSBill Taylor /* Cleanup the outstanding command list */
15369e39c5baSBill Taylor tavor_outstanding_cmdlist_fini(state);
15379e39c5baSBill Taylor /* FALLTHROUGH */
15389e39c5baSBill Taylor
15399e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL18:
15409e39c5baSBill Taylor /* Cleanup the "In" mailbox list */
15419e39c5baSBill Taylor tavor_intr_inmbox_list_fini(state);
15429e39c5baSBill Taylor /* FALLTHROUGH */
15439e39c5baSBill Taylor
15449e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL17:
15459e39c5baSBill Taylor /* Cleanup the interrupt "In" mailbox resource pool */
15469e39c5baSBill Taylor mbox_info.mbi_rsrcpool = &state->ts_rsrc_hdl[
15479e39c5baSBill Taylor TAVOR_INTR_IN_MBOX];
15489e39c5baSBill Taylor tavor_rsrc_mbox_fini(state, &mbox_info);
15499e39c5baSBill Taylor /* FALLTHROUGH */
15509e39c5baSBill Taylor
15519e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL16:
15529e39c5baSBill Taylor /* Cleanup the "In" mailbox list */
15539e39c5baSBill Taylor tavor_inmbox_list_fini(state);
15549e39c5baSBill Taylor /* FALLTHROUGH */
15559e39c5baSBill Taylor
15569e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL15:
15579e39c5baSBill Taylor /* Cleanup the "In" mailbox resource pool */
15589e39c5baSBill Taylor mbox_info.mbi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_IN_MBOX];
15599e39c5baSBill Taylor tavor_rsrc_mbox_fini(state, &mbox_info);
15609e39c5baSBill Taylor /* FALLTHROUGH */
15619e39c5baSBill Taylor
15629e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL14:
15639e39c5baSBill Taylor /*
15649e39c5baSBill Taylor * Cleanup the SRQC table resource pool.
15659e39c5baSBill Taylor *
15669e39c5baSBill Taylor * Note: We only clean up if SRQ is enabled. Otherwise we
15679e39c5baSBill Taylor * simply fallthrough to the next resource cleanup.
15689e39c5baSBill Taylor */
15699e39c5baSBill Taylor if (state->ts_cfg_profile->cp_srq_enable != 0) {
15709e39c5baSBill Taylor entry_info.hwi_rsrcpool =
15719e39c5baSBill Taylor &state->ts_rsrc_hdl[TAVOR_SRQC];
15729e39c5baSBill Taylor tavor_rsrc_hw_entries_fini(state, &entry_info);
15739e39c5baSBill Taylor }
15749e39c5baSBill Taylor /* FALLTHROUGH */
15759e39c5baSBill Taylor
15769e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL13:
15779e39c5baSBill Taylor /* Cleanup the UAR scratch table resource pool */
15789e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_UAR_SCR];
15799e39c5baSBill Taylor tavor_rsrc_hw_entries_fini(state, &entry_info);
15809e39c5baSBill Taylor /* FALLTHROUGH */
15819e39c5baSBill Taylor
15829e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL12:
15839e39c5baSBill Taylor /* Cleanup the UDAV table resource pool */
15849e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_UDAV];
15859e39c5baSBill Taylor tavor_rsrc_hw_entries_fini(state, &entry_info);
15869e39c5baSBill Taylor /* FALLTHROUGH */
15879e39c5baSBill Taylor
15889e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL11:
15899e39c5baSBill Taylor /* Cleanup the EQPC table resource pool */
15909e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_EQPC];
15919e39c5baSBill Taylor tavor_rsrc_hw_entries_fini(state, &entry_info);
15929e39c5baSBill Taylor /* FALLTHROUGH */
15939e39c5baSBill Taylor
15949e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL10:
15959e39c5baSBill Taylor /* Cleanup the CQC table resource pool */
15969e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_CQC];
15979e39c5baSBill Taylor tavor_rsrc_hw_entries_fini(state, &entry_info);
15989e39c5baSBill Taylor /* FALLTHROUGH */
15999e39c5baSBill Taylor
16009e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL9:
16019e39c5baSBill Taylor /* Cleanup the RDB table resource pool */
16029e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_RDB];
16039e39c5baSBill Taylor tavor_rsrc_hw_entries_fini(state, &entry_info);
16049e39c5baSBill Taylor /* FALLTHROUGH */
16059e39c5baSBill Taylor
16069e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL8:
16079e39c5baSBill Taylor /* Cleanup the QPC table resource pool */
16089e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_QPC];
16099e39c5baSBill Taylor tavor_rsrc_hw_entries_fini(state, &entry_info);
16109e39c5baSBill Taylor /* FALLTHROUGH */
16119e39c5baSBill Taylor
16129e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL7:
16139e39c5baSBill Taylor /* Cleanup the MTT table resource pool */
16149e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_MTT];
16159e39c5baSBill Taylor tavor_rsrc_hw_entries_fini(state, &entry_info);
16169e39c5baSBill Taylor /* FALLTHROUGH */
16179e39c5baSBill Taylor
16189e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL6:
16199e39c5baSBill Taylor /* Cleanup the MPT table resource pool */
16209e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_MPT];
16219e39c5baSBill Taylor tavor_rsrc_hw_entries_fini(state, &entry_info);
16229e39c5baSBill Taylor /* FALLTHROUGH */
16239e39c5baSBill Taylor
16249e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL5:
16259e39c5baSBill Taylor /* Destroy the vmem arena for DDR memory */
16269e39c5baSBill Taylor vmem_destroy(state->ts_ddrvmem);
16279e39c5baSBill Taylor break;
16289e39c5baSBill Taylor
16299e39c5baSBill Taylor /*
16309e39c5baSBill Taylor * The cleanup below comes from the "Phase 1" initialization step.
16319e39c5baSBill Taylor * (see tavor_rsrc_init_phase1() above)
16329e39c5baSBill Taylor */
16339e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_PHASE1_COMPLETE:
16349e39c5baSBill Taylor /* Cleanup the interrupt "Out" mailbox list */
16359e39c5baSBill Taylor tavor_intr_outmbox_list_fini(state);
16369e39c5baSBill Taylor /* FALLTHROUGH */
16379e39c5baSBill Taylor
16389e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL3:
16399e39c5baSBill Taylor /* Cleanup the "Out" mailbox resource pool */
16409e39c5baSBill Taylor mbox_info.mbi_rsrcpool = &state->ts_rsrc_hdl[
16419e39c5baSBill Taylor TAVOR_INTR_OUT_MBOX];
16429e39c5baSBill Taylor tavor_rsrc_mbox_fini(state, &mbox_info);
16439e39c5baSBill Taylor /* FALLTHROUGH */
16449e39c5baSBill Taylor
16459e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL2:
16469e39c5baSBill Taylor /* Cleanup the "Out" mailbox list */
16479e39c5baSBill Taylor tavor_outmbox_list_fini(state);
16489e39c5baSBill Taylor /* FALLTHROUGH */
16499e39c5baSBill Taylor
16509e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL1:
16519e39c5baSBill Taylor /* Cleanup the "Out" mailbox resource pool */
16529e39c5baSBill Taylor mbox_info.mbi_rsrcpool = &state->ts_rsrc_hdl[TAVOR_OUT_MBOX];
16539e39c5baSBill Taylor tavor_rsrc_mbox_fini(state, &mbox_info);
16549e39c5baSBill Taylor /* FALLTHROUGH */
16559e39c5baSBill Taylor
16569e39c5baSBill Taylor case TAVOR_RSRC_CLEANUP_LEVEL0:
16579e39c5baSBill Taylor /* Free the array of tavor_rsrc_pool_info_t's */
16589e39c5baSBill Taylor kmem_free(state->ts_rsrc_hdl, TAVOR_NUM_RESOURCES *
16599e39c5baSBill Taylor sizeof (tavor_rsrc_pool_info_t));
16609e39c5baSBill Taylor kmem_cache_destroy(state->ts_rsrc_cache);
16619e39c5baSBill Taylor break;
16629e39c5baSBill Taylor
16639e39c5baSBill Taylor default:
16649e39c5baSBill Taylor TAVOR_WARNING(state, "unexpected resource cleanup level");
16659e39c5baSBill Taylor }
16669e39c5baSBill Taylor }
16679e39c5baSBill Taylor
16689e39c5baSBill Taylor
16699e39c5baSBill Taylor /*
16709e39c5baSBill Taylor * tavor_rsrc_mbox_init()
16719e39c5baSBill Taylor * Context: Only called from attach() path context
16729e39c5baSBill Taylor */
16739e39c5baSBill Taylor static int
tavor_rsrc_mbox_init(tavor_state_t * state,tavor_rsrc_mbox_info_t * info)16749e39c5baSBill Taylor tavor_rsrc_mbox_init(tavor_state_t *state, tavor_rsrc_mbox_info_t *info)
16759e39c5baSBill Taylor {
16769e39c5baSBill Taylor tavor_rsrc_pool_info_t *rsrc_pool;
16779e39c5baSBill Taylor tavor_rsrc_priv_mbox_t *priv;
16789e39c5baSBill Taylor vmem_t *vmp;
16799e39c5baSBill Taylor uint64_t offset;
16809e39c5baSBill Taylor uint_t dma_xfer_mode;
16819e39c5baSBill Taylor
16829e39c5baSBill Taylor ASSERT(state != NULL);
16839e39c5baSBill Taylor ASSERT(info != NULL);
16849e39c5baSBill Taylor
16859e39c5baSBill Taylor rsrc_pool = info->mbi_rsrcpool;
16869e39c5baSBill Taylor ASSERT(rsrc_pool != NULL);
16879e39c5baSBill Taylor
16889e39c5baSBill Taylor dma_xfer_mode = state->ts_cfg_profile->cp_streaming_consistent;
16899e39c5baSBill Taylor
16909e39c5baSBill Taylor /* Allocate and initialize mailbox private structure */
16919e39c5baSBill Taylor priv = kmem_zalloc(sizeof (tavor_rsrc_priv_mbox_t), KM_SLEEP);
16929e39c5baSBill Taylor priv->pmb_dip = state->ts_dip;
16939e39c5baSBill Taylor priv->pmb_acchdl = state->ts_reg_ddrhdl;
16949e39c5baSBill Taylor priv->pmb_devaccattr = state->ts_reg_accattr;
16959e39c5baSBill Taylor priv->pmb_xfer_mode = dma_xfer_mode;
16969e39c5baSBill Taylor
16979e39c5baSBill Taylor /*
16989e39c5baSBill Taylor * Initialize many of the default DMA attributes. Then set alignment
16999e39c5baSBill Taylor * and scatter-gather restrictions specific for mailbox memory.
17009e39c5baSBill Taylor */
17019e39c5baSBill Taylor tavor_dma_attr_init(&priv->pmb_dmaattr);
17029e39c5baSBill Taylor priv->pmb_dmaattr.dma_attr_align = TAVOR_MBOX_ALIGN;
17039e39c5baSBill Taylor priv->pmb_dmaattr.dma_attr_sgllen = 1;
17049e39c5baSBill Taylor
17059e39c5baSBill Taylor rsrc_pool->rsrc_private = priv;
17069e39c5baSBill Taylor
17079e39c5baSBill Taylor /* Is object in DDR memory or system memory? */
17089e39c5baSBill Taylor if (rsrc_pool->rsrc_loc == TAVOR_IN_DDR) {
17099e39c5baSBill Taylor rsrc_pool->rsrc_ddr_offset = vmem_xalloc(state->ts_ddrvmem,
17109e39c5baSBill Taylor rsrc_pool->rsrc_pool_size, rsrc_pool->rsrc_align,
17119e39c5baSBill Taylor 0, 0, NULL, NULL, VM_SLEEP);
17129e39c5baSBill Taylor if (rsrc_pool->rsrc_ddr_offset == NULL) {
17139e39c5baSBill Taylor /* Unable to alloc space for mailboxes */
17149e39c5baSBill Taylor kmem_free(priv, sizeof (tavor_rsrc_priv_mbox_t));
17159e39c5baSBill Taylor return (DDI_FAILURE);
17169e39c5baSBill Taylor }
17179e39c5baSBill Taylor
17189e39c5baSBill Taylor /* Calculate offset and starting point (in DDR) */
17199e39c5baSBill Taylor offset = ((uintptr_t)rsrc_pool->rsrc_ddr_offset -
17209e39c5baSBill Taylor state->ts_ddr.ddr_baseaddr);
17219e39c5baSBill Taylor rsrc_pool->rsrc_start =
17229e39c5baSBill Taylor (void *)(uintptr_t)((uintptr_t)state->ts_reg_ddr_baseaddr +
17239e39c5baSBill Taylor offset);
17249e39c5baSBill Taylor
17259e39c5baSBill Taylor /* Create new vmem arena for the mailboxes */
17269e39c5baSBill Taylor vmp = vmem_create(info->mbi_rsrcname,
17279e39c5baSBill Taylor rsrc_pool->rsrc_ddr_offset, rsrc_pool->rsrc_pool_size,
17289e39c5baSBill Taylor rsrc_pool->rsrc_quantum, NULL, NULL, NULL, 0, VM_SLEEP);
17299e39c5baSBill Taylor if (vmp == NULL) {
17309e39c5baSBill Taylor /* Unable to create vmem arena */
17319e39c5baSBill Taylor vmem_xfree(state->ts_ddrvmem,
17329e39c5baSBill Taylor rsrc_pool->rsrc_ddr_offset,
17339e39c5baSBill Taylor rsrc_pool->rsrc_pool_size);
17349e39c5baSBill Taylor kmem_free(priv, sizeof (tavor_rsrc_priv_mbox_t));
17359e39c5baSBill Taylor return (DDI_FAILURE);
17369e39c5baSBill Taylor }
17379e39c5baSBill Taylor rsrc_pool->rsrc_vmp = vmp;
17389e39c5baSBill Taylor } else {
17399e39c5baSBill Taylor rsrc_pool->rsrc_ddr_offset = NULL;
17409e39c5baSBill Taylor rsrc_pool->rsrc_start = NULL;
17419e39c5baSBill Taylor rsrc_pool->rsrc_vmp = NULL;
17429e39c5baSBill Taylor }
17439e39c5baSBill Taylor
17449e39c5baSBill Taylor return (DDI_SUCCESS);
17459e39c5baSBill Taylor }
17469e39c5baSBill Taylor
17479e39c5baSBill Taylor
17489e39c5baSBill Taylor /*
17499e39c5baSBill Taylor * tavor_rsrc_mbox_fini()
17509e39c5baSBill Taylor * Context: Only called from attach() and/or detach() path contexts
17519e39c5baSBill Taylor */
17529e39c5baSBill Taylor static void
tavor_rsrc_mbox_fini(tavor_state_t * state,tavor_rsrc_mbox_info_t * info)17539e39c5baSBill Taylor tavor_rsrc_mbox_fini(tavor_state_t *state, tavor_rsrc_mbox_info_t *info)
17549e39c5baSBill Taylor {
17559e39c5baSBill Taylor tavor_rsrc_pool_info_t *rsrc_pool;
17569e39c5baSBill Taylor
17579e39c5baSBill Taylor ASSERT(state != NULL);
17589e39c5baSBill Taylor ASSERT(info != NULL);
17599e39c5baSBill Taylor
17609e39c5baSBill Taylor rsrc_pool = info->mbi_rsrcpool;
17619e39c5baSBill Taylor ASSERT(rsrc_pool != NULL);
17629e39c5baSBill Taylor
17639e39c5baSBill Taylor /* If mailboxes are DDR memory, then destroy and free up vmem */
17649e39c5baSBill Taylor if (rsrc_pool->rsrc_loc == TAVOR_IN_DDR) {
17659e39c5baSBill Taylor
17669e39c5baSBill Taylor /* Destroy the specially created mbox vmem arena */
17679e39c5baSBill Taylor vmem_destroy(rsrc_pool->rsrc_vmp);
17689e39c5baSBill Taylor
17699e39c5baSBill Taylor /* Free up the region from the ddr_vmem arena */
17709e39c5baSBill Taylor vmem_xfree(state->ts_ddrvmem, rsrc_pool->rsrc_ddr_offset,
17719e39c5baSBill Taylor rsrc_pool->rsrc_pool_size);
17729e39c5baSBill Taylor }
17739e39c5baSBill Taylor
17749e39c5baSBill Taylor /* Free up the private struct */
17759e39c5baSBill Taylor kmem_free(rsrc_pool->rsrc_private, sizeof (tavor_rsrc_priv_mbox_t));
17769e39c5baSBill Taylor }
17779e39c5baSBill Taylor
17789e39c5baSBill Taylor
17799e39c5baSBill Taylor /*
17809e39c5baSBill Taylor * tavor_rsrc_hw_entries_init()
17819e39c5baSBill Taylor * Context: Only called from attach() path context
17829e39c5baSBill Taylor */
17839e39c5baSBill Taylor static int
tavor_rsrc_hw_entries_init(tavor_state_t * state,tavor_rsrc_hw_entry_info_t * info)17849e39c5baSBill Taylor tavor_rsrc_hw_entries_init(tavor_state_t *state,
17859e39c5baSBill Taylor tavor_rsrc_hw_entry_info_t *info)
17869e39c5baSBill Taylor {
17879e39c5baSBill Taylor tavor_rsrc_pool_info_t *rsrc_pool;
17889e39c5baSBill Taylor tavor_rsrc_t *rsvd_rsrc = NULL;
17899e39c5baSBill Taylor vmem_t *vmp;
17909e39c5baSBill Taylor uint64_t num_hwentry, max_hwentry, num_prealloc;
17919e39c5baSBill Taylor uint64_t offset;
17929e39c5baSBill Taylor int status;
17939e39c5baSBill Taylor
17949e39c5baSBill Taylor ASSERT(state != NULL);
17959e39c5baSBill Taylor ASSERT(info != NULL);
17969e39c5baSBill Taylor
17979e39c5baSBill Taylor rsrc_pool = info->hwi_rsrcpool;
17989e39c5baSBill Taylor ASSERT(rsrc_pool != NULL);
17999e39c5baSBill Taylor num_hwentry = info->hwi_num;
18009e39c5baSBill Taylor max_hwentry = info->hwi_max;
18019e39c5baSBill Taylor num_prealloc = info->hwi_prealloc;
18029e39c5baSBill Taylor
18039e39c5baSBill Taylor /* Make sure number of HW entries makes sense */
18049e39c5baSBill Taylor if (num_hwentry > max_hwentry) {
18059e39c5baSBill Taylor return (DDI_FAILURE);
18069e39c5baSBill Taylor }
18079e39c5baSBill Taylor
18089e39c5baSBill Taylor /*
18099e39c5baSBill Taylor * Determine if we need to allocate DDR space to set up the
18109e39c5baSBill Taylor * "rsrc_start" pointer. Not necessary if "rsrc_start" has already
18119e39c5baSBill Taylor * been initialized (as is the case for the UAR page init).
18129e39c5baSBill Taylor */
18139e39c5baSBill Taylor if (rsrc_pool->rsrc_start == NULL) {
18149e39c5baSBill Taylor /* Make sure HW entries table is aligned as specified */
18159e39c5baSBill Taylor rsrc_pool->rsrc_ddr_offset = vmem_xalloc(state->ts_ddrvmem,
18169e39c5baSBill Taylor rsrc_pool->rsrc_pool_size, rsrc_pool->rsrc_align,
18179e39c5baSBill Taylor 0, 0, NULL, NULL, VM_NOSLEEP | VM_FIRSTFIT);
18189e39c5baSBill Taylor if (rsrc_pool->rsrc_ddr_offset == NULL) {
18199e39c5baSBill Taylor /* Unable to alloc space for aligned HW table */
18209e39c5baSBill Taylor return (DDI_FAILURE);
18219e39c5baSBill Taylor }
18229e39c5baSBill Taylor
18239e39c5baSBill Taylor /* Calculate offset and starting point (in DDR) */
18249e39c5baSBill Taylor offset = ((uintptr_t)rsrc_pool->rsrc_ddr_offset -
18259e39c5baSBill Taylor state->ts_ddr.ddr_baseaddr);
18269e39c5baSBill Taylor rsrc_pool->rsrc_start =
18279e39c5baSBill Taylor (void *)(uintptr_t)((uintptr_t)state->ts_reg_ddr_baseaddr +
18289e39c5baSBill Taylor offset);
18299e39c5baSBill Taylor } else {
18309e39c5baSBill Taylor rsrc_pool->rsrc_ddr_offset = rsrc_pool->rsrc_start;
18319e39c5baSBill Taylor }
18329e39c5baSBill Taylor
18339e39c5baSBill Taylor /*
18349e39c5baSBill Taylor * Create new vmem arena for the HW entries table (if rsrc_quantum
18359e39c5baSBill Taylor * is non-zero). Otherwise if rsrc_quantum is zero, then these HW
18369e39c5baSBill Taylor * entries are not going to be dynamically allocatable (i.e. they
18379e39c5baSBill Taylor * won't be allocated/freed through tavor_rsrc_alloc/free). This
18389e39c5baSBill Taylor * latter option is used for EQPC and UARSCR resource which are, in
18399e39c5baSBill Taylor * fact, managed by the Tavor hardware.
18409e39c5baSBill Taylor */
18419e39c5baSBill Taylor if (rsrc_pool->rsrc_quantum != 0) {
18429e39c5baSBill Taylor vmp = vmem_create(info->hwi_rsrcname,
18439e39c5baSBill Taylor rsrc_pool->rsrc_ddr_offset, rsrc_pool->rsrc_pool_size,
18449e39c5baSBill Taylor rsrc_pool->rsrc_quantum, NULL, NULL, NULL, 0, VM_SLEEP);
18459e39c5baSBill Taylor if (vmp == NULL) {
18469e39c5baSBill Taylor /* Unable to create vmem arena */
18479e39c5baSBill Taylor if (rsrc_pool->rsrc_ddr_offset !=
18489e39c5baSBill Taylor rsrc_pool->rsrc_start) {
18499e39c5baSBill Taylor vmem_xfree(state->ts_ddrvmem,
18509e39c5baSBill Taylor rsrc_pool->rsrc_ddr_offset,
18519e39c5baSBill Taylor rsrc_pool->rsrc_pool_size);
18529e39c5baSBill Taylor }
18539e39c5baSBill Taylor return (DDI_FAILURE);
18549e39c5baSBill Taylor }
18559e39c5baSBill Taylor rsrc_pool->rsrc_vmp = vmp;
18569e39c5baSBill Taylor } else {
18579e39c5baSBill Taylor rsrc_pool->rsrc_vmp = NULL;
18589e39c5baSBill Taylor }
18599e39c5baSBill Taylor
18609e39c5baSBill Taylor /* The first HW entries may be reserved by Tavor firmware */
18619e39c5baSBill Taylor if (num_prealloc != 0) {
18629e39c5baSBill Taylor status = tavor_rsrc_alloc(state, rsrc_pool->rsrc_type,
18639e39c5baSBill Taylor num_prealloc, TAVOR_SLEEP, &rsvd_rsrc);
18649e39c5baSBill Taylor if (status != DDI_SUCCESS) {
18659e39c5baSBill Taylor /* Unable to preallocate the reserved HW entries */
18669e39c5baSBill Taylor if (rsrc_pool->rsrc_vmp != NULL) {
18679e39c5baSBill Taylor vmem_destroy(rsrc_pool->rsrc_vmp);
18689e39c5baSBill Taylor }
18699e39c5baSBill Taylor if (rsrc_pool->rsrc_ddr_offset !=
18709e39c5baSBill Taylor rsrc_pool->rsrc_start) {
18719e39c5baSBill Taylor vmem_xfree(state->ts_ddrvmem,
18729e39c5baSBill Taylor rsrc_pool->rsrc_ddr_offset,
18739e39c5baSBill Taylor rsrc_pool->rsrc_pool_size);
18749e39c5baSBill Taylor }
18759e39c5baSBill Taylor return (DDI_FAILURE);
18769e39c5baSBill Taylor }
18779e39c5baSBill Taylor }
18789e39c5baSBill Taylor rsrc_pool->rsrc_private = rsvd_rsrc;
18799e39c5baSBill Taylor
18809e39c5baSBill Taylor return (DDI_SUCCESS);
18819e39c5baSBill Taylor }
18829e39c5baSBill Taylor
18839e39c5baSBill Taylor
18849e39c5baSBill Taylor /*
18859e39c5baSBill Taylor * tavor_rsrc_hw_entries_fini()
18869e39c5baSBill Taylor * Context: Only called from attach() and/or detach() path contexts
18879e39c5baSBill Taylor */
18889e39c5baSBill Taylor static void
tavor_rsrc_hw_entries_fini(tavor_state_t * state,tavor_rsrc_hw_entry_info_t * info)18899e39c5baSBill Taylor tavor_rsrc_hw_entries_fini(tavor_state_t *state,
18909e39c5baSBill Taylor tavor_rsrc_hw_entry_info_t *info)
18919e39c5baSBill Taylor {
18929e39c5baSBill Taylor tavor_rsrc_pool_info_t *rsrc_pool;
18939e39c5baSBill Taylor tavor_rsrc_t *rsvd_rsrc;
18949e39c5baSBill Taylor
18959e39c5baSBill Taylor ASSERT(state != NULL);
18969e39c5baSBill Taylor ASSERT(info != NULL);
18979e39c5baSBill Taylor
18989e39c5baSBill Taylor rsrc_pool = info->hwi_rsrcpool;
18999e39c5baSBill Taylor ASSERT(rsrc_pool != NULL);
19009e39c5baSBill Taylor
19019e39c5baSBill Taylor /* Free up any "reserved" (i.e. preallocated) HW entries */
19029e39c5baSBill Taylor rsvd_rsrc = (tavor_rsrc_t *)rsrc_pool->rsrc_private;
19039e39c5baSBill Taylor if (rsvd_rsrc != NULL) {
19049e39c5baSBill Taylor tavor_rsrc_free(state, &rsvd_rsrc);
19059e39c5baSBill Taylor }
19069e39c5baSBill Taylor
19079e39c5baSBill Taylor /*
19089e39c5baSBill Taylor * If we've actually setup a vmem arena for the HW entries, then
19099e39c5baSBill Taylor * destroy it now
19109e39c5baSBill Taylor */
19119e39c5baSBill Taylor if (rsrc_pool->rsrc_vmp != NULL) {
19129e39c5baSBill Taylor vmem_destroy(rsrc_pool->rsrc_vmp);
19139e39c5baSBill Taylor }
19149e39c5baSBill Taylor
19159e39c5baSBill Taylor /*
19169e39c5baSBill Taylor * Determine if a region was allocated from the tavor_ddr_vmem
19179e39c5baSBill Taylor * arena (and free it up if necessary)
19189e39c5baSBill Taylor */
19199e39c5baSBill Taylor if (rsrc_pool->rsrc_ddr_offset != rsrc_pool->rsrc_start) {
19209e39c5baSBill Taylor vmem_xfree(state->ts_ddrvmem, rsrc_pool->rsrc_ddr_offset,
19219e39c5baSBill Taylor rsrc_pool->rsrc_pool_size);
19229e39c5baSBill Taylor }
19239e39c5baSBill Taylor }
19249e39c5baSBill Taylor
19259e39c5baSBill Taylor
19269e39c5baSBill Taylor /*
19279e39c5baSBill Taylor * tavor_rsrc_sw_handles_init()
19289e39c5baSBill Taylor * Context: Only called from attach() path context
19299e39c5baSBill Taylor */
19309e39c5baSBill Taylor /* ARGSUSED */
19319e39c5baSBill Taylor static int
tavor_rsrc_sw_handles_init(tavor_state_t * state,tavor_rsrc_sw_hdl_info_t * info)19329e39c5baSBill Taylor tavor_rsrc_sw_handles_init(tavor_state_t *state, tavor_rsrc_sw_hdl_info_t *info)
19339e39c5baSBill Taylor {
19349e39c5baSBill Taylor tavor_rsrc_pool_info_t *rsrc_pool;
19359e39c5baSBill Taylor uint64_t num_swhdl, max_swhdl, prealloc_sz;
19369e39c5baSBill Taylor
19379e39c5baSBill Taylor ASSERT(state != NULL);
19389e39c5baSBill Taylor ASSERT(info != NULL);
19399e39c5baSBill Taylor
19409e39c5baSBill Taylor rsrc_pool = info->swi_rsrcpool;
19419e39c5baSBill Taylor ASSERT(rsrc_pool != NULL);
19429e39c5baSBill Taylor num_swhdl = info->swi_num;
19439e39c5baSBill Taylor max_swhdl = info->swi_max;
19449e39c5baSBill Taylor prealloc_sz = info->swi_prealloc_sz;
19459e39c5baSBill Taylor
19469e39c5baSBill Taylor /* Make sure number of SW handles makes sense */
19479e39c5baSBill Taylor if (num_swhdl > max_swhdl) {
19489e39c5baSBill Taylor return (DDI_FAILURE);
19499e39c5baSBill Taylor }
19509e39c5baSBill Taylor
19519e39c5baSBill Taylor /*
19529e39c5baSBill Taylor * Depending on the flags parameter, create a kmem_cache for some
19539e39c5baSBill Taylor * number of software handle structures. Note: kmem_cache_create()
19549e39c5baSBill Taylor * will SLEEP until successful.
19559e39c5baSBill Taylor */
19569e39c5baSBill Taylor if (info->swi_flags & TAVOR_SWHDL_KMEMCACHE_INIT) {
19579e39c5baSBill Taylor rsrc_pool->rsrc_private = kmem_cache_create(
19589e39c5baSBill Taylor info->swi_rsrcname, rsrc_pool->rsrc_quantum, 0,
19599e39c5baSBill Taylor info->swi_constructor, info->swi_destructor, NULL,
19609e39c5baSBill Taylor rsrc_pool->rsrc_state, NULL, 0);
19619e39c5baSBill Taylor }
19629e39c5baSBill Taylor
19639e39c5baSBill Taylor /* Allocate the central list of SW handle pointers */
19649e39c5baSBill Taylor if (info->swi_flags & TAVOR_SWHDL_TABLE_INIT) {
19659e39c5baSBill Taylor info->swi_table_ptr = kmem_zalloc(num_swhdl * prealloc_sz,
19669e39c5baSBill Taylor KM_SLEEP);
19679e39c5baSBill Taylor }
19689e39c5baSBill Taylor
19699e39c5baSBill Taylor return (DDI_SUCCESS);
19709e39c5baSBill Taylor }
19719e39c5baSBill Taylor
19729e39c5baSBill Taylor
19739e39c5baSBill Taylor /*
19749e39c5baSBill Taylor * tavor_rsrc_sw_handles_fini()
19759e39c5baSBill Taylor * Context: Only called from attach() and/or detach() path contexts
19769e39c5baSBill Taylor */
19779e39c5baSBill Taylor /* ARGSUSED */
19789e39c5baSBill Taylor static void
tavor_rsrc_sw_handles_fini(tavor_state_t * state,tavor_rsrc_sw_hdl_info_t * info)19799e39c5baSBill Taylor tavor_rsrc_sw_handles_fini(tavor_state_t *state, tavor_rsrc_sw_hdl_info_t *info)
19809e39c5baSBill Taylor {
19819e39c5baSBill Taylor tavor_rsrc_pool_info_t *rsrc_pool;
19829e39c5baSBill Taylor uint64_t num_swhdl, prealloc_sz;
19839e39c5baSBill Taylor
19849e39c5baSBill Taylor ASSERT(state != NULL);
19859e39c5baSBill Taylor ASSERT(info != NULL);
19869e39c5baSBill Taylor
19879e39c5baSBill Taylor rsrc_pool = info->swi_rsrcpool;
19889e39c5baSBill Taylor num_swhdl = info->swi_num;
19899e39c5baSBill Taylor prealloc_sz = info->swi_prealloc_sz;
19909e39c5baSBill Taylor
19919e39c5baSBill Taylor /*
19929e39c5baSBill Taylor * If a "software handle" kmem_cache exists for this resource, then
19939e39c5baSBill Taylor * destroy it now
19949e39c5baSBill Taylor */
19959e39c5baSBill Taylor if (rsrc_pool != NULL) {
19969e39c5baSBill Taylor kmem_cache_destroy(rsrc_pool->rsrc_private);
19979e39c5baSBill Taylor }
19989e39c5baSBill Taylor
19999e39c5baSBill Taylor /* Free up this central list of SW handle pointers */
20009e39c5baSBill Taylor if (info->swi_table_ptr != NULL) {
20019e39c5baSBill Taylor kmem_free(info->swi_table_ptr, num_swhdl * prealloc_sz);
20029e39c5baSBill Taylor }
20039e39c5baSBill Taylor }
20049e39c5baSBill Taylor
20059e39c5baSBill Taylor
20069e39c5baSBill Taylor /*
20079e39c5baSBill Taylor * tavor_rsrc_pd_handles_init()
20089e39c5baSBill Taylor * Context: Only called from attach() path context
20099e39c5baSBill Taylor */
20109e39c5baSBill Taylor static int
tavor_rsrc_pd_handles_init(tavor_state_t * state,tavor_rsrc_sw_hdl_info_t * info)20119e39c5baSBill Taylor tavor_rsrc_pd_handles_init(tavor_state_t *state, tavor_rsrc_sw_hdl_info_t *info)
20129e39c5baSBill Taylor {
20139e39c5baSBill Taylor tavor_rsrc_pool_info_t *rsrc_pool;
20149e39c5baSBill Taylor vmem_t *vmp;
20159e39c5baSBill Taylor char vmem_name[TAVOR_RSRC_NAME_MAXLEN];
20169e39c5baSBill Taylor int status;
20179e39c5baSBill Taylor
20189e39c5baSBill Taylor ASSERT(state != NULL);
20199e39c5baSBill Taylor ASSERT(info != NULL);
20209e39c5baSBill Taylor
20219e39c5baSBill Taylor rsrc_pool = info->swi_rsrcpool;
20229e39c5baSBill Taylor ASSERT(rsrc_pool != NULL);
20239e39c5baSBill Taylor
20249e39c5baSBill Taylor /* Initialize the resource pool for software handle table */
20259e39c5baSBill Taylor status = tavor_rsrc_sw_handles_init(state, info);
20269e39c5baSBill Taylor if (status != DDI_SUCCESS) {
20279e39c5baSBill Taylor return (DDI_FAILURE);
20289e39c5baSBill Taylor }
20299e39c5baSBill Taylor
20309e39c5baSBill Taylor /* Build vmem arena name from Tavor instance */
20319e39c5baSBill Taylor TAVOR_RSRC_NAME(vmem_name, TAVOR_PDHDL_VMEM);
20329e39c5baSBill Taylor
20339e39c5baSBill Taylor /* Create new vmem arena for PD numbers */
20349e39c5baSBill Taylor vmp = vmem_create(vmem_name, (caddr_t)1, info->swi_num, 1, NULL,
20359e39c5baSBill Taylor NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER);
20369e39c5baSBill Taylor if (vmp == NULL) {
20379e39c5baSBill Taylor /* Unable to create vmem arena */
20389e39c5baSBill Taylor info->swi_table_ptr = NULL;
20399e39c5baSBill Taylor tavor_rsrc_sw_handles_fini(state, info);
20409e39c5baSBill Taylor return (DDI_FAILURE);
20419e39c5baSBill Taylor }
20429e39c5baSBill Taylor rsrc_pool->rsrc_vmp = vmp;
20439e39c5baSBill Taylor
20449e39c5baSBill Taylor return (DDI_SUCCESS);
20459e39c5baSBill Taylor }
20469e39c5baSBill Taylor
20479e39c5baSBill Taylor
20489e39c5baSBill Taylor /*
20499e39c5baSBill Taylor * tavor_rsrc_pd_handles_fini()
20509e39c5baSBill Taylor * Context: Only called from attach() and/or detach() path contexts
20519e39c5baSBill Taylor */
20529e39c5baSBill Taylor static void
tavor_rsrc_pd_handles_fini(tavor_state_t * state,tavor_rsrc_sw_hdl_info_t * info)20539e39c5baSBill Taylor tavor_rsrc_pd_handles_fini(tavor_state_t *state, tavor_rsrc_sw_hdl_info_t *info)
20549e39c5baSBill Taylor {
20559e39c5baSBill Taylor tavor_rsrc_pool_info_t *rsrc_pool;
20569e39c5baSBill Taylor
20579e39c5baSBill Taylor ASSERT(state != NULL);
20589e39c5baSBill Taylor ASSERT(info != NULL);
20599e39c5baSBill Taylor
20609e39c5baSBill Taylor rsrc_pool = info->swi_rsrcpool;
20619e39c5baSBill Taylor
20629e39c5baSBill Taylor /* Destroy the specially created UAR scratch table vmem arena */
20639e39c5baSBill Taylor vmem_destroy(rsrc_pool->rsrc_vmp);
20649e39c5baSBill Taylor
20659e39c5baSBill Taylor /* Destroy the "tavor_sw_pd_t" kmem_cache */
20669e39c5baSBill Taylor tavor_rsrc_sw_handles_fini(state, info);
20679e39c5baSBill Taylor }
20689e39c5baSBill Taylor
20699e39c5baSBill Taylor
20709e39c5baSBill Taylor /*
20719e39c5baSBill Taylor * tavor_rsrc_mbox_alloc()
20729e39c5baSBill Taylor * Context: Only called from attach() path context
20739e39c5baSBill Taylor */
20749e39c5baSBill Taylor static int
tavor_rsrc_mbox_alloc(tavor_rsrc_pool_info_t * pool_info,uint_t num,tavor_rsrc_t * hdl)20759e39c5baSBill Taylor tavor_rsrc_mbox_alloc(tavor_rsrc_pool_info_t *pool_info, uint_t num,
20769e39c5baSBill Taylor tavor_rsrc_t *hdl)
20779e39c5baSBill Taylor {
20789e39c5baSBill Taylor tavor_rsrc_priv_mbox_t *priv;
20799e39c5baSBill Taylor void *addr;
20809e39c5baSBill Taylor caddr_t kaddr;
20819e39c5baSBill Taylor uint64_t offset;
20829e39c5baSBill Taylor size_t real_len, temp_len;
20839e39c5baSBill Taylor int status;
20849e39c5baSBill Taylor
20859e39c5baSBill Taylor ASSERT(pool_info != NULL);
20869e39c5baSBill Taylor ASSERT(hdl != NULL);
20879e39c5baSBill Taylor
20889e39c5baSBill Taylor /* Get the private pointer for the mailboxes */
20899e39c5baSBill Taylor priv = pool_info->rsrc_private;
20909e39c5baSBill Taylor ASSERT(priv != NULL);
20919e39c5baSBill Taylor
20929e39c5baSBill Taylor /*
20939e39c5baSBill Taylor * Allocate a DMA handle for the mailbox. This will be used for
20949e39c5baSBill Taylor * two purposes (potentially). First, it could be used below in
20959e39c5baSBill Taylor * the call to ddi_dma_mem_alloc() - if the mailbox is to come from
20969e39c5baSBill Taylor * system memory. Second, it is definitely used later to bind
20979e39c5baSBill Taylor * the mailbox for DMA access from/by the hardware.
20989e39c5baSBill Taylor */
20999e39c5baSBill Taylor status = ddi_dma_alloc_handle(priv->pmb_dip, &priv->pmb_dmaattr,
21009e39c5baSBill Taylor DDI_DMA_SLEEP, NULL, &hdl->tr_dmahdl);
21019e39c5baSBill Taylor if (status != DDI_SUCCESS) {
21029e39c5baSBill Taylor return (DDI_FAILURE);
21039e39c5baSBill Taylor }
21049e39c5baSBill Taylor
21059e39c5baSBill Taylor /* Is mailbox in DDR memory or system memory? */
21069e39c5baSBill Taylor if (pool_info->rsrc_loc == TAVOR_IN_DDR) {
21079e39c5baSBill Taylor /* Use vmem_alloc() to get DDR address of mbox */
21089e39c5baSBill Taylor hdl->tr_len = (num * pool_info->rsrc_quantum);
21099e39c5baSBill Taylor addr = vmem_alloc(pool_info->rsrc_vmp, hdl->tr_len,
21109e39c5baSBill Taylor VM_SLEEP);
21119e39c5baSBill Taylor if (addr == NULL) {
21129e39c5baSBill Taylor /* No more DDR available for mailbox entries */
21139e39c5baSBill Taylor ddi_dma_free_handle(&hdl->tr_dmahdl);
21149e39c5baSBill Taylor return (DDI_FAILURE);
21159e39c5baSBill Taylor }
21169e39c5baSBill Taylor hdl->tr_acchdl = priv->pmb_acchdl;
21179e39c5baSBill Taylor
21189e39c5baSBill Taylor /* Calculate kernel virtual address (from the DDR offset) */
21199e39c5baSBill Taylor offset = ((uintptr_t)addr -
21209e39c5baSBill Taylor (uintptr_t)pool_info->rsrc_ddr_offset);
21219e39c5baSBill Taylor hdl->tr_addr = (void *)(uintptr_t)(offset +
21229e39c5baSBill Taylor (uintptr_t)pool_info->rsrc_start);
21239e39c5baSBill Taylor
21249e39c5baSBill Taylor } else { /* TAVOR_IN_SYSMEM */
21259e39c5baSBill Taylor
21269e39c5baSBill Taylor /* Use ddi_dma_mem_alloc() to get memory for mailbox */
21279e39c5baSBill Taylor temp_len = (num * pool_info->rsrc_quantum);
21289e39c5baSBill Taylor status = ddi_dma_mem_alloc(hdl->tr_dmahdl, temp_len,
21299e39c5baSBill Taylor &priv->pmb_devaccattr, priv->pmb_xfer_mode, DDI_DMA_SLEEP,
21309e39c5baSBill Taylor NULL, &kaddr, &real_len, &hdl->tr_acchdl);
21319e39c5baSBill Taylor if (status != DDI_SUCCESS) {
21329e39c5baSBill Taylor /* No more sys memory available for mailbox entries */
21339e39c5baSBill Taylor ddi_dma_free_handle(&hdl->tr_dmahdl);
21349e39c5baSBill Taylor return (DDI_FAILURE);
21359e39c5baSBill Taylor }
21369e39c5baSBill Taylor hdl->tr_addr = (void *)kaddr;
21379e39c5baSBill Taylor hdl->tr_len = real_len;
21389e39c5baSBill Taylor }
21399e39c5baSBill Taylor
21409e39c5baSBill Taylor return (DDI_SUCCESS);
21419e39c5baSBill Taylor }
21429e39c5baSBill Taylor
21439e39c5baSBill Taylor
21449e39c5baSBill Taylor /*
21459e39c5baSBill Taylor * tavor_rsrc_mbox_free()
21469e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
21479e39c5baSBill Taylor */
21489e39c5baSBill Taylor static void
tavor_rsrc_mbox_free(tavor_rsrc_pool_info_t * pool_info,tavor_rsrc_t * hdl)21499e39c5baSBill Taylor tavor_rsrc_mbox_free(tavor_rsrc_pool_info_t *pool_info, tavor_rsrc_t *hdl)
21509e39c5baSBill Taylor {
21519e39c5baSBill Taylor void *addr;
21529e39c5baSBill Taylor uint64_t offset;
21539e39c5baSBill Taylor
21549e39c5baSBill Taylor ASSERT(pool_info != NULL);
21559e39c5baSBill Taylor ASSERT(hdl != NULL);
21569e39c5baSBill Taylor
21579e39c5baSBill Taylor /* Is mailbox in DDR memory or system memory? */
21589e39c5baSBill Taylor if (pool_info->rsrc_loc == TAVOR_IN_DDR) {
21599e39c5baSBill Taylor
21609e39c5baSBill Taylor /* Calculate the allocated address (the mbox's DDR offset) */
21619e39c5baSBill Taylor offset = ((uintptr_t)hdl->tr_addr -
21629e39c5baSBill Taylor (uintptr_t)pool_info->rsrc_start);
21639e39c5baSBill Taylor addr = (void *)(uintptr_t)(offset +
21649e39c5baSBill Taylor (uintptr_t)pool_info->rsrc_ddr_offset);
21659e39c5baSBill Taylor
21669e39c5baSBill Taylor /* Use vmem_free() to free up DDR memory for mailbox */
21679e39c5baSBill Taylor vmem_free(pool_info->rsrc_vmp, addr, hdl->tr_len);
21689e39c5baSBill Taylor
21699e39c5baSBill Taylor } else { /* TAVOR_IN_SYSMEM */
21709e39c5baSBill Taylor
21719e39c5baSBill Taylor /* Use ddi_dma_mem_free() to free up sys memory for mailbox */
21729e39c5baSBill Taylor ddi_dma_mem_free(&hdl->tr_acchdl);
21739e39c5baSBill Taylor }
21749e39c5baSBill Taylor
21759e39c5baSBill Taylor /* Free the DMA handle for the mailbox */
21769e39c5baSBill Taylor ddi_dma_free_handle(&hdl->tr_dmahdl);
21779e39c5baSBill Taylor }
21789e39c5baSBill Taylor
21799e39c5baSBill Taylor
21809e39c5baSBill Taylor /*
21819e39c5baSBill Taylor * tavor_rsrc_hw_entry_alloc()
21829e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
21839e39c5baSBill Taylor */
21849e39c5baSBill Taylor static int
tavor_rsrc_hw_entry_alloc(tavor_rsrc_pool_info_t * pool_info,uint_t num,uint_t num_align,ddi_acc_handle_t acc_handle,uint_t sleepflag,tavor_rsrc_t * hdl)21859e39c5baSBill Taylor tavor_rsrc_hw_entry_alloc(tavor_rsrc_pool_info_t *pool_info, uint_t num,
21869e39c5baSBill Taylor uint_t num_align, ddi_acc_handle_t acc_handle, uint_t sleepflag,
21879e39c5baSBill Taylor tavor_rsrc_t *hdl)
21889e39c5baSBill Taylor {
21899e39c5baSBill Taylor void *addr;
21909e39c5baSBill Taylor uint64_t offset;
21919e39c5baSBill Taylor uint32_t align;
21929e39c5baSBill Taylor int flag;
21939e39c5baSBill Taylor
21949e39c5baSBill Taylor ASSERT(pool_info != NULL);
21959e39c5baSBill Taylor ASSERT(hdl != NULL);
21969e39c5baSBill Taylor
21979e39c5baSBill Taylor /*
21989e39c5baSBill Taylor * Tavor hardware entries (QPC, CQC, EQC, MPT, MTT, etc.) do not
21999e39c5baSBill Taylor * use dma_handle (because they are in Tavor locally attached DDR
22009e39c5baSBill Taylor * memory) and, generally, don't use the acc_handle (because the
22019e39c5baSBill Taylor * entries are not directly accessed by software). The exceptions
22029e39c5baSBill Taylor * to this rule are the UARPG and UDAV entries.
22039e39c5baSBill Taylor */
22049e39c5baSBill Taylor
22059e39c5baSBill Taylor /*
22069e39c5baSBill Taylor * Use vmem_xalloc() to get a properly aligned pointer (based on
22079e39c5baSBill Taylor * the number requested) to the HW entry(ies). This handles the
22089e39c5baSBill Taylor * cases (for special QPCs and for RDB entries) where we need more
22099e39c5baSBill Taylor * than one and need to ensure that they are properly aligned.
22109e39c5baSBill Taylor */
22119e39c5baSBill Taylor flag = (sleepflag == TAVOR_SLEEP) ? VM_SLEEP : VM_NOSLEEP;
22129e39c5baSBill Taylor hdl->tr_len = (num * pool_info->rsrc_quantum);
22139e39c5baSBill Taylor align = (num_align * pool_info->rsrc_quantum);
22149e39c5baSBill Taylor addr = vmem_xalloc(pool_info->rsrc_vmp, hdl->tr_len,
22159e39c5baSBill Taylor align, 0, 0, NULL, NULL, flag | VM_FIRSTFIT);
22169e39c5baSBill Taylor if (addr == NULL) {
22179e39c5baSBill Taylor /* No more HW entries available */
22189e39c5baSBill Taylor return (DDI_FAILURE);
22199e39c5baSBill Taylor }
22209e39c5baSBill Taylor
22219e39c5baSBill Taylor /* If an access handle was provided, fill it in */
22229e39c5baSBill Taylor if (acc_handle != 0) {
22239e39c5baSBill Taylor hdl->tr_acchdl = acc_handle;
22249e39c5baSBill Taylor }
22259e39c5baSBill Taylor
22269e39c5baSBill Taylor /* Calculate vaddr and HW table index (from the DDR offset) */
22279e39c5baSBill Taylor offset = ((uintptr_t)addr - (uintptr_t)pool_info->rsrc_ddr_offset);
22289e39c5baSBill Taylor hdl->tr_addr = (void *)(uintptr_t)(offset +
22299e39c5baSBill Taylor (uintptr_t)pool_info->rsrc_start);
22309e39c5baSBill Taylor hdl->tr_indx = (offset >> pool_info->rsrc_shift);
22319e39c5baSBill Taylor
22329e39c5baSBill Taylor return (DDI_SUCCESS);
22339e39c5baSBill Taylor }
22349e39c5baSBill Taylor
22359e39c5baSBill Taylor
22369e39c5baSBill Taylor /*
22379e39c5baSBill Taylor * tavor_rsrc_hw_entry_free()
22389e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
22399e39c5baSBill Taylor */
22409e39c5baSBill Taylor static void
tavor_rsrc_hw_entry_free(tavor_rsrc_pool_info_t * pool_info,tavor_rsrc_t * hdl)22419e39c5baSBill Taylor tavor_rsrc_hw_entry_free(tavor_rsrc_pool_info_t *pool_info, tavor_rsrc_t *hdl)
22429e39c5baSBill Taylor {
22439e39c5baSBill Taylor void *addr;
22449e39c5baSBill Taylor uint64_t offset;
22459e39c5baSBill Taylor
22469e39c5baSBill Taylor ASSERT(pool_info != NULL);
22479e39c5baSBill Taylor ASSERT(hdl != NULL);
22489e39c5baSBill Taylor
22499e39c5baSBill Taylor /* Calculate the allocated address (the entry's DDR offset) */
22509e39c5baSBill Taylor offset = ((uintptr_t)hdl->tr_addr - (uintptr_t)pool_info->rsrc_start);
22519e39c5baSBill Taylor addr = (void *)(uintptr_t)(offset +
22529e39c5baSBill Taylor (uintptr_t)pool_info->rsrc_ddr_offset);
22539e39c5baSBill Taylor
22549e39c5baSBill Taylor /* Use vmem_xfree() to free up the HW table entry */
22559e39c5baSBill Taylor vmem_xfree(pool_info->rsrc_vmp, addr, hdl->tr_len);
22569e39c5baSBill Taylor }
22579e39c5baSBill Taylor
22589e39c5baSBill Taylor
22599e39c5baSBill Taylor /*
22609e39c5baSBill Taylor * tavor_rsrc_swhdl_alloc()
22619e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
22629e39c5baSBill Taylor */
22639e39c5baSBill Taylor static int
tavor_rsrc_swhdl_alloc(tavor_rsrc_pool_info_t * pool_info,uint_t sleepflag,tavor_rsrc_t * hdl)22649e39c5baSBill Taylor tavor_rsrc_swhdl_alloc(tavor_rsrc_pool_info_t *pool_info, uint_t sleepflag,
22659e39c5baSBill Taylor tavor_rsrc_t *hdl)
22669e39c5baSBill Taylor {
22679e39c5baSBill Taylor void *addr;
22689e39c5baSBill Taylor int flag;
22699e39c5baSBill Taylor
22709e39c5baSBill Taylor ASSERT(pool_info != NULL);
22719e39c5baSBill Taylor ASSERT(hdl != NULL);
22729e39c5baSBill Taylor
22739e39c5baSBill Taylor /* Allocate the software handle structure */
22749e39c5baSBill Taylor flag = (sleepflag == TAVOR_SLEEP) ? KM_SLEEP : KM_NOSLEEP;
22759e39c5baSBill Taylor addr = kmem_cache_alloc(pool_info->rsrc_private, flag);
22769e39c5baSBill Taylor if (addr == NULL) {
22779e39c5baSBill Taylor return (DDI_FAILURE);
22789e39c5baSBill Taylor }
22799e39c5baSBill Taylor hdl->tr_len = pool_info->rsrc_quantum;
22809e39c5baSBill Taylor hdl->tr_addr = addr;
22819e39c5baSBill Taylor
22829e39c5baSBill Taylor return (DDI_SUCCESS);
22839e39c5baSBill Taylor }
22849e39c5baSBill Taylor
22859e39c5baSBill Taylor
22869e39c5baSBill Taylor /*
22879e39c5baSBill Taylor * tavor_rsrc_swhdl_free()
22889e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
22899e39c5baSBill Taylor */
22909e39c5baSBill Taylor static void
tavor_rsrc_swhdl_free(tavor_rsrc_pool_info_t * pool_info,tavor_rsrc_t * hdl)22919e39c5baSBill Taylor tavor_rsrc_swhdl_free(tavor_rsrc_pool_info_t *pool_info, tavor_rsrc_t *hdl)
22929e39c5baSBill Taylor {
22939e39c5baSBill Taylor ASSERT(pool_info != NULL);
22949e39c5baSBill Taylor ASSERT(hdl != NULL);
22959e39c5baSBill Taylor
22969e39c5baSBill Taylor /* Free the software handle structure */
22979e39c5baSBill Taylor kmem_cache_free(pool_info->rsrc_private, hdl->tr_addr);
22989e39c5baSBill Taylor }
22999e39c5baSBill Taylor
23009e39c5baSBill Taylor
23019e39c5baSBill Taylor /*
23029e39c5baSBill Taylor * tavor_rsrc_pdhdl_alloc()
23039e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
23049e39c5baSBill Taylor */
23059e39c5baSBill Taylor static int
tavor_rsrc_pdhdl_alloc(tavor_rsrc_pool_info_t * pool_info,uint_t sleepflag,tavor_rsrc_t * hdl)23069e39c5baSBill Taylor tavor_rsrc_pdhdl_alloc(tavor_rsrc_pool_info_t *pool_info, uint_t sleepflag,
23079e39c5baSBill Taylor tavor_rsrc_t *hdl)
23089e39c5baSBill Taylor {
23099e39c5baSBill Taylor tavor_pdhdl_t addr;
23109e39c5baSBill Taylor void *tmpaddr;
23119e39c5baSBill Taylor int flag, status;
23129e39c5baSBill Taylor
23139e39c5baSBill Taylor ASSERT(pool_info != NULL);
23149e39c5baSBill Taylor ASSERT(hdl != NULL);
23159e39c5baSBill Taylor
23169e39c5baSBill Taylor /* Allocate the software handle */
23179e39c5baSBill Taylor status = tavor_rsrc_swhdl_alloc(pool_info, sleepflag, hdl);
23189e39c5baSBill Taylor if (status != DDI_SUCCESS) {
23199e39c5baSBill Taylor return (DDI_FAILURE);
23209e39c5baSBill Taylor }
23219e39c5baSBill Taylor addr = (tavor_pdhdl_t)hdl->tr_addr;
23229e39c5baSBill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*addr))
23239e39c5baSBill Taylor
23249e39c5baSBill Taylor /* Allocate a PD number for the handle */
23259e39c5baSBill Taylor flag = (sleepflag == TAVOR_SLEEP) ? VM_SLEEP : VM_NOSLEEP;
23269e39c5baSBill Taylor tmpaddr = vmem_alloc(pool_info->rsrc_vmp, 1, flag);
23279e39c5baSBill Taylor if (tmpaddr == NULL) {
23289e39c5baSBill Taylor /* No more PD number entries available */
23299e39c5baSBill Taylor tavor_rsrc_swhdl_free(pool_info, hdl);
23309e39c5baSBill Taylor return (DDI_FAILURE);
23319e39c5baSBill Taylor }
23329e39c5baSBill Taylor addr->pd_pdnum = (uint32_t)(uintptr_t)tmpaddr;
23339e39c5baSBill Taylor addr->pd_rsrcp = hdl;
23349e39c5baSBill Taylor hdl->tr_indx = addr->pd_pdnum;
23359e39c5baSBill Taylor
23369e39c5baSBill Taylor return (DDI_SUCCESS);
23379e39c5baSBill Taylor }
23389e39c5baSBill Taylor
23399e39c5baSBill Taylor
23409e39c5baSBill Taylor /*
23419e39c5baSBill Taylor * tavor_rsrc_pdhdl_free()
23429e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
23439e39c5baSBill Taylor */
23449e39c5baSBill Taylor static void
tavor_rsrc_pdhdl_free(tavor_rsrc_pool_info_t * pool_info,tavor_rsrc_t * hdl)23459e39c5baSBill Taylor tavor_rsrc_pdhdl_free(tavor_rsrc_pool_info_t *pool_info, tavor_rsrc_t *hdl)
23469e39c5baSBill Taylor {
23479e39c5baSBill Taylor ASSERT(pool_info != NULL);
23489e39c5baSBill Taylor ASSERT(hdl != NULL);
23499e39c5baSBill Taylor
23509e39c5baSBill Taylor /* Use vmem_free() to free up the PD number */
23519e39c5baSBill Taylor vmem_free(pool_info->rsrc_vmp, (void *)(uintptr_t)hdl->tr_indx, 1);
23529e39c5baSBill Taylor
23539e39c5baSBill Taylor /* Free the software handle structure */
23549e39c5baSBill Taylor tavor_rsrc_swhdl_free(pool_info, hdl);
23559e39c5baSBill Taylor }
23569e39c5baSBill Taylor
23579e39c5baSBill Taylor
23589e39c5baSBill Taylor /*
23599e39c5baSBill Taylor * tavor_rsrc_pdhdl_constructor()
23609e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
23619e39c5baSBill Taylor */
23629e39c5baSBill Taylor /* ARGSUSED */
23639e39c5baSBill Taylor static int
tavor_rsrc_pdhdl_constructor(void * pd,void * priv,int flags)23649e39c5baSBill Taylor tavor_rsrc_pdhdl_constructor(void *pd, void *priv, int flags)
23659e39c5baSBill Taylor {
23669e39c5baSBill Taylor tavor_pdhdl_t pdhdl;
23679e39c5baSBill Taylor tavor_state_t *state;
23689e39c5baSBill Taylor
23699e39c5baSBill Taylor pdhdl = (tavor_pdhdl_t)pd;
23709e39c5baSBill Taylor state = (tavor_state_t *)priv;
23719e39c5baSBill Taylor
23729e39c5baSBill Taylor mutex_init(&pdhdl->pd_lock, NULL, MUTEX_DRIVER,
23739e39c5baSBill Taylor DDI_INTR_PRI(state->ts_intrmsi_pri));
23749e39c5baSBill Taylor
23759e39c5baSBill Taylor return (DDI_SUCCESS);
23769e39c5baSBill Taylor }
23779e39c5baSBill Taylor
23789e39c5baSBill Taylor
23799e39c5baSBill Taylor /*
23809e39c5baSBill Taylor * tavor_rsrc_pdhdl_destructor()
23819e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
23829e39c5baSBill Taylor */
23839e39c5baSBill Taylor /* ARGSUSED */
23849e39c5baSBill Taylor static void
tavor_rsrc_pdhdl_destructor(void * pd,void * priv)23859e39c5baSBill Taylor tavor_rsrc_pdhdl_destructor(void *pd, void *priv)
23869e39c5baSBill Taylor {
23879e39c5baSBill Taylor tavor_pdhdl_t pdhdl;
23889e39c5baSBill Taylor
23899e39c5baSBill Taylor pdhdl = (tavor_pdhdl_t)pd;
23909e39c5baSBill Taylor
23919e39c5baSBill Taylor mutex_destroy(&pdhdl->pd_lock);
23929e39c5baSBill Taylor }
23939e39c5baSBill Taylor
23949e39c5baSBill Taylor
23959e39c5baSBill Taylor /*
23969e39c5baSBill Taylor * tavor_rsrc_cqhdl_constructor()
23979e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
23989e39c5baSBill Taylor */
23999e39c5baSBill Taylor /* ARGSUSED */
24009e39c5baSBill Taylor static int
tavor_rsrc_cqhdl_constructor(void * cq,void * priv,int flags)24019e39c5baSBill Taylor tavor_rsrc_cqhdl_constructor(void *cq, void *priv, int flags)
24029e39c5baSBill Taylor {
24039e39c5baSBill Taylor tavor_cqhdl_t cqhdl;
24049e39c5baSBill Taylor tavor_state_t *state;
24059e39c5baSBill Taylor
24069e39c5baSBill Taylor cqhdl = (tavor_cqhdl_t)cq;
24079e39c5baSBill Taylor state = (tavor_state_t *)priv;
24089e39c5baSBill Taylor
24099e39c5baSBill Taylor mutex_init(&cqhdl->cq_lock, NULL, MUTEX_DRIVER,
24109e39c5baSBill Taylor DDI_INTR_PRI(state->ts_intrmsi_pri));
24119e39c5baSBill Taylor mutex_init(&cqhdl->cq_wrid_wqhdr_lock, NULL, MUTEX_DRIVER,
24129e39c5baSBill Taylor DDI_INTR_PRI(state->ts_intrmsi_pri));
24139e39c5baSBill Taylor
24149e39c5baSBill Taylor return (DDI_SUCCESS);
24159e39c5baSBill Taylor }
24169e39c5baSBill Taylor
24179e39c5baSBill Taylor
24189e39c5baSBill Taylor /*
24199e39c5baSBill Taylor * tavor_rsrc_cqhdl_destructor()
24209e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
24219e39c5baSBill Taylor */
24229e39c5baSBill Taylor /* ARGSUSED */
24239e39c5baSBill Taylor static void
tavor_rsrc_cqhdl_destructor(void * cq,void * priv)24249e39c5baSBill Taylor tavor_rsrc_cqhdl_destructor(void *cq, void *priv)
24259e39c5baSBill Taylor {
24269e39c5baSBill Taylor tavor_cqhdl_t cqhdl;
24279e39c5baSBill Taylor
24289e39c5baSBill Taylor cqhdl = (tavor_cqhdl_t)cq;
24299e39c5baSBill Taylor
24309e39c5baSBill Taylor mutex_destroy(&cqhdl->cq_wrid_wqhdr_lock);
24319e39c5baSBill Taylor mutex_destroy(&cqhdl->cq_lock);
24329e39c5baSBill Taylor }
24339e39c5baSBill Taylor
24349e39c5baSBill Taylor
24359e39c5baSBill Taylor /*
24369e39c5baSBill Taylor * tavor_rsrc_qphdl_constructor()
24379e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
24389e39c5baSBill Taylor */
24399e39c5baSBill Taylor /* ARGSUSED */
24409e39c5baSBill Taylor static int
tavor_rsrc_qphdl_constructor(void * qp,void * priv,int flags)24419e39c5baSBill Taylor tavor_rsrc_qphdl_constructor(void *qp, void *priv, int flags)
24429e39c5baSBill Taylor {
24439e39c5baSBill Taylor tavor_qphdl_t qphdl;
24449e39c5baSBill Taylor tavor_state_t *state;
24459e39c5baSBill Taylor
24469e39c5baSBill Taylor qphdl = (tavor_qphdl_t)qp;
24479e39c5baSBill Taylor state = (tavor_state_t *)priv;
24489e39c5baSBill Taylor
24499e39c5baSBill Taylor mutex_init(&qphdl->qp_lock, NULL, MUTEX_DRIVER,
24509e39c5baSBill Taylor DDI_INTR_PRI(state->ts_intrmsi_pri));
24519e39c5baSBill Taylor
24529e39c5baSBill Taylor return (DDI_SUCCESS);
24539e39c5baSBill Taylor }
24549e39c5baSBill Taylor
24559e39c5baSBill Taylor
24569e39c5baSBill Taylor /*
24579e39c5baSBill Taylor * tavor_rsrc_qphdl_destructor()
24589e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
24599e39c5baSBill Taylor */
24609e39c5baSBill Taylor /* ARGSUSED */
24619e39c5baSBill Taylor static void
tavor_rsrc_qphdl_destructor(void * qp,void * priv)24629e39c5baSBill Taylor tavor_rsrc_qphdl_destructor(void *qp, void *priv)
24639e39c5baSBill Taylor {
24649e39c5baSBill Taylor tavor_qphdl_t qphdl;
24659e39c5baSBill Taylor
24669e39c5baSBill Taylor qphdl = (tavor_qphdl_t)qp;
24679e39c5baSBill Taylor
24689e39c5baSBill Taylor mutex_destroy(&qphdl->qp_lock);
24699e39c5baSBill Taylor }
24709e39c5baSBill Taylor
24719e39c5baSBill Taylor
24729e39c5baSBill Taylor /*
24739e39c5baSBill Taylor * tavor_rsrc_srqhdl_constructor()
24749e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
24759e39c5baSBill Taylor */
24769e39c5baSBill Taylor /* ARGSUSED */
24779e39c5baSBill Taylor static int
tavor_rsrc_srqhdl_constructor(void * srq,void * priv,int flags)24789e39c5baSBill Taylor tavor_rsrc_srqhdl_constructor(void *srq, void *priv, int flags)
24799e39c5baSBill Taylor {
24809e39c5baSBill Taylor tavor_srqhdl_t srqhdl;
24819e39c5baSBill Taylor tavor_state_t *state;
24829e39c5baSBill Taylor
24839e39c5baSBill Taylor srqhdl = (tavor_srqhdl_t)srq;
24849e39c5baSBill Taylor state = (tavor_state_t *)priv;
24859e39c5baSBill Taylor
24869e39c5baSBill Taylor mutex_init(&srqhdl->srq_lock, NULL, MUTEX_DRIVER,
24879e39c5baSBill Taylor DDI_INTR_PRI(state->ts_intrmsi_pri));
24889e39c5baSBill Taylor
24899e39c5baSBill Taylor return (DDI_SUCCESS);
24909e39c5baSBill Taylor }
24919e39c5baSBill Taylor
24929e39c5baSBill Taylor
24939e39c5baSBill Taylor /*
24949e39c5baSBill Taylor * tavor_rsrc_srqhdl_destructor()
24959e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
24969e39c5baSBill Taylor */
24979e39c5baSBill Taylor /* ARGSUSED */
24989e39c5baSBill Taylor static void
tavor_rsrc_srqhdl_destructor(void * srq,void * priv)24999e39c5baSBill Taylor tavor_rsrc_srqhdl_destructor(void *srq, void *priv)
25009e39c5baSBill Taylor {
25019e39c5baSBill Taylor tavor_srqhdl_t srqhdl;
25029e39c5baSBill Taylor
25039e39c5baSBill Taylor srqhdl = (tavor_srqhdl_t)srq;
25049e39c5baSBill Taylor
25059e39c5baSBill Taylor mutex_destroy(&srqhdl->srq_lock);
25069e39c5baSBill Taylor }
25079e39c5baSBill Taylor
25089e39c5baSBill Taylor
25099e39c5baSBill Taylor /*
25109e39c5baSBill Taylor * tavor_rsrc_refcnt_constructor()
25119e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
25129e39c5baSBill Taylor */
25139e39c5baSBill Taylor /* ARGSUSED */
25149e39c5baSBill Taylor static int
tavor_rsrc_refcnt_constructor(void * rc,void * priv,int flags)25159e39c5baSBill Taylor tavor_rsrc_refcnt_constructor(void *rc, void *priv, int flags)
25169e39c5baSBill Taylor {
25179e39c5baSBill Taylor tavor_sw_refcnt_t *refcnt;
25189e39c5baSBill Taylor tavor_state_t *state;
25199e39c5baSBill Taylor
25209e39c5baSBill Taylor refcnt = (tavor_sw_refcnt_t *)rc;
25219e39c5baSBill Taylor state = (tavor_state_t *)priv;
25229e39c5baSBill Taylor
25239e39c5baSBill Taylor mutex_init(&refcnt->swrc_lock, NULL, MUTEX_DRIVER,
25249e39c5baSBill Taylor DDI_INTR_PRI(state->ts_intrmsi_pri));
25259e39c5baSBill Taylor
25269e39c5baSBill Taylor return (DDI_SUCCESS);
25279e39c5baSBill Taylor }
25289e39c5baSBill Taylor
25299e39c5baSBill Taylor
25309e39c5baSBill Taylor /*
25319e39c5baSBill Taylor * tavor_rsrc_refcnt_destructor()
25329e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
25339e39c5baSBill Taylor */
25349e39c5baSBill Taylor /* ARGSUSED */
25359e39c5baSBill Taylor static void
tavor_rsrc_refcnt_destructor(void * rc,void * priv)25369e39c5baSBill Taylor tavor_rsrc_refcnt_destructor(void *rc, void *priv)
25379e39c5baSBill Taylor {
25389e39c5baSBill Taylor tavor_sw_refcnt_t *refcnt;
25399e39c5baSBill Taylor
25409e39c5baSBill Taylor refcnt = (tavor_sw_refcnt_t *)rc;
25419e39c5baSBill Taylor
25429e39c5baSBill Taylor mutex_destroy(&refcnt->swrc_lock);
25439e39c5baSBill Taylor }
25449e39c5baSBill Taylor
25459e39c5baSBill Taylor
25469e39c5baSBill Taylor /*
25479e39c5baSBill Taylor * tavor_rsrc_ahhdl_constructor()
25489e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
25499e39c5baSBill Taylor */
25509e39c5baSBill Taylor /* ARGSUSED */
25519e39c5baSBill Taylor static int
tavor_rsrc_ahhdl_constructor(void * ah,void * priv,int flags)25529e39c5baSBill Taylor tavor_rsrc_ahhdl_constructor(void *ah, void *priv, int flags)
25539e39c5baSBill Taylor {
25549e39c5baSBill Taylor tavor_ahhdl_t ahhdl;
25559e39c5baSBill Taylor tavor_state_t *state;
25569e39c5baSBill Taylor
25579e39c5baSBill Taylor ahhdl = (tavor_ahhdl_t)ah;
25589e39c5baSBill Taylor state = (tavor_state_t *)priv;
25599e39c5baSBill Taylor
25609e39c5baSBill Taylor mutex_init(&ahhdl->ah_lock, NULL, MUTEX_DRIVER,
25619e39c5baSBill Taylor DDI_INTR_PRI(state->ts_intrmsi_pri));
25629e39c5baSBill Taylor
25639e39c5baSBill Taylor return (DDI_SUCCESS);
25649e39c5baSBill Taylor }
25659e39c5baSBill Taylor
25669e39c5baSBill Taylor
25679e39c5baSBill Taylor /*
25689e39c5baSBill Taylor * tavor_rsrc_ahhdl_destructor()
25699e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
25709e39c5baSBill Taylor */
25719e39c5baSBill Taylor /* ARGSUSED */
25729e39c5baSBill Taylor static void
tavor_rsrc_ahhdl_destructor(void * ah,void * priv)25739e39c5baSBill Taylor tavor_rsrc_ahhdl_destructor(void *ah, void *priv)
25749e39c5baSBill Taylor {
25759e39c5baSBill Taylor tavor_ahhdl_t ahhdl;
25769e39c5baSBill Taylor
25779e39c5baSBill Taylor ahhdl = (tavor_ahhdl_t)ah;
25789e39c5baSBill Taylor
25799e39c5baSBill Taylor mutex_destroy(&ahhdl->ah_lock);
25809e39c5baSBill Taylor }
25819e39c5baSBill Taylor
25829e39c5baSBill Taylor
25839e39c5baSBill Taylor /*
25849e39c5baSBill Taylor * tavor_rsrc_mrhdl_constructor()
25859e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
25869e39c5baSBill Taylor */
25879e39c5baSBill Taylor /* ARGSUSED */
25889e39c5baSBill Taylor static int
tavor_rsrc_mrhdl_constructor(void * mr,void * priv,int flags)25899e39c5baSBill Taylor tavor_rsrc_mrhdl_constructor(void *mr, void *priv, int flags)
25909e39c5baSBill Taylor {
25919e39c5baSBill Taylor tavor_mrhdl_t mrhdl;
25929e39c5baSBill Taylor tavor_state_t *state;
25939e39c5baSBill Taylor
25949e39c5baSBill Taylor mrhdl = (tavor_mrhdl_t)mr;
25959e39c5baSBill Taylor state = (tavor_state_t *)priv;
25969e39c5baSBill Taylor
25979e39c5baSBill Taylor mutex_init(&mrhdl->mr_lock, NULL, MUTEX_DRIVER,
25989e39c5baSBill Taylor DDI_INTR_PRI(state->ts_intrmsi_pri));
25999e39c5baSBill Taylor
26009e39c5baSBill Taylor return (DDI_SUCCESS);
26019e39c5baSBill Taylor }
26029e39c5baSBill Taylor
26039e39c5baSBill Taylor
26049e39c5baSBill Taylor /*
26059e39c5baSBill Taylor * tavor_rsrc_mrhdl_destructor()
26069e39c5baSBill Taylor * Context: Can be called from interrupt or base context.
26079e39c5baSBill Taylor */
26089e39c5baSBill Taylor /* ARGSUSED */
26099e39c5baSBill Taylor static void
tavor_rsrc_mrhdl_destructor(void * mr,void * priv)26109e39c5baSBill Taylor tavor_rsrc_mrhdl_destructor(void *mr, void *priv)
26119e39c5baSBill Taylor {
26129e39c5baSBill Taylor tavor_mrhdl_t mrhdl;
26139e39c5baSBill Taylor
26149e39c5baSBill Taylor mrhdl = (tavor_mrhdl_t)mr;
26159e39c5baSBill Taylor
26169e39c5baSBill Taylor mutex_destroy(&mrhdl->mr_lock);
26179e39c5baSBill Taylor }
26189e39c5baSBill Taylor
26199e39c5baSBill Taylor
26209e39c5baSBill Taylor /*
26219e39c5baSBill Taylor * tavor_rsrc_mcg_entry_get_size()
26229e39c5baSBill Taylor */
26239e39c5baSBill Taylor static int
tavor_rsrc_mcg_entry_get_size(tavor_state_t * state,uint_t * mcg_size_shift)26249e39c5baSBill Taylor tavor_rsrc_mcg_entry_get_size(tavor_state_t *state, uint_t *mcg_size_shift)
26259e39c5baSBill Taylor {
26269e39c5baSBill Taylor uint_t num_qp_per_mcg, max_qp_per_mcg, log2;
26279e39c5baSBill Taylor
26289e39c5baSBill Taylor /*
26299e39c5baSBill Taylor * Round the configured number of QP per MCG to next larger
26309e39c5baSBill Taylor * power-of-2 size and update.
26319e39c5baSBill Taylor */
26329e39c5baSBill Taylor num_qp_per_mcg = state->ts_cfg_profile->cp_num_qp_per_mcg + 8;
26339e39c5baSBill Taylor log2 = highbit(num_qp_per_mcg);
2634de710d24SJosef 'Jeff' Sipek if (ISP2(num_qp_per_mcg)) {
26359e39c5baSBill Taylor log2 = log2 - 1;
26369e39c5baSBill Taylor }
26379e39c5baSBill Taylor state->ts_cfg_profile->cp_num_qp_per_mcg = (1 << log2) - 8;
26389e39c5baSBill Taylor
26399e39c5baSBill Taylor /* Now make sure number of QP per MCG makes sense */
26409e39c5baSBill Taylor num_qp_per_mcg = state->ts_cfg_profile->cp_num_qp_per_mcg;
26419e39c5baSBill Taylor max_qp_per_mcg = (1 << state->ts_devlim.log_max_qp_mcg);
26429e39c5baSBill Taylor if (num_qp_per_mcg > max_qp_per_mcg) {
26439e39c5baSBill Taylor return (DDI_FAILURE);
26449e39c5baSBill Taylor }
26459e39c5baSBill Taylor
26469e39c5baSBill Taylor /* Return the (shift) size of an individual MCG HW entry */
26479e39c5baSBill Taylor *mcg_size_shift = log2 + 2;
26489e39c5baSBill Taylor
26499e39c5baSBill Taylor return (DDI_SUCCESS);
26509e39c5baSBill Taylor }
2651