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 /* 23*c7facc54SBill Taylor * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 249e39c5baSBill Taylor * Use is subject to license terms. 259e39c5baSBill Taylor */ 269e39c5baSBill Taylor 279e39c5baSBill Taylor /* 289e39c5baSBill Taylor * hermon_rsrc.c 299e39c5baSBill Taylor * Hermon Resource Management Routines 309e39c5baSBill Taylor * 319e39c5baSBill Taylor * Implements all the routines necessary for setup, teardown, and 329e39c5baSBill Taylor * alloc/free of all Hermon resources, including those that are managed 339e39c5baSBill Taylor * by Hermon hardware or which live in Hermon's direct attached DDR memory. 349e39c5baSBill Taylor */ 359e39c5baSBill Taylor 369e39c5baSBill Taylor #include <sys/types.h> 379e39c5baSBill Taylor #include <sys/conf.h> 389e39c5baSBill Taylor #include <sys/ddi.h> 399e39c5baSBill Taylor #include <sys/sunddi.h> 409e39c5baSBill Taylor #include <sys/modctl.h> 419e39c5baSBill Taylor #include <sys/vmem.h> 429e39c5baSBill Taylor #include <sys/bitmap.h> 439e39c5baSBill Taylor 449e39c5baSBill Taylor #include <sys/ib/adapters/hermon/hermon.h> 459e39c5baSBill Taylor 469e39c5baSBill Taylor int hermon_rsrc_verbose = 0; 479e39c5baSBill Taylor 489e39c5baSBill Taylor /* 499e39c5baSBill Taylor * The following routines are used for initializing and destroying 509e39c5baSBill Taylor * the resource pools used by the Hermon resource allocation routines. 519e39c5baSBill Taylor * They consist of four classes of object: 529e39c5baSBill Taylor * 539e39c5baSBill Taylor * Mailboxes: The "In" and "Out" mailbox types are used by the Hermon 549e39c5baSBill Taylor * command interface routines. Mailboxes are used to pass information 559e39c5baSBill Taylor * back and forth to the Hermon firmware. Either type of mailbox may 569e39c5baSBill Taylor * be allocated from Hermon's direct attached DDR memory or from system 579e39c5baSBill Taylor * memory (although currently all "In" mailboxes are in DDR and all "out" 589e39c5baSBill Taylor * mailboxes come from system memory. 599e39c5baSBill Taylor * 609e39c5baSBill Taylor * HW entry objects: These objects represent resources required by the Hermon 619e39c5baSBill Taylor * hardware. These objects include things like Queue Pair contexts (QPC), 629e39c5baSBill Taylor * Completion Queue contexts (CQC), Event Queue contexts (EQC), RDB (for 639e39c5baSBill Taylor * supporting RDMA Read/Atomic), Multicast Group entries (MCG), Memory 649e39c5baSBill Taylor * Protection Table entries (MPT), Memory Translation Table entries (MTT). 659e39c5baSBill Taylor * 669e39c5baSBill Taylor * What these objects all have in common is that they are each required 679e39c5baSBill Taylor * to come from ICM memory, they are always allocated from tables, and 689e39c5baSBill Taylor * they are not to be directly accessed (read or written) by driver 699e39c5baSBill Taylor * software (Mellanox FMR access to MPT is an exception). 709e39c5baSBill Taylor * The other notable exceptions are the UAR pages (UAR_PG) which are 719e39c5baSBill Taylor * allocated from the UAR address space rather than DDR, and the UD 729e39c5baSBill Taylor * address vectors (UDAV) which are similar to the common object types 739e39c5baSBill Taylor * with the major difference being that UDAVs _are_ directly read and 749e39c5baSBill Taylor * written by driver software. 759e39c5baSBill Taylor * 769e39c5baSBill Taylor * SW handle objects: These objects represent resources required by Hermon 779e39c5baSBill Taylor * driver software. They are primarily software tracking structures, 789e39c5baSBill Taylor * which are allocated from system memory (using kmem_cache). Several of 799e39c5baSBill Taylor * the objects have both a "constructor" and "destructor" method 809e39c5baSBill Taylor * associated with them (see below). 819e39c5baSBill Taylor * 829e39c5baSBill Taylor * Protection Domain (PD) handle objects: These objects are very much like 839e39c5baSBill Taylor * a SW handle object with the notable difference that all PD handle 849e39c5baSBill Taylor * objects have an actual Protection Domain number (PD) associated with 859e39c5baSBill Taylor * them (and the PD number is allocated/managed through a separate 869e39c5baSBill Taylor * vmem_arena specifically set aside for this purpose. 879e39c5baSBill Taylor */ 889e39c5baSBill Taylor 899e39c5baSBill Taylor static int hermon_rsrc_mbox_init(hermon_state_t *state, 909e39c5baSBill Taylor hermon_rsrc_mbox_info_t *info); 919e39c5baSBill Taylor static void hermon_rsrc_mbox_fini(hermon_state_t *state, 929e39c5baSBill Taylor hermon_rsrc_mbox_info_t *info); 939e39c5baSBill Taylor 949e39c5baSBill Taylor static int hermon_rsrc_sw_handles_init(hermon_state_t *state, 959e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t *info); 969e39c5baSBill Taylor static void hermon_rsrc_sw_handles_fini(hermon_state_t *state, 979e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t *info); 989e39c5baSBill Taylor 999e39c5baSBill Taylor static int hermon_rsrc_pd_handles_init(hermon_state_t *state, 1009e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t *info); 1019e39c5baSBill Taylor static void hermon_rsrc_pd_handles_fini(hermon_state_t *state, 1029e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t *info); 1039e39c5baSBill Taylor 1049e39c5baSBill Taylor /* 1059e39c5baSBill Taylor * The following routines are used for allocating and freeing the specific 1069e39c5baSBill Taylor * types of objects described above from their associated resource pools. 1079e39c5baSBill Taylor */ 1089e39c5baSBill Taylor static int hermon_rsrc_mbox_alloc(hermon_rsrc_pool_info_t *pool_info, 1099e39c5baSBill Taylor uint_t num, hermon_rsrc_t *hdl); 1109e39c5baSBill Taylor static void hermon_rsrc_mbox_free(hermon_rsrc_pool_info_t *pool_info, 1119e39c5baSBill Taylor hermon_rsrc_t *hdl); 1129e39c5baSBill Taylor 1139e39c5baSBill Taylor static int hermon_rsrc_hw_entry_alloc(hermon_rsrc_pool_info_t *pool_info, 1149e39c5baSBill Taylor uint_t num, uint_t num_align, ddi_acc_handle_t acc_handle, 1159e39c5baSBill Taylor uint_t sleepflag, hermon_rsrc_t *hdl); 1169e39c5baSBill Taylor static void hermon_rsrc_hw_entry_free(hermon_rsrc_pool_info_t *pool_info, 1179e39c5baSBill Taylor hermon_rsrc_t *hdl); 1189e39c5baSBill Taylor 1199e39c5baSBill Taylor static int hermon_rsrc_hw_entry_icm_confirm(hermon_rsrc_pool_info_t *pool_info, 1209e39c5baSBill Taylor uint_t num, hermon_rsrc_t *hdl); 1219e39c5baSBill Taylor static int hermon_rsrc_hw_entry_icm_free(hermon_rsrc_pool_info_t *pool_info, 1229e39c5baSBill Taylor hermon_rsrc_t *hdl); 1239e39c5baSBill Taylor 1249e39c5baSBill Taylor static int hermon_rsrc_swhdl_alloc(hermon_rsrc_pool_info_t *pool_info, 1259e39c5baSBill Taylor uint_t sleepflag, hermon_rsrc_t *hdl); 1269e39c5baSBill Taylor static void hermon_rsrc_swhdl_free(hermon_rsrc_pool_info_t *pool_info, 1279e39c5baSBill Taylor hermon_rsrc_t *hdl); 1289e39c5baSBill Taylor 1299e39c5baSBill Taylor static int hermon_rsrc_pdhdl_alloc(hermon_rsrc_pool_info_t *pool_info, 1309e39c5baSBill Taylor uint_t sleepflag, hermon_rsrc_t *hdl); 1319e39c5baSBill Taylor static void hermon_rsrc_pdhdl_free(hermon_rsrc_pool_info_t *pool_info, 1329e39c5baSBill Taylor hermon_rsrc_t *hdl); 1339e39c5baSBill Taylor 1349e39c5baSBill Taylor /* 1359e39c5baSBill Taylor * The following routines are the constructors and destructors for several 1369e39c5baSBill Taylor * of the SW handle type objects. For certain types of SW handles objects 1379e39c5baSBill Taylor * (all of which are implemented using kmem_cache), we need to do some 1389e39c5baSBill Taylor * special field initialization (specifically, mutex_init/destroy). These 1399e39c5baSBill Taylor * routines enable that init and teardown. 1409e39c5baSBill Taylor */ 1419e39c5baSBill Taylor static int hermon_rsrc_pdhdl_constructor(void *pd, void *priv, int flags); 1429e39c5baSBill Taylor static void hermon_rsrc_pdhdl_destructor(void *pd, void *state); 1439e39c5baSBill Taylor static int hermon_rsrc_cqhdl_constructor(void *cq, void *priv, int flags); 1449e39c5baSBill Taylor static void hermon_rsrc_cqhdl_destructor(void *cq, void *state); 1459e39c5baSBill Taylor static int hermon_rsrc_qphdl_constructor(void *cq, void *priv, int flags); 1469e39c5baSBill Taylor static void hermon_rsrc_qphdl_destructor(void *cq, void *state); 1479e39c5baSBill Taylor static int hermon_rsrc_srqhdl_constructor(void *srq, void *priv, int flags); 1489e39c5baSBill Taylor static void hermon_rsrc_srqhdl_destructor(void *srq, void *state); 1499e39c5baSBill Taylor static int hermon_rsrc_refcnt_constructor(void *rc, void *priv, int flags); 1509e39c5baSBill Taylor static void hermon_rsrc_refcnt_destructor(void *rc, void *state); 1519e39c5baSBill Taylor static int hermon_rsrc_ahhdl_constructor(void *ah, void *priv, int flags); 1529e39c5baSBill Taylor static void hermon_rsrc_ahhdl_destructor(void *ah, void *state); 1539e39c5baSBill Taylor static int hermon_rsrc_mrhdl_constructor(void *mr, void *priv, int flags); 1549e39c5baSBill Taylor static void hermon_rsrc_mrhdl_destructor(void *mr, void *state); 1559e39c5baSBill Taylor 1569e39c5baSBill Taylor /* 1579e39c5baSBill Taylor * Special routine to calculate and return the size of a MCG object based 1589e39c5baSBill Taylor * on current driver configuration (specifically, the number of QP per MCG 1599e39c5baSBill Taylor * that has been configured. 1609e39c5baSBill Taylor */ 1619e39c5baSBill Taylor static int hermon_rsrc_mcg_entry_get_size(hermon_state_t *state, 1629e39c5baSBill Taylor uint_t *mcg_size_shift); 1639e39c5baSBill Taylor 1649e39c5baSBill Taylor 1659e39c5baSBill Taylor /* 1669e39c5baSBill Taylor * hermon_rsrc_alloc() 1679e39c5baSBill Taylor * 1689e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 1699e39c5baSBill Taylor * The "sleepflag" parameter is used by all object allocators to 1709e39c5baSBill Taylor * determine whether to SLEEP for resources or not. 1719e39c5baSBill Taylor */ 1729e39c5baSBill Taylor int 1739e39c5baSBill Taylor hermon_rsrc_alloc(hermon_state_t *state, hermon_rsrc_type_t rsrc, uint_t num, 1749e39c5baSBill Taylor uint_t sleepflag, hermon_rsrc_t **hdl) 1759e39c5baSBill Taylor { 1769e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool; 1779e39c5baSBill Taylor hermon_rsrc_t *tmp_rsrc_hdl; 1789e39c5baSBill Taylor int flag, status = DDI_FAILURE; 1799e39c5baSBill Taylor 1809e39c5baSBill Taylor ASSERT(state != NULL); 1819e39c5baSBill Taylor ASSERT(hdl != NULL); 1829e39c5baSBill Taylor 1839e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[rsrc]; 1849e39c5baSBill Taylor ASSERT(rsrc_pool != NULL); 1859e39c5baSBill Taylor 1869e39c5baSBill Taylor /* 1879e39c5baSBill Taylor * Allocate space for the object used to track the resource handle 1889e39c5baSBill Taylor */ 1899e39c5baSBill Taylor flag = (sleepflag == HERMON_SLEEP) ? KM_SLEEP : KM_NOSLEEP; 1909e39c5baSBill Taylor tmp_rsrc_hdl = (hermon_rsrc_t *)kmem_cache_alloc(state->hs_rsrc_cache, 1919e39c5baSBill Taylor flag); 1929e39c5baSBill Taylor if (tmp_rsrc_hdl == NULL) { 1939e39c5baSBill Taylor return (DDI_FAILURE); 1949e39c5baSBill Taylor } 1959e39c5baSBill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*tmp_rsrc_hdl)) 1969e39c5baSBill Taylor 1979e39c5baSBill Taylor /* 1989e39c5baSBill Taylor * Set rsrc_hdl type. This is later used by the hermon_rsrc_free call 1999e39c5baSBill Taylor * to know what type of resource is being freed. 2009e39c5baSBill Taylor */ 2019e39c5baSBill Taylor tmp_rsrc_hdl->rsrc_type = rsrc; 2029e39c5baSBill Taylor 2039e39c5baSBill Taylor /* 2049e39c5baSBill Taylor * Depending on resource type, call the appropriate alloc routine 2059e39c5baSBill Taylor */ 2069e39c5baSBill Taylor switch (rsrc_pool->rsrc_type) { 2079e39c5baSBill Taylor case HERMON_IN_MBOX: 2089e39c5baSBill Taylor case HERMON_OUT_MBOX: 2099e39c5baSBill Taylor case HERMON_INTR_IN_MBOX: 2109e39c5baSBill Taylor case HERMON_INTR_OUT_MBOX: 2119e39c5baSBill Taylor status = hermon_rsrc_mbox_alloc(rsrc_pool, num, tmp_rsrc_hdl); 2129e39c5baSBill Taylor break; 2139e39c5baSBill Taylor 2149e39c5baSBill Taylor case HERMON_QPC: 215*c7facc54SBill Taylor /* Allocate "num" contiguous/aligned QPCs for RSS */ 216*c7facc54SBill Taylor status = hermon_rsrc_hw_entry_alloc(rsrc_pool, num, num, 217*c7facc54SBill Taylor 0, sleepflag, tmp_rsrc_hdl); 218*c7facc54SBill Taylor break; 219*c7facc54SBill Taylor 2209e39c5baSBill Taylor case HERMON_CQC: 2219e39c5baSBill Taylor case HERMON_SRQC: 2229e39c5baSBill Taylor case HERMON_EQC: 2239e39c5baSBill Taylor /* 2249e39c5baSBill Taylor * Because these objects are NOT accessed by Hermon driver 2259e39c5baSBill Taylor * software, we set the acc_handle parameter to zero. 2269e39c5baSBill Taylor */ 2279e39c5baSBill Taylor status = hermon_rsrc_hw_entry_alloc(rsrc_pool, num, 1, 0, 2289e39c5baSBill Taylor sleepflag, tmp_rsrc_hdl); 2299e39c5baSBill Taylor break; 2309e39c5baSBill Taylor 2319e39c5baSBill Taylor case HERMON_DMPT: 2329e39c5baSBill Taylor /* 2339e39c5baSBill Taylor * Because these objects are sometimes accessed by Hermon 2349e39c5baSBill Taylor * driver software (FMR for MPTs), we need the acc_handle 2359e39c5baSBill Taylor * to be set. The ICM-aware code will set it for all 2369e39c5baSBill Taylor * ICM backed resources. 2379e39c5baSBill Taylor * But if they are allocated in multiples, we specify here that 2389e39c5baSBill Taylor * they must be aligned on a more restrictive boundary. 2399e39c5baSBill Taylor */ 2409e39c5baSBill Taylor status = hermon_rsrc_hw_entry_alloc(rsrc_pool, num, num, 2419e39c5baSBill Taylor 0, sleepflag, tmp_rsrc_hdl); 2429e39c5baSBill Taylor break; 2439e39c5baSBill Taylor 2449e39c5baSBill Taylor case HERMON_MCG: 2459e39c5baSBill Taylor /* 2469e39c5baSBill Taylor * Hermon MCG entries are also NOT accessed by Hermon driver 2479e39c5baSBill Taylor * software, but because MCG entries do not have the same 2489e39c5baSBill Taylor * alignnment restrictions we loosen the constraint here. 2499e39c5baSBill Taylor */ 2509e39c5baSBill Taylor status = hermon_rsrc_hw_entry_alloc(rsrc_pool, num, 1, 0, 2519e39c5baSBill Taylor sleepflag, tmp_rsrc_hdl); 2529e39c5baSBill Taylor break; 2539e39c5baSBill Taylor 2549e39c5baSBill Taylor case HERMON_MTT: 2559e39c5baSBill Taylor /* 2569e39c5baSBill Taylor * Because MTT objects are among the few HW resources that 2579e39c5baSBill Taylor * may be allocated in odd numbers, we specify a less 2589e39c5baSBill Taylor * restrictive alignment than for the above resources. 2599e39c5baSBill Taylor */ 2609e39c5baSBill Taylor status = hermon_rsrc_hw_entry_alloc(rsrc_pool, num, 1, 2619e39c5baSBill Taylor 0, sleepflag, tmp_rsrc_hdl); 2629e39c5baSBill Taylor break; 2639e39c5baSBill Taylor 2649e39c5baSBill Taylor case HERMON_UARPG: 2659e39c5baSBill Taylor /* 2669e39c5baSBill Taylor * Because UAR pages are written by Hermon driver software (for 2679e39c5baSBill Taylor * doorbells), we set the acc_handle parameter to point to 2689e39c5baSBill Taylor * the ddi_acc_handle_t for the Hermon UAR memory. 2699e39c5baSBill Taylor */ 2709e39c5baSBill Taylor status = hermon_rsrc_hw_entry_alloc(rsrc_pool, num, 1, 2719e39c5baSBill Taylor hermon_rsrc_alloc_uarhdl(state), sleepflag, tmp_rsrc_hdl); 2729e39c5baSBill Taylor break; 2739e39c5baSBill Taylor 2749e39c5baSBill Taylor case HERMON_MRHDL: 2759e39c5baSBill Taylor case HERMON_EQHDL: 2769e39c5baSBill Taylor case HERMON_CQHDL: 2779e39c5baSBill Taylor case HERMON_SRQHDL: 2789e39c5baSBill Taylor case HERMON_AHHDL: 2799e39c5baSBill Taylor case HERMON_QPHDL: 2809e39c5baSBill Taylor case HERMON_REFCNT: 2819e39c5baSBill Taylor status = hermon_rsrc_swhdl_alloc(rsrc_pool, sleepflag, 2829e39c5baSBill Taylor tmp_rsrc_hdl); 2839e39c5baSBill Taylor break; 2849e39c5baSBill Taylor 2859e39c5baSBill Taylor case HERMON_PDHDL: 2869e39c5baSBill Taylor status = hermon_rsrc_pdhdl_alloc(rsrc_pool, sleepflag, 2879e39c5baSBill Taylor tmp_rsrc_hdl); 2889e39c5baSBill Taylor break; 2899e39c5baSBill Taylor 2909e39c5baSBill Taylor case HERMON_RDB: /* handled during HERMON_QPC */ 2919e39c5baSBill Taylor case HERMON_ALTC: /* handled during HERMON_QPC */ 2929e39c5baSBill Taylor case HERMON_AUXC: /* handled during HERMON_QPC */ 2939e39c5baSBill Taylor case HERMON_CMPT_QPC: /* handled during HERMON_QPC */ 2949e39c5baSBill Taylor case HERMON_CMPT_SRQC: /* handled during HERMON_SRQC */ 2959e39c5baSBill Taylor case HERMON_CMPT_CQC: /* handled during HERMON_CPC */ 2969e39c5baSBill Taylor case HERMON_CMPT_EQC: /* handled during HERMON_EPC */ 2979e39c5baSBill Taylor default: 2989e39c5baSBill Taylor HERMON_WARNING(state, "unexpected resource type in alloc "); 2999e39c5baSBill Taylor cmn_err(CE_WARN, "Resource type %x \n", rsrc_pool->rsrc_type); 3009e39c5baSBill Taylor break; 3019e39c5baSBill Taylor } 3029e39c5baSBill Taylor 3039e39c5baSBill Taylor /* 3049e39c5baSBill Taylor * If the resource allocation failed, then free the special resource 3059e39c5baSBill Taylor * tracking structure and return failure. Otherwise return the 3069e39c5baSBill Taylor * handle for the resource tracking structure. 3079e39c5baSBill Taylor */ 3089e39c5baSBill Taylor if (status != DDI_SUCCESS) { 3099e39c5baSBill Taylor kmem_cache_free(state->hs_rsrc_cache, tmp_rsrc_hdl); 3109e39c5baSBill Taylor tmp_rsrc_hdl = NULL; 3119e39c5baSBill Taylor return (DDI_FAILURE); 3129e39c5baSBill Taylor } else { 3139e39c5baSBill Taylor *hdl = tmp_rsrc_hdl; 3149e39c5baSBill Taylor return (DDI_SUCCESS); 3159e39c5baSBill Taylor } 3169e39c5baSBill Taylor } 3179e39c5baSBill Taylor 3189e39c5baSBill Taylor 3199e39c5baSBill Taylor /* 3209e39c5baSBill Taylor * hermon_rsrc_free() 3219e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 3229e39c5baSBill Taylor */ 3239e39c5baSBill Taylor void 3249e39c5baSBill Taylor hermon_rsrc_free(hermon_state_t *state, hermon_rsrc_t **hdl) 3259e39c5baSBill Taylor { 3269e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool; 3279e39c5baSBill Taylor 3289e39c5baSBill Taylor ASSERT(state != NULL); 3299e39c5baSBill Taylor ASSERT(hdl != NULL); 3309e39c5baSBill Taylor 3319e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[(*hdl)->rsrc_type]; 3329e39c5baSBill Taylor ASSERT(rsrc_pool != NULL); 3339e39c5baSBill Taylor 3349e39c5baSBill Taylor /* 3359e39c5baSBill Taylor * Depending on resource type, call the appropriate free routine 3369e39c5baSBill Taylor */ 3379e39c5baSBill Taylor switch (rsrc_pool->rsrc_type) { 3389e39c5baSBill Taylor case HERMON_IN_MBOX: 3399e39c5baSBill Taylor case HERMON_OUT_MBOX: 3409e39c5baSBill Taylor case HERMON_INTR_IN_MBOX: 3419e39c5baSBill Taylor case HERMON_INTR_OUT_MBOX: 3429e39c5baSBill Taylor hermon_rsrc_mbox_free(rsrc_pool, *hdl); 3439e39c5baSBill Taylor break; 3449e39c5baSBill Taylor 3459e39c5baSBill Taylor case HERMON_QPC: 3469e39c5baSBill Taylor case HERMON_CQC: 3479e39c5baSBill Taylor case HERMON_SRQC: 3489e39c5baSBill Taylor case HERMON_EQC: 3499e39c5baSBill Taylor case HERMON_DMPT: 3509e39c5baSBill Taylor case HERMON_MCG: 3519e39c5baSBill Taylor case HERMON_MTT: 3529e39c5baSBill Taylor case HERMON_UARPG: 3539e39c5baSBill Taylor hermon_rsrc_hw_entry_free(rsrc_pool, *hdl); 3549e39c5baSBill Taylor break; 3559e39c5baSBill Taylor 3569e39c5baSBill Taylor case HERMON_MRHDL: 3579e39c5baSBill Taylor case HERMON_EQHDL: 3589e39c5baSBill Taylor case HERMON_CQHDL: 3599e39c5baSBill Taylor case HERMON_SRQHDL: 3609e39c5baSBill Taylor case HERMON_AHHDL: 3619e39c5baSBill Taylor case HERMON_QPHDL: 3629e39c5baSBill Taylor case HERMON_REFCNT: 3639e39c5baSBill Taylor hermon_rsrc_swhdl_free(rsrc_pool, *hdl); 3649e39c5baSBill Taylor break; 3659e39c5baSBill Taylor 3669e39c5baSBill Taylor case HERMON_PDHDL: 3679e39c5baSBill Taylor hermon_rsrc_pdhdl_free(rsrc_pool, *hdl); 3689e39c5baSBill Taylor break; 3699e39c5baSBill Taylor 3709e39c5baSBill Taylor case HERMON_RDB: 3719e39c5baSBill Taylor case HERMON_ALTC: 3729e39c5baSBill Taylor case HERMON_AUXC: 3739e39c5baSBill Taylor case HERMON_CMPT_QPC: 3749e39c5baSBill Taylor case HERMON_CMPT_SRQC: 3759e39c5baSBill Taylor case HERMON_CMPT_CQC: 3769e39c5baSBill Taylor case HERMON_CMPT_EQC: 3779e39c5baSBill Taylor default: 3789e39c5baSBill Taylor HERMON_WARNING(state, "unexpected resource type in free"); 3799e39c5baSBill Taylor break; 3809e39c5baSBill Taylor } 3819e39c5baSBill Taylor 3829e39c5baSBill Taylor /* 3839e39c5baSBill Taylor * Free the special resource tracking structure, set the handle to 3849e39c5baSBill Taylor * NULL, and return. 3859e39c5baSBill Taylor */ 3869e39c5baSBill Taylor kmem_cache_free(state->hs_rsrc_cache, *hdl); 3879e39c5baSBill Taylor *hdl = NULL; 3889e39c5baSBill Taylor } 3899e39c5baSBill Taylor 3909e39c5baSBill Taylor 3919e39c5baSBill Taylor /* 3929e39c5baSBill Taylor * hermon_rsrc_init_phase1() 3939e39c5baSBill Taylor * 3949e39c5baSBill Taylor * Completes the first phase of Hermon resource/configuration init. 3959e39c5baSBill Taylor * This involves creating the kmem_cache for the "hermon_rsrc_t" 3969e39c5baSBill Taylor * structs, allocating the space for the resource pool handles, 3979e39c5baSBill Taylor * and setting up the "Out" mailboxes. 3989e39c5baSBill Taylor * 3999e39c5baSBill Taylor * When this function completes, the Hermon driver is ready to 4009e39c5baSBill Taylor * post the following commands which return information only in the 4019e39c5baSBill Taylor * "Out" mailbox: QUERY_DDR, QUERY_FW, QUERY_DEV_LIM, and QUERY_ADAPTER 4029e39c5baSBill Taylor * If any of these commands are to be posted at this time, they must be 4039e39c5baSBill Taylor * done so only when "spinning" (as the outstanding command list and 4049e39c5baSBill Taylor * EQ setup code has not yet run) 4059e39c5baSBill Taylor * 4069e39c5baSBill Taylor * Context: Only called from attach() path context 4079e39c5baSBill Taylor */ 4089e39c5baSBill Taylor int 4099e39c5baSBill Taylor hermon_rsrc_init_phase1(hermon_state_t *state) 4109e39c5baSBill Taylor { 4119e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool; 4129e39c5baSBill Taylor hermon_rsrc_mbox_info_t mbox_info; 4139e39c5baSBill Taylor hermon_rsrc_cleanup_level_t cleanup; 4149e39c5baSBill Taylor hermon_cfg_profile_t *cfgprof; 4159e39c5baSBill Taylor uint64_t num, size; 4169e39c5baSBill Taylor int status; 4179e39c5baSBill Taylor char *rsrc_name; 4189e39c5baSBill Taylor 4199e39c5baSBill Taylor ASSERT(state != NULL); 4209e39c5baSBill Taylor 4219e39c5baSBill Taylor /* This is where Phase 1 of resource initialization begins */ 4229e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL0; 4239e39c5baSBill Taylor 4249e39c5baSBill Taylor /* Build kmem cache name from Hermon instance */ 4259e39c5baSBill Taylor rsrc_name = (char *)kmem_zalloc(HERMON_RSRC_NAME_MAXLEN, KM_SLEEP); 4269e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_RSRC_CACHE); 4279e39c5baSBill Taylor 4289e39c5baSBill Taylor /* 4299e39c5baSBill Taylor * Create the kmem_cache for "hermon_rsrc_t" structures 4309e39c5baSBill Taylor * (kmem_cache_create will SLEEP until successful) 4319e39c5baSBill Taylor */ 4329e39c5baSBill Taylor state->hs_rsrc_cache = kmem_cache_create(rsrc_name, 4339e39c5baSBill Taylor sizeof (hermon_rsrc_t), 0, NULL, NULL, NULL, NULL, NULL, 0); 4349e39c5baSBill Taylor 4359e39c5baSBill Taylor /* 4369e39c5baSBill Taylor * Allocate an array of hermon_rsrc_pool_info_t's (used in all 4379e39c5baSBill Taylor * subsequent resource allocations) 4389e39c5baSBill Taylor */ 4399e39c5baSBill Taylor state->hs_rsrc_hdl = kmem_zalloc(HERMON_NUM_RESOURCES * 4409e39c5baSBill Taylor sizeof (hermon_rsrc_pool_info_t), KM_SLEEP); 4419e39c5baSBill Taylor 4429e39c5baSBill Taylor /* Pull in the configuration profile */ 4439e39c5baSBill Taylor cfgprof = state->hs_cfg_profile; 4449e39c5baSBill Taylor 4459e39c5baSBill Taylor /* Initialize the resource pool for "out" mailboxes */ 4469e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_outmbox); 4479e39c5baSBill Taylor size = ((uint64_t)1 << cfgprof->cp_log_outmbox_size); 4489e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[HERMON_OUT_MBOX]; 4499e39c5baSBill Taylor rsrc_pool->rsrc_type = HERMON_OUT_MBOX; 4509e39c5baSBill Taylor rsrc_pool->rsrc_loc = HERMON_IN_SYSMEM; 4519e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (size * num); 4529e39c5baSBill Taylor rsrc_pool->rsrc_shift = cfgprof->cp_log_outmbox_size; 4539e39c5baSBill Taylor rsrc_pool->rsrc_quantum = (uint_t)size; 4549e39c5baSBill Taylor rsrc_pool->rsrc_align = HERMON_MBOX_ALIGN; 4559e39c5baSBill Taylor rsrc_pool->rsrc_state = state; 4569e39c5baSBill Taylor mbox_info.mbi_num = num; 4579e39c5baSBill Taylor mbox_info.mbi_size = size; 4589e39c5baSBill Taylor mbox_info.mbi_rsrcpool = rsrc_pool; 4599e39c5baSBill Taylor status = hermon_rsrc_mbox_init(state, &mbox_info); 4609e39c5baSBill Taylor if (status != DDI_SUCCESS) { 4619e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup); 4629e39c5baSBill Taylor status = DDI_FAILURE; 4639e39c5baSBill Taylor goto rsrcinitp1_fail; 4649e39c5baSBill Taylor } 4659e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL1; 4669e39c5baSBill Taylor 4679e39c5baSBill Taylor /* Initialize the mailbox list */ 4689e39c5baSBill Taylor status = hermon_outmbox_list_init(state); 4699e39c5baSBill Taylor if (status != DDI_SUCCESS) { 4709e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup); 4719e39c5baSBill Taylor status = DDI_FAILURE; 4729e39c5baSBill Taylor goto rsrcinitp1_fail; 4739e39c5baSBill Taylor } 4749e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL2; 4759e39c5baSBill Taylor 4769e39c5baSBill Taylor /* Initialize the resource pool for "interrupt out" mailboxes */ 4779e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_intr_outmbox); 4789e39c5baSBill Taylor size = ((uint64_t)1 << cfgprof->cp_log_outmbox_size); 4799e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[HERMON_INTR_OUT_MBOX]; 4809e39c5baSBill Taylor rsrc_pool->rsrc_type = HERMON_INTR_OUT_MBOX; 4819e39c5baSBill Taylor rsrc_pool->rsrc_loc = HERMON_IN_SYSMEM; 4829e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (size * num); 4839e39c5baSBill Taylor rsrc_pool->rsrc_shift = cfgprof->cp_log_outmbox_size; 4849e39c5baSBill Taylor rsrc_pool->rsrc_quantum = (uint_t)size; 4859e39c5baSBill Taylor rsrc_pool->rsrc_align = HERMON_MBOX_ALIGN; 4869e39c5baSBill Taylor rsrc_pool->rsrc_state = state; 4879e39c5baSBill Taylor mbox_info.mbi_num = num; 4889e39c5baSBill Taylor mbox_info.mbi_size = size; 4899e39c5baSBill Taylor mbox_info.mbi_rsrcpool = rsrc_pool; 4909e39c5baSBill Taylor status = hermon_rsrc_mbox_init(state, &mbox_info); 4919e39c5baSBill Taylor if (status != DDI_SUCCESS) { 4929e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup); 4939e39c5baSBill Taylor status = DDI_FAILURE; 4949e39c5baSBill Taylor goto rsrcinitp1_fail; 4959e39c5baSBill Taylor } 4969e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL3; 4979e39c5baSBill Taylor 4989e39c5baSBill Taylor /* Initialize the mailbox list */ 4999e39c5baSBill Taylor status = hermon_intr_outmbox_list_init(state); 5009e39c5baSBill Taylor if (status != DDI_SUCCESS) { 5019e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup); 5029e39c5baSBill Taylor status = DDI_FAILURE; 5039e39c5baSBill Taylor goto rsrcinitp1_fail; 5049e39c5baSBill Taylor } 5059e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL4; 5069e39c5baSBill Taylor 5079e39c5baSBill Taylor /* Initialize the resource pool for "in" mailboxes */ 5089e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_inmbox); 5099e39c5baSBill Taylor size = ((uint64_t)1 << cfgprof->cp_log_inmbox_size); 5109e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[HERMON_IN_MBOX]; 5119e39c5baSBill Taylor rsrc_pool->rsrc_type = HERMON_IN_MBOX; 5129e39c5baSBill Taylor rsrc_pool->rsrc_loc = HERMON_IN_SYSMEM; 5139e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (size * num); 5149e39c5baSBill Taylor rsrc_pool->rsrc_shift = cfgprof->cp_log_inmbox_size; 5159e39c5baSBill Taylor rsrc_pool->rsrc_quantum = (uint_t)size; 5169e39c5baSBill Taylor rsrc_pool->rsrc_align = HERMON_MBOX_ALIGN; 5179e39c5baSBill Taylor rsrc_pool->rsrc_state = state; 5189e39c5baSBill Taylor mbox_info.mbi_num = num; 5199e39c5baSBill Taylor mbox_info.mbi_size = size; 5209e39c5baSBill Taylor mbox_info.mbi_rsrcpool = rsrc_pool; 5219e39c5baSBill Taylor status = hermon_rsrc_mbox_init(state, &mbox_info); 5229e39c5baSBill Taylor if (status != DDI_SUCCESS) { 5239e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup); 5249e39c5baSBill Taylor status = DDI_FAILURE; 5259e39c5baSBill Taylor goto rsrcinitp1_fail; 5269e39c5baSBill Taylor } 5279e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL5; 5289e39c5baSBill Taylor 5299e39c5baSBill Taylor /* Initialize the mailbox list */ 5309e39c5baSBill Taylor status = hermon_inmbox_list_init(state); 5319e39c5baSBill Taylor if (status != DDI_SUCCESS) { 5329e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup); 5339e39c5baSBill Taylor status = DDI_FAILURE; 5349e39c5baSBill Taylor goto rsrcinitp1_fail; 5359e39c5baSBill Taylor } 5369e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL6; 5379e39c5baSBill Taylor 5389e39c5baSBill Taylor /* Initialize the resource pool for "interrupt in" mailboxes */ 5399e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_intr_inmbox); 5409e39c5baSBill Taylor size = ((uint64_t)1 << cfgprof->cp_log_inmbox_size); 5419e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[HERMON_INTR_IN_MBOX]; 5429e39c5baSBill Taylor rsrc_pool->rsrc_type = HERMON_INTR_IN_MBOX; 5439e39c5baSBill Taylor rsrc_pool->rsrc_loc = HERMON_IN_SYSMEM; 5449e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (size * num); 5459e39c5baSBill Taylor rsrc_pool->rsrc_shift = cfgprof->cp_log_inmbox_size; 5469e39c5baSBill Taylor rsrc_pool->rsrc_quantum = (uint_t)size; 5479e39c5baSBill Taylor rsrc_pool->rsrc_align = HERMON_MBOX_ALIGN; 5489e39c5baSBill Taylor rsrc_pool->rsrc_state = state; 5499e39c5baSBill Taylor mbox_info.mbi_num = num; 5509e39c5baSBill Taylor mbox_info.mbi_size = size; 5519e39c5baSBill Taylor mbox_info.mbi_rsrcpool = rsrc_pool; 5529e39c5baSBill Taylor status = hermon_rsrc_mbox_init(state, &mbox_info); 5539e39c5baSBill Taylor if (status != DDI_SUCCESS) { 5549e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup); 5559e39c5baSBill Taylor status = DDI_FAILURE; 5569e39c5baSBill Taylor goto rsrcinitp1_fail; 5579e39c5baSBill Taylor } 5589e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL7; 5599e39c5baSBill Taylor 5609e39c5baSBill Taylor /* Initialize the mailbox list */ 5619e39c5baSBill Taylor status = hermon_intr_inmbox_list_init(state); 5629e39c5baSBill Taylor if (status != DDI_SUCCESS) { 5639e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup); 5649e39c5baSBill Taylor status = DDI_FAILURE; 5659e39c5baSBill Taylor goto rsrcinitp1_fail; 5669e39c5baSBill Taylor } 5679e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_PHASE1_COMPLETE; 5689e39c5baSBill Taylor kmem_free(rsrc_name, HERMON_RSRC_NAME_MAXLEN); 5699e39c5baSBill Taylor return (DDI_SUCCESS); 5709e39c5baSBill Taylor 5719e39c5baSBill Taylor rsrcinitp1_fail: 5729e39c5baSBill Taylor kmem_free(rsrc_name, HERMON_RSRC_NAME_MAXLEN); 5739e39c5baSBill Taylor return (status); 5749e39c5baSBill Taylor } 5759e39c5baSBill Taylor 5769e39c5baSBill Taylor 5779e39c5baSBill Taylor /* 5789e39c5baSBill Taylor * hermon_rsrc_init_phase2() 5799e39c5baSBill Taylor * Context: Only called from attach() path context 5809e39c5baSBill Taylor */ 5819e39c5baSBill Taylor int 5829e39c5baSBill Taylor hermon_rsrc_init_phase2(hermon_state_t *state) 5839e39c5baSBill Taylor { 5849e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t hdl_info; 5859e39c5baSBill Taylor hermon_rsrc_hw_entry_info_t entry_info; 5869e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool; 5879e39c5baSBill Taylor hermon_rsrc_cleanup_level_t cleanup, ncleanup; 5889e39c5baSBill Taylor hermon_cfg_profile_t *cfgprof; 5899e39c5baSBill Taylor hermon_hw_querydevlim_t *devlim; 5909e39c5baSBill Taylor uint64_t num, max, num_prealloc; 5919e39c5baSBill Taylor uint_t mcg_size, mcg_size_shift; 5929e39c5baSBill Taylor int i, status; 5939e39c5baSBill Taylor char *rsrc_name; 5949e39c5baSBill Taylor 5959e39c5baSBill Taylor ASSERT(state != NULL); 5969e39c5baSBill Taylor 5979e39c5baSBill Taylor /* Phase 2 initialization begins where Phase 1 left off */ 5989e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_PHASE1_COMPLETE; 5999e39c5baSBill Taylor 6009e39c5baSBill Taylor /* Allocate the ICM resource name space */ 6019e39c5baSBill Taylor 6029e39c5baSBill Taylor /* Build the ICM vmem arena names from Hermon instance */ 6039e39c5baSBill Taylor rsrc_name = (char *)kmem_zalloc(HERMON_RSRC_NAME_MAXLEN, KM_SLEEP); 6049e39c5baSBill Taylor 6059e39c5baSBill Taylor /* 6069e39c5baSBill Taylor * Initialize the resource pools for all objects that exist in 6079e39c5baSBill Taylor * context memory (ICM). The ICM consists of context tables, each 6089e39c5baSBill Taylor * type of resource (QP, CQ, EQ, etc) having it's own context table 6099e39c5baSBill Taylor * (QPC, CQC, EQC, etc...). 6109e39c5baSBill Taylor */ 6119e39c5baSBill Taylor cfgprof = state->hs_cfg_profile; 6129e39c5baSBill Taylor devlim = &state->hs_devlim; 6139e39c5baSBill Taylor 6149e39c5baSBill Taylor /* 6159e39c5baSBill Taylor * Initialize the resource pools for each of the driver resources. 6169e39c5baSBill Taylor * With a few exceptions, these resources fall into the two cateogories 6179e39c5baSBill Taylor * of either hw_entries or sw_entries. 6189e39c5baSBill Taylor */ 6199e39c5baSBill Taylor 6209e39c5baSBill Taylor /* 6219e39c5baSBill Taylor * Initialize the resource pools for ICM (hardware) types first. 6229e39c5baSBill Taylor * These resources are managed through vmem arenas, which are 6239e39c5baSBill Taylor * created via the rsrc pool initialization routine. Note that, 6249e39c5baSBill Taylor * due to further calculations, the MCG resource pool is 6259e39c5baSBill Taylor * initialized seperately. 6269e39c5baSBill Taylor */ 6279e39c5baSBill Taylor for (i = 0; i < HERMON_NUM_ICM_RESOURCES; i++) { 6289e39c5baSBill Taylor 6299e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[i]; 6309e39c5baSBill Taylor rsrc_pool->rsrc_type = i; 6319e39c5baSBill Taylor 6329e39c5baSBill Taylor /* Set the resource-specific attributes */ 6339e39c5baSBill Taylor switch (i) { 6349e39c5baSBill Taylor case HERMON_MTT: 6359e39c5baSBill Taylor max = ((uint64_t)1 << devlim->log_max_mtt); 6369e39c5baSBill Taylor num_prealloc = ((uint64_t)1 << devlim->log_rsvd_mtt); 6379e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_MTT_VMEM); 6389e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL9; 6399e39c5baSBill Taylor break; 6409e39c5baSBill Taylor 6419e39c5baSBill Taylor case HERMON_DMPT: 6429e39c5baSBill Taylor max = ((uint64_t)1 << devlim->log_max_dmpt); 6439e39c5baSBill Taylor num_prealloc = ((uint64_t)1 << devlim->log_rsvd_dmpt); 6449e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_DMPT_VMEM); 6459e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL10; 6469e39c5baSBill Taylor break; 6479e39c5baSBill Taylor 6489e39c5baSBill Taylor case HERMON_QPC: 6499e39c5baSBill Taylor max = ((uint64_t)1 << devlim->log_max_qp); 6509e39c5baSBill Taylor num_prealloc = ((uint64_t)1 << devlim->log_rsvd_qp); 6519e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_QPC_VMEM); 6529e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL11; 6539e39c5baSBill Taylor break; 6549e39c5baSBill Taylor 6559e39c5baSBill Taylor case HERMON_CQC: 6569e39c5baSBill Taylor max = ((uint64_t)1 << devlim->log_max_cq); 6579e39c5baSBill Taylor num_prealloc = ((uint64_t)1 << devlim->log_rsvd_cq); 6589e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_CQC_VMEM); 6599e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL13; 6609e39c5baSBill Taylor break; 6619e39c5baSBill Taylor 6629e39c5baSBill Taylor case HERMON_SRQC: 6639e39c5baSBill Taylor max = ((uint64_t)1 << devlim->log_max_srq); 6649e39c5baSBill Taylor num_prealloc = ((uint64_t)1 << devlim->log_rsvd_srq); 6659e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_SRQC_VMEM); 6669e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL16; 6679e39c5baSBill Taylor break; 6689e39c5baSBill Taylor 6699e39c5baSBill Taylor case HERMON_EQC: 6709e39c5baSBill Taylor max = ((uint64_t)1 << devlim->log_max_eq); 6719e39c5baSBill Taylor num_prealloc = devlim->num_rsvd_eq; 6729e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_EQC_VMEM); 6739e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL18; 6749e39c5baSBill Taylor break; 6759e39c5baSBill Taylor 6769e39c5baSBill Taylor case HERMON_MCG: /* handled below */ 6779e39c5baSBill Taylor case HERMON_AUXC: 6789e39c5baSBill Taylor case HERMON_ALTC: 6799e39c5baSBill Taylor case HERMON_RDB: 6809e39c5baSBill Taylor case HERMON_CMPT_QPC: 6819e39c5baSBill Taylor case HERMON_CMPT_SRQC: 6829e39c5baSBill Taylor case HERMON_CMPT_CQC: 6839e39c5baSBill Taylor case HERMON_CMPT_EQC: 6849e39c5baSBill Taylor default: 6859e39c5baSBill Taylor /* We don't need to initialize this rsrc here. */ 6869e39c5baSBill Taylor continue; 6879e39c5baSBill Taylor } 6889e39c5baSBill Taylor 6899e39c5baSBill Taylor /* Set the common values for all resource pools */ 6909e39c5baSBill Taylor rsrc_pool->rsrc_state = state; 6919e39c5baSBill Taylor rsrc_pool->rsrc_loc = HERMON_IN_ICM; 6929e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = state->hs_icm[i].table_size; 6939e39c5baSBill Taylor rsrc_pool->rsrc_align = state->hs_icm[i].table_size; 6949e39c5baSBill Taylor rsrc_pool->rsrc_shift = state->hs_icm[i].log_object_size; 6959e39c5baSBill Taylor rsrc_pool->rsrc_quantum = state->hs_icm[i].object_size; 6969e39c5baSBill Taylor 6979e39c5baSBill Taylor /* Now, initialize the entry_info and call the init routine */ 6989e39c5baSBill Taylor entry_info.hwi_num = state->hs_icm[i].num_entries; 6999e39c5baSBill Taylor entry_info.hwi_max = max; 7009e39c5baSBill Taylor entry_info.hwi_prealloc = num_prealloc; 7019e39c5baSBill Taylor entry_info.hwi_rsrcpool = rsrc_pool; 7029e39c5baSBill Taylor entry_info.hwi_rsrcname = rsrc_name; 7039e39c5baSBill Taylor status = hermon_rsrc_hw_entries_init(state, &entry_info); 7049e39c5baSBill Taylor if (status != DDI_SUCCESS) { 7059e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup); 7069e39c5baSBill Taylor status = DDI_FAILURE; 7079e39c5baSBill Taylor goto rsrcinitp2_fail; 7089e39c5baSBill Taylor } 7099e39c5baSBill Taylor cleanup = ncleanup; 7109e39c5baSBill Taylor } 7119e39c5baSBill Taylor 7129e39c5baSBill Taylor /* 7139e39c5baSBill Taylor * Initialize the Multicast Group (MCG) entries. First, calculate 7149e39c5baSBill Taylor * (and validate) the size of the MCGs. 7159e39c5baSBill Taylor */ 7169e39c5baSBill Taylor status = hermon_rsrc_mcg_entry_get_size(state, &mcg_size_shift); 7179e39c5baSBill Taylor if (status != DDI_SUCCESS) { 7189e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup); 7199e39c5baSBill Taylor status = DDI_FAILURE; 7209e39c5baSBill Taylor goto rsrcinitp2_fail; 7219e39c5baSBill Taylor } 7229e39c5baSBill Taylor mcg_size = HERMON_MCGMEM_SZ(state); 7239e39c5baSBill Taylor 7249e39c5baSBill Taylor /* 7259e39c5baSBill Taylor * Initialize the resource pool for the MCG table entries. Notice 7269e39c5baSBill Taylor * that the number of MCGs is configurable. Note also that a certain 7279e39c5baSBill Taylor * number of MCGs must be set aside for Hermon firmware use (they 7289e39c5baSBill Taylor * correspond to the number of MCGs used by the internal hash 7299e39c5baSBill Taylor * function). 7309e39c5baSBill Taylor */ 7319e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_mcg); 7329e39c5baSBill Taylor max = ((uint64_t)1 << devlim->log_max_mcg); 7339e39c5baSBill Taylor num_prealloc = ((uint64_t)1 << cfgprof->cp_log_num_mcg_hash); 7349e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[HERMON_MCG]; 7359e39c5baSBill Taylor rsrc_pool->rsrc_type = HERMON_MCG; 7369e39c5baSBill Taylor rsrc_pool->rsrc_loc = HERMON_IN_ICM; 7379e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (mcg_size * num); 7389e39c5baSBill Taylor rsrc_pool->rsrc_shift = mcg_size_shift; 7399e39c5baSBill Taylor rsrc_pool->rsrc_quantum = mcg_size; 7409e39c5baSBill Taylor rsrc_pool->rsrc_align = (mcg_size * num); 7419e39c5baSBill Taylor rsrc_pool->rsrc_state = state; 7429e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_MCG_VMEM); 7439e39c5baSBill Taylor entry_info.hwi_num = num; 7449e39c5baSBill Taylor entry_info.hwi_max = max; 7459e39c5baSBill Taylor entry_info.hwi_prealloc = num_prealloc; 7469e39c5baSBill Taylor entry_info.hwi_rsrcpool = rsrc_pool; 7479e39c5baSBill Taylor entry_info.hwi_rsrcname = rsrc_name; 7489e39c5baSBill Taylor status = hermon_rsrc_hw_entries_init(state, &entry_info); 7499e39c5baSBill Taylor if (status != DDI_SUCCESS) { 7509e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup); 7519e39c5baSBill Taylor status = DDI_FAILURE; 7529e39c5baSBill Taylor goto rsrcinitp2_fail; 7539e39c5baSBill Taylor } 7549e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL19; 7559e39c5baSBill Taylor 7569e39c5baSBill Taylor /* 7579e39c5baSBill Taylor * Initialize the full range of ICM for the AUXC resource. 7589e39c5baSBill Taylor * This is done because its size is so small, about 1 byte per QP. 7599e39c5baSBill Taylor */ 7609e39c5baSBill Taylor 7619e39c5baSBill Taylor /* 7629e39c5baSBill Taylor * Initialize the Hermon command handling interfaces. This step 7639e39c5baSBill Taylor * sets up the outstanding command tracking mechanism for easy access 7649e39c5baSBill Taylor * and fast allocation (see hermon_cmd.c for more details). 7659e39c5baSBill Taylor */ 7669e39c5baSBill Taylor status = hermon_outstanding_cmdlist_init(state); 7679e39c5baSBill Taylor if (status != DDI_SUCCESS) { 7689e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup); 7699e39c5baSBill Taylor status = DDI_FAILURE; 7709e39c5baSBill Taylor goto rsrcinitp2_fail; 7719e39c5baSBill Taylor } 7729e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL20; 7739e39c5baSBill Taylor 7749e39c5baSBill Taylor /* Initialize the resource pool and vmem arena for the PD handles */ 7759e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[HERMON_PDHDL]; 7769e39c5baSBill Taylor rsrc_pool->rsrc_type = HERMON_PDHDL; 7779e39c5baSBill Taylor rsrc_pool->rsrc_loc = HERMON_IN_SYSMEM; 7789e39c5baSBill Taylor rsrc_pool->rsrc_quantum = sizeof (struct hermon_sw_pd_s); 7799e39c5baSBill Taylor rsrc_pool->rsrc_state = state; 7809e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_PDHDL_CACHE); 7819e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_pd); 7829e39c5baSBill Taylor hdl_info.swi_max = ((uint64_t)1 << devlim->log_max_pd); 7839e39c5baSBill Taylor hdl_info.swi_rsrcpool = rsrc_pool; 7849e39c5baSBill Taylor hdl_info.swi_constructor = hermon_rsrc_pdhdl_constructor; 7859e39c5baSBill Taylor hdl_info.swi_destructor = hermon_rsrc_pdhdl_destructor; 7869e39c5baSBill Taylor hdl_info.swi_rsrcname = rsrc_name; 7879e39c5baSBill Taylor hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT; 7889e39c5baSBill Taylor status = hermon_rsrc_pd_handles_init(state, &hdl_info); 7899e39c5baSBill Taylor if (status != DDI_SUCCESS) { 7909e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup); 7919e39c5baSBill Taylor status = DDI_FAILURE; 7929e39c5baSBill Taylor goto rsrcinitp2_fail; 7939e39c5baSBill Taylor } 7949e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL21; 7959e39c5baSBill Taylor 7969e39c5baSBill Taylor /* 7979e39c5baSBill Taylor * Initialize the resource pools for the rest of the software handles. 7989e39c5baSBill Taylor * This includes MR handles, EQ handles, QP handles, etc. These 7999e39c5baSBill Taylor * objects are almost entirely managed using kmem_cache routines, 8009e39c5baSBill Taylor * and do not utilize a vmem arena. 8019e39c5baSBill Taylor */ 8029e39c5baSBill Taylor for (i = HERMON_NUM_ICM_RESOURCES; i < HERMON_NUM_RESOURCES; i++) { 8039e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[i]; 8049e39c5baSBill Taylor 8059e39c5baSBill Taylor /* Set the resource-specific attributes */ 8069e39c5baSBill Taylor switch (i) { 8079e39c5baSBill Taylor case HERMON_MRHDL: 8089e39c5baSBill Taylor rsrc_pool->rsrc_type = HERMON_MRHDL; 8099e39c5baSBill Taylor rsrc_pool->rsrc_quantum = 8109e39c5baSBill Taylor sizeof (struct hermon_sw_mr_s); 8119e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_MRHDL_CACHE); 8129e39c5baSBill Taylor hdl_info.swi_num = 8139e39c5baSBill Taylor ((uint64_t)1 << cfgprof->cp_log_num_dmpt) + 8149e39c5baSBill Taylor ((uint64_t)1 << cfgprof->cp_log_num_cmpt); 8159e39c5baSBill Taylor hdl_info.swi_max = 8169e39c5baSBill Taylor ((uint64_t)1 << cfgprof->cp_log_num_dmpt) + 8179e39c5baSBill Taylor ((uint64_t)1 << cfgprof->cp_log_num_cmpt); 8189e39c5baSBill Taylor hdl_info.swi_constructor = 8199e39c5baSBill Taylor hermon_rsrc_mrhdl_constructor; 8209e39c5baSBill Taylor hdl_info.swi_destructor = hermon_rsrc_mrhdl_destructor; 8219e39c5baSBill Taylor hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT; 8229e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL22; 8239e39c5baSBill Taylor break; 8249e39c5baSBill Taylor 8259e39c5baSBill Taylor case HERMON_EQHDL: 8269e39c5baSBill Taylor rsrc_pool->rsrc_type = HERMON_EQHDL; 8279e39c5baSBill Taylor rsrc_pool->rsrc_quantum = 8289e39c5baSBill Taylor sizeof (struct hermon_sw_eq_s); 8299e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_EQHDL_CACHE); 8309e39c5baSBill Taylor hdl_info.swi_num = HERMON_NUM_EQ; 8319e39c5baSBill Taylor hdl_info.swi_max = ((uint64_t)1 << devlim->log_max_eq); 8329e39c5baSBill Taylor hdl_info.swi_constructor = NULL; 8339e39c5baSBill Taylor hdl_info.swi_destructor = NULL; 8349e39c5baSBill Taylor hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT; 8359e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL23; 8369e39c5baSBill Taylor break; 8379e39c5baSBill Taylor 8389e39c5baSBill Taylor case HERMON_CQHDL: 8399e39c5baSBill Taylor rsrc_pool->rsrc_type = HERMON_CQHDL; 8409e39c5baSBill Taylor rsrc_pool->rsrc_quantum = 8419e39c5baSBill Taylor sizeof (struct hermon_sw_cq_s); 8429e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_CQHDL_CACHE); 8439e39c5baSBill Taylor hdl_info.swi_num = 8449e39c5baSBill Taylor (uint64_t)1 << cfgprof->cp_log_num_cq; 8459e39c5baSBill Taylor hdl_info.swi_max = (uint64_t)1 << devlim->log_max_cq; 8469e39c5baSBill Taylor hdl_info.swi_constructor = 8479e39c5baSBill Taylor hermon_rsrc_cqhdl_constructor; 8489e39c5baSBill Taylor hdl_info.swi_destructor = hermon_rsrc_cqhdl_destructor; 8499e39c5baSBill Taylor hdl_info.swi_flags = (HERMON_SWHDL_KMEMCACHE_INIT | 8509e39c5baSBill Taylor HERMON_SWHDL_TABLE_INIT); 8519e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (hermon_cqhdl_t); 8529e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL24; 8539e39c5baSBill Taylor break; 8549e39c5baSBill Taylor 8559e39c5baSBill Taylor case HERMON_SRQHDL: 8569e39c5baSBill Taylor rsrc_pool->rsrc_type = HERMON_SRQHDL; 8579e39c5baSBill Taylor rsrc_pool->rsrc_quantum = 8589e39c5baSBill Taylor sizeof (struct hermon_sw_srq_s); 8599e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_SRQHDL_CACHE); 8609e39c5baSBill Taylor hdl_info.swi_num = 8619e39c5baSBill Taylor (uint64_t)1 << cfgprof->cp_log_num_srq; 8629e39c5baSBill Taylor hdl_info.swi_max = (uint64_t)1 << devlim->log_max_srq; 8639e39c5baSBill Taylor hdl_info.swi_constructor = 8649e39c5baSBill Taylor hermon_rsrc_srqhdl_constructor; 8659e39c5baSBill Taylor hdl_info.swi_destructor = hermon_rsrc_srqhdl_destructor; 8669e39c5baSBill Taylor hdl_info.swi_flags = (HERMON_SWHDL_KMEMCACHE_INIT | 8679e39c5baSBill Taylor HERMON_SWHDL_TABLE_INIT); 8689e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (hermon_srqhdl_t); 8699e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL25; 8709e39c5baSBill Taylor break; 8719e39c5baSBill Taylor 8729e39c5baSBill Taylor case HERMON_AHHDL: 8739e39c5baSBill Taylor rsrc_pool->rsrc_type = HERMON_AHHDL; 8749e39c5baSBill Taylor rsrc_pool->rsrc_quantum = 8759e39c5baSBill Taylor sizeof (struct hermon_sw_ah_s); 8769e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_AHHDL_CACHE); 8779e39c5baSBill Taylor hdl_info.swi_num = 8789e39c5baSBill Taylor (uint64_t)1 << cfgprof->cp_log_num_ah; 8799e39c5baSBill Taylor hdl_info.swi_max = HERMON_NUM_AH; 8809e39c5baSBill Taylor hdl_info.swi_constructor = 8819e39c5baSBill Taylor hermon_rsrc_ahhdl_constructor; 8829e39c5baSBill Taylor hdl_info.swi_destructor = hermon_rsrc_ahhdl_destructor; 8839e39c5baSBill Taylor hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT; 8849e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL26; 8859e39c5baSBill Taylor break; 8869e39c5baSBill Taylor 8879e39c5baSBill Taylor case HERMON_QPHDL: 8889e39c5baSBill Taylor rsrc_pool->rsrc_type = HERMON_QPHDL; 8899e39c5baSBill Taylor rsrc_pool->rsrc_quantum = 8909e39c5baSBill Taylor sizeof (struct hermon_sw_qp_s); 8919e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_QPHDL_CACHE); 8929e39c5baSBill Taylor hdl_info.swi_num = 8939e39c5baSBill Taylor (uint64_t)1 << cfgprof->cp_log_num_qp; 8949e39c5baSBill Taylor hdl_info.swi_max = (uint64_t)1 << devlim->log_max_qp; 8959e39c5baSBill Taylor hdl_info.swi_constructor = 8969e39c5baSBill Taylor hermon_rsrc_qphdl_constructor; 8979e39c5baSBill Taylor hdl_info.swi_destructor = hermon_rsrc_qphdl_destructor; 8989e39c5baSBill Taylor hdl_info.swi_flags = (HERMON_SWHDL_KMEMCACHE_INIT | 8999e39c5baSBill Taylor HERMON_SWHDL_TABLE_INIT); 9009e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (hermon_qphdl_t); 9019e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL27; 9029e39c5baSBill Taylor break; 9039e39c5baSBill Taylor 9049e39c5baSBill Taylor case HERMON_REFCNT: 9059e39c5baSBill Taylor rsrc_pool->rsrc_type = HERMON_REFCNT; 9069e39c5baSBill Taylor rsrc_pool->rsrc_quantum = sizeof (hermon_sw_refcnt_t); 9079e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_REFCNT_CACHE); 9089e39c5baSBill Taylor hdl_info.swi_num = 9099e39c5baSBill Taylor (uint64_t)1 << cfgprof->cp_log_num_dmpt; 9109e39c5baSBill Taylor hdl_info.swi_max = (uint64_t)1 << devlim->log_max_dmpt; 9119e39c5baSBill Taylor hdl_info.swi_constructor = 9129e39c5baSBill Taylor hermon_rsrc_refcnt_constructor; 9139e39c5baSBill Taylor hdl_info.swi_destructor = hermon_rsrc_refcnt_destructor; 9149e39c5baSBill Taylor hdl_info.swi_flags = HERMON_SWHDL_KMEMCACHE_INIT; 9159e39c5baSBill Taylor ncleanup = HERMON_RSRC_CLEANUP_LEVEL28; 9169e39c5baSBill Taylor break; 9179e39c5baSBill Taylor 9189e39c5baSBill Taylor default: 9199e39c5baSBill Taylor continue; 9209e39c5baSBill Taylor } 9219e39c5baSBill Taylor 9229e39c5baSBill Taylor /* Set the common values and call the init routine */ 9239e39c5baSBill Taylor rsrc_pool->rsrc_loc = HERMON_IN_SYSMEM; 9249e39c5baSBill Taylor rsrc_pool->rsrc_state = state; 9259e39c5baSBill Taylor hdl_info.swi_rsrcpool = rsrc_pool; 9269e39c5baSBill Taylor hdl_info.swi_rsrcname = rsrc_name; 9279e39c5baSBill Taylor status = hermon_rsrc_sw_handles_init(state, &hdl_info); 9289e39c5baSBill Taylor if (status != DDI_SUCCESS) { 9299e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup); 9309e39c5baSBill Taylor status = DDI_FAILURE; 9319e39c5baSBill Taylor goto rsrcinitp2_fail; 9329e39c5baSBill Taylor } 9339e39c5baSBill Taylor cleanup = ncleanup; 9349e39c5baSBill Taylor 9359e39c5baSBill Taylor /* 9369e39c5baSBill Taylor * For table entries, save away a pointer to the central list 9379e39c5baSBill Taylor * of handle pointers. These are used to enable fast lookup 9389e39c5baSBill Taylor * of the resources during event processing. 9399e39c5baSBill Taylor */ 9409e39c5baSBill Taylor switch (i) { 9419e39c5baSBill Taylor case HERMON_CQHDL: 9429e39c5baSBill Taylor state->hs_cqhdl = hdl_info.swi_table_ptr; 9439e39c5baSBill Taylor break; 9449e39c5baSBill Taylor case HERMON_QPHDL: 9459e39c5baSBill Taylor state->hs_qphdl = hdl_info.swi_table_ptr; 9469e39c5baSBill Taylor break; 9479e39c5baSBill Taylor case HERMON_SRQHDL: 9489e39c5baSBill Taylor state->hs_srqhdl = hdl_info.swi_table_ptr; 9499e39c5baSBill Taylor break; 9509e39c5baSBill Taylor default: 9519e39c5baSBill Taylor break; 9529e39c5baSBill Taylor } 9539e39c5baSBill Taylor } 9549e39c5baSBill Taylor 9559e39c5baSBill Taylor /* 9569e39c5baSBill Taylor * Initialize a resource pool for the MCG handles. Notice that for 9579e39c5baSBill Taylor * these MCG handles, we are allocating a table of structures (used to 9589e39c5baSBill Taylor * keep track of the MCG entries that are being written to hardware 9599e39c5baSBill Taylor * and to speed up multicast attach/detach operations). 9609e39c5baSBill Taylor */ 9619e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_mcg); 9629e39c5baSBill Taylor hdl_info.swi_max = ((uint64_t)1 << devlim->log_max_mcg); 9639e39c5baSBill Taylor hdl_info.swi_flags = HERMON_SWHDL_TABLE_INIT; 9649e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (struct hermon_sw_mcg_list_s); 9659e39c5baSBill Taylor status = hermon_rsrc_sw_handles_init(state, &hdl_info); 9669e39c5baSBill Taylor if (status != DDI_SUCCESS) { 9679e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup); 9689e39c5baSBill Taylor status = DDI_FAILURE; 9699e39c5baSBill Taylor goto rsrcinitp2_fail; 9709e39c5baSBill Taylor } 9719e39c5baSBill Taylor state->hs_mcghdl = hdl_info.swi_table_ptr; 9729e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_LEVEL29; 9739e39c5baSBill Taylor 9749e39c5baSBill Taylor /* 9759e39c5baSBill Taylor * Last, initialize the resource pool for the UAR pages, which contain 9769e39c5baSBill Taylor * the hardware's doorbell registers. Each process supported in User 9779e39c5baSBill Taylor * Mode is assigned a UAR page. Also coming from this pool are the 9789e39c5baSBill Taylor * kernel-assigned UAR page, and any hardware-reserved pages. Note 9799e39c5baSBill Taylor * that the number of UAR pages is configurable, the value must be less 9809e39c5baSBill Taylor * than the maximum value (obtained from the QUERY_DEV_LIM command) or 9819e39c5baSBill Taylor * the initialization will fail. Note also that we assign the base 9829e39c5baSBill Taylor * address of the UAR BAR to the rsrc_start parameter. 9839e39c5baSBill Taylor */ 9849e39c5baSBill Taylor num = ((uint64_t)1 << cfgprof->cp_log_num_uar); 9859e39c5baSBill Taylor max = num; 9869e39c5baSBill Taylor num_prealloc = max(devlim->num_rsvd_uar, 128); 9879e39c5baSBill Taylor rsrc_pool = &state->hs_rsrc_hdl[HERMON_UARPG]; 9889e39c5baSBill Taylor rsrc_pool->rsrc_type = HERMON_UARPG; 9899e39c5baSBill Taylor rsrc_pool->rsrc_loc = HERMON_IN_UAR; 9909e39c5baSBill Taylor rsrc_pool->rsrc_pool_size = (num << PAGESHIFT); 9919e39c5baSBill Taylor rsrc_pool->rsrc_shift = PAGESHIFT; 9929e39c5baSBill Taylor rsrc_pool->rsrc_quantum = (uint_t)PAGESIZE; 9939e39c5baSBill Taylor rsrc_pool->rsrc_align = PAGESIZE; 9949e39c5baSBill Taylor rsrc_pool->rsrc_state = state; 9959e39c5baSBill Taylor rsrc_pool->rsrc_start = (void *)state->hs_reg_uar_baseaddr; 9969e39c5baSBill Taylor HERMON_RSRC_NAME(rsrc_name, HERMON_UAR_PAGE_VMEM_ATTCH); 9979e39c5baSBill Taylor entry_info.hwi_num = num; 9989e39c5baSBill Taylor entry_info.hwi_max = max; 9999e39c5baSBill Taylor entry_info.hwi_prealloc = num_prealloc; 10009e39c5baSBill Taylor entry_info.hwi_rsrcpool = rsrc_pool; 10019e39c5baSBill Taylor entry_info.hwi_rsrcname = rsrc_name; 10029e39c5baSBill Taylor status = hermon_rsrc_hw_entries_init(state, &entry_info); 10039e39c5baSBill Taylor if (status != DDI_SUCCESS) { 10049e39c5baSBill Taylor hermon_rsrc_fini(state, cleanup); 10059e39c5baSBill Taylor status = DDI_FAILURE; 10069e39c5baSBill Taylor goto rsrcinitp2_fail; 10079e39c5baSBill Taylor } 10089e39c5baSBill Taylor 10099e39c5baSBill Taylor cleanup = HERMON_RSRC_CLEANUP_ALL; 10109e39c5baSBill Taylor 10119e39c5baSBill Taylor kmem_free(rsrc_name, HERMON_RSRC_NAME_MAXLEN); 10129e39c5baSBill Taylor return (DDI_SUCCESS); 10139e39c5baSBill Taylor 10149e39c5baSBill Taylor rsrcinitp2_fail: 10159e39c5baSBill Taylor kmem_free(rsrc_name, HERMON_RSRC_NAME_MAXLEN); 10169e39c5baSBill Taylor return (status); 10179e39c5baSBill Taylor } 10189e39c5baSBill Taylor 10199e39c5baSBill Taylor 10209e39c5baSBill Taylor /* 10219e39c5baSBill Taylor * hermon_rsrc_fini() 10229e39c5baSBill Taylor * Context: Only called from attach() and/or detach() path contexts 10239e39c5baSBill Taylor */ 10249e39c5baSBill Taylor void 10259e39c5baSBill Taylor hermon_rsrc_fini(hermon_state_t *state, hermon_rsrc_cleanup_level_t clean) 10269e39c5baSBill Taylor { 10279e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t hdl_info; 10289e39c5baSBill Taylor hermon_rsrc_hw_entry_info_t entry_info; 10299e39c5baSBill Taylor hermon_rsrc_mbox_info_t mbox_info; 10309e39c5baSBill Taylor hermon_cfg_profile_t *cfgprof; 10319e39c5baSBill Taylor 10329e39c5baSBill Taylor ASSERT(state != NULL); 10339e39c5baSBill Taylor 10349e39c5baSBill Taylor cfgprof = state->hs_cfg_profile; 10359e39c5baSBill Taylor 10369e39c5baSBill Taylor /* 10379e39c5baSBill Taylor * If init code above is shortened up (see comments), then we 10389e39c5baSBill Taylor * need to establish how to safely and simply clean up from any 10399e39c5baSBill Taylor * given failure point. Flags, maybe... 10409e39c5baSBill Taylor */ 10419e39c5baSBill Taylor 10429e39c5baSBill Taylor switch (clean) { 10439e39c5baSBill Taylor /* 10449e39c5baSBill Taylor * If we add more resources that need to be cleaned up here, we should 10459e39c5baSBill Taylor * ensure that HERMON_RSRC_CLEANUP_ALL is still the first entry (i.e. 10469e39c5baSBill Taylor * corresponds to the last resource allocated). 10479e39c5baSBill Taylor */ 10489e39c5baSBill Taylor 10499e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_ALL: 10509e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL31: 10519e39c5baSBill Taylor /* Cleanup the UAR page resource pool, first the dbr pages */ 10529e39c5baSBill Taylor if (state->hs_kern_dbr) { 10539e39c5baSBill Taylor hermon_dbr_kern_free(state); 10549e39c5baSBill Taylor state->hs_kern_dbr = NULL; 10559e39c5baSBill Taylor } 10569e39c5baSBill Taylor 10579e39c5baSBill Taylor /* NS then, the pool itself */ 10589e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_UARPG]; 10599e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info); 10609e39c5baSBill Taylor 10619e39c5baSBill Taylor /* FALLTHROUGH */ 10629e39c5baSBill Taylor 10639e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL30: 10649e39c5baSBill Taylor /* Cleanup the central MCG handle pointers list */ 10659e39c5baSBill Taylor hdl_info.swi_rsrcpool = NULL; 10669e39c5baSBill Taylor hdl_info.swi_table_ptr = state->hs_mcghdl; 10679e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_mcg); 10689e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (struct hermon_sw_mcg_list_s); 10699e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, &hdl_info); 10709e39c5baSBill Taylor /* FALLTHROUGH */ 10719e39c5baSBill Taylor 10729e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL29: 10739e39c5baSBill Taylor /* Cleanup the reference count resource pool */ 10749e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_REFCNT]; 10759e39c5baSBill Taylor hdl_info.swi_table_ptr = NULL; 10769e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, &hdl_info); 10779e39c5baSBill Taylor /* FALLTHROUGH */ 10789e39c5baSBill Taylor 10799e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL28: 10809e39c5baSBill Taylor /* Cleanup the QP handle resource pool */ 10819e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_QPHDL]; 10829e39c5baSBill Taylor hdl_info.swi_table_ptr = state->hs_qphdl; 10839e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_qp); 10849e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (hermon_qphdl_t); 10859e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, &hdl_info); 10869e39c5baSBill Taylor /* FALLTHROUGH */ 10879e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL27: 10889e39c5baSBill Taylor /* Cleanup the address handle resrouce pool */ 10899e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_AHHDL]; 10909e39c5baSBill Taylor hdl_info.swi_table_ptr = NULL; 10919e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, &hdl_info); 10929e39c5baSBill Taylor /* FALLTHROUGH */ 10939e39c5baSBill Taylor 10949e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL26: 10959e39c5baSBill Taylor /* Cleanup the SRQ handle resource pool. */ 10969e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_SRQHDL]; 10979e39c5baSBill Taylor hdl_info.swi_table_ptr = state->hs_srqhdl; 10989e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_srq); 10999e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (hermon_srqhdl_t); 11009e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, &hdl_info); 11019e39c5baSBill Taylor /* FALLTHROUGH */ 11029e39c5baSBill Taylor 11039e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL25: 11049e39c5baSBill Taylor /* Cleanup the CQ handle resource pool */ 11059e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_CQHDL]; 11069e39c5baSBill Taylor hdl_info.swi_table_ptr = state->hs_cqhdl; 11079e39c5baSBill Taylor hdl_info.swi_num = ((uint64_t)1 << cfgprof->cp_log_num_cq); 11089e39c5baSBill Taylor hdl_info.swi_prealloc_sz = sizeof (hermon_cqhdl_t); 11099e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, &hdl_info); 11109e39c5baSBill Taylor /* FALLTHROUGH */ 11119e39c5baSBill Taylor 11129e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL24: 11139e39c5baSBill Taylor /* Cleanup the EQ handle resource pool */ 11149e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_EQHDL]; 11159e39c5baSBill Taylor hdl_info.swi_table_ptr = NULL; 11169e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, &hdl_info); 11179e39c5baSBill Taylor /* FALLTHROUGH */ 11189e39c5baSBill Taylor 11199e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL23: 11209e39c5baSBill Taylor /* Cleanup the MR handle resource pool */ 11219e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_MRHDL]; 11229e39c5baSBill Taylor hdl_info.swi_table_ptr = NULL; 11239e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, &hdl_info); 11249e39c5baSBill Taylor /* FALLTHROUGH */ 11259e39c5baSBill Taylor 11269e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL22: 11279e39c5baSBill Taylor /* Cleanup the PD handle resource pool */ 11289e39c5baSBill Taylor hdl_info.swi_rsrcpool = &state->hs_rsrc_hdl[HERMON_PDHDL]; 11299e39c5baSBill Taylor hdl_info.swi_table_ptr = NULL; 11309e39c5baSBill Taylor hermon_rsrc_pd_handles_fini(state, &hdl_info); 11319e39c5baSBill Taylor /* FALLTHROUGH */ 11329e39c5baSBill Taylor 11339e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL21: 11349e39c5baSBill Taylor /* Currently unused - FALLTHROUGH */ 11359e39c5baSBill Taylor 11369e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL20: 11379e39c5baSBill Taylor /* Cleanup the outstanding command list */ 11389e39c5baSBill Taylor hermon_outstanding_cmdlist_fini(state); 11399e39c5baSBill Taylor /* FALLTHROUGH */ 11409e39c5baSBill Taylor 11419e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL19: 11429e39c5baSBill Taylor /* Cleanup the EQC table resource pool */ 11439e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_EQC]; 11449e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info); 11459e39c5baSBill Taylor /* FALLTHROUGH */ 11469e39c5baSBill Taylor 11479e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL18: 11489e39c5baSBill Taylor /* Cleanup the MCG table resource pool */ 11499e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_MCG]; 11509e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info); 11519e39c5baSBill Taylor /* FALLTHROUGH */ 11529e39c5baSBill Taylor 11539e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL17: 11549e39c5baSBill Taylor /* Currently Unused - fallthrough */ 11559e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL16: 11569e39c5baSBill Taylor /* Cleanup the SRQC table resource pool */ 11579e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_SRQC]; 11589e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info); 11599e39c5baSBill Taylor /* FALLTHROUGH */ 11609e39c5baSBill Taylor 11619e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL15: 11629e39c5baSBill Taylor /* Cleanup the AUXC table resource pool */ 11639e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_AUXC]; 11649e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info); 11659e39c5baSBill Taylor /* FALLTHROUGH */ 11669e39c5baSBill Taylor 11679e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL14: 11689e39c5baSBill Taylor /* Cleanup the ALTCF table resource pool */ 11699e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_ALTC]; 11709e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info); 11719e39c5baSBill Taylor /* FALLTHROUGH */ 11729e39c5baSBill Taylor 11739e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL13: 11749e39c5baSBill Taylor /* Cleanup the CQC table resource pool */ 11759e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_CQC]; 11769e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info); 11779e39c5baSBill Taylor /* FALLTHROUGH */ 11789e39c5baSBill Taylor 11799e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL12: 11809e39c5baSBill Taylor /* Cleanup the RDB table resource pool */ 11819e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_RDB]; 11829e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info); 11839e39c5baSBill Taylor /* FALLTHROUGH */ 11849e39c5baSBill Taylor 11859e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL11: 11869e39c5baSBill Taylor /* Cleanup the QPC table resource pool */ 11879e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_QPC]; 11889e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info); 11899e39c5baSBill Taylor /* FALLTHROUGH */ 11909e39c5baSBill Taylor 11919e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL10EQ: 11929e39c5baSBill Taylor /* Cleanup the cMPTs for the EQs, CQs, SRQs, and QPs */ 11939e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_CMPT_EQC]; 11949e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info); 11959e39c5baSBill Taylor /* FALLTHROUGH */ 11969e39c5baSBill Taylor 11979e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL10CQ: 11989e39c5baSBill Taylor /* Cleanup the cMPTs for the EQs, CQs, SRQs, and QPs */ 11999e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_CMPT_CQC]; 12009e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info); 12019e39c5baSBill Taylor /* FALLTHROUGH */ 12029e39c5baSBill Taylor 12039e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL10SRQ: 12049e39c5baSBill Taylor /* Cleanup the cMPTs for the EQs, CQs, SRQs, and QPs */ 12059e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_CMPT_SRQC]; 12069e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info); 12079e39c5baSBill Taylor /* FALLTHROUGH */ 12089e39c5baSBill Taylor 12099e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL10QP: 12109e39c5baSBill Taylor /* Cleanup the cMPTs for the EQs, CQs, SRQs, and QPs */ 12119e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_CMPT_QPC]; 12129e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info); 12139e39c5baSBill Taylor /* FALLTHROUGH */ 12149e39c5baSBill Taylor 12159e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL10: 12169e39c5baSBill Taylor /* Cleanup the dMPT table resource pool */ 12179e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_DMPT]; 12189e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info); 12199e39c5baSBill Taylor /* FALLTHROUGH */ 12209e39c5baSBill Taylor 12219e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL9: 12229e39c5baSBill Taylor /* Cleanup the MTT table resource pool */ 12239e39c5baSBill Taylor entry_info.hwi_rsrcpool = &state->hs_rsrc_hdl[HERMON_MTT]; 12249e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(state, &entry_info); 12259e39c5baSBill Taylor break; 12269e39c5baSBill Taylor 12279e39c5baSBill Taylor /* 12289e39c5baSBill Taylor * The cleanup below comes from the "Phase 1" initialization step. 12299e39c5baSBill Taylor * (see hermon_rsrc_init_phase1() above) 12309e39c5baSBill Taylor */ 12319e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_PHASE1_COMPLETE: 12329e39c5baSBill Taylor /* Cleanup the "In" mailbox list */ 12339e39c5baSBill Taylor hermon_intr_inmbox_list_fini(state); 12349e39c5baSBill Taylor /* FALLTHROUGH */ 12359e39c5baSBill Taylor 12369e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL7: 12379e39c5baSBill Taylor /* Cleanup the interrupt "In" mailbox resource pool */ 12389e39c5baSBill Taylor mbox_info.mbi_rsrcpool = 12399e39c5baSBill Taylor &state->hs_rsrc_hdl[HERMON_INTR_IN_MBOX]; 12409e39c5baSBill Taylor hermon_rsrc_mbox_fini(state, &mbox_info); 12419e39c5baSBill Taylor /* FALLTHROUGH */ 12429e39c5baSBill Taylor 12439e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL6: 12449e39c5baSBill Taylor /* Cleanup the "In" mailbox list */ 12459e39c5baSBill Taylor hermon_inmbox_list_fini(state); 12469e39c5baSBill Taylor /* FALLTHROUGH */ 12479e39c5baSBill Taylor 12489e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL5: 12499e39c5baSBill Taylor /* Cleanup the "In" mailbox resource pool */ 12509e39c5baSBill Taylor mbox_info.mbi_rsrcpool = &state->hs_rsrc_hdl[HERMON_IN_MBOX]; 12519e39c5baSBill Taylor hermon_rsrc_mbox_fini(state, &mbox_info); 12529e39c5baSBill Taylor /* FALLTHROUGH */ 12539e39c5baSBill Taylor 12549e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL4: 12559e39c5baSBill Taylor /* Cleanup the interrupt "Out" mailbox list */ 12569e39c5baSBill Taylor hermon_intr_outmbox_list_fini(state); 12579e39c5baSBill Taylor /* FALLTHROUGH */ 12589e39c5baSBill Taylor 12599e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL3: 12609e39c5baSBill Taylor /* Cleanup the "Out" mailbox resource pool */ 12619e39c5baSBill Taylor mbox_info.mbi_rsrcpool = 12629e39c5baSBill Taylor &state->hs_rsrc_hdl[HERMON_INTR_OUT_MBOX]; 12639e39c5baSBill Taylor hermon_rsrc_mbox_fini(state, &mbox_info); 12649e39c5baSBill Taylor /* FALLTHROUGH */ 12659e39c5baSBill Taylor 12669e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL2: 12679e39c5baSBill Taylor /* Cleanup the "Out" mailbox list */ 12689e39c5baSBill Taylor hermon_outmbox_list_fini(state); 12699e39c5baSBill Taylor /* FALLTHROUGH */ 12709e39c5baSBill Taylor 12719e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL1: 12729e39c5baSBill Taylor /* Cleanup the "Out" mailbox resource pool */ 12739e39c5baSBill Taylor mbox_info.mbi_rsrcpool = &state->hs_rsrc_hdl[HERMON_OUT_MBOX]; 12749e39c5baSBill Taylor hermon_rsrc_mbox_fini(state, &mbox_info); 12759e39c5baSBill Taylor /* FALLTHROUGH */ 12769e39c5baSBill Taylor 12779e39c5baSBill Taylor case HERMON_RSRC_CLEANUP_LEVEL0: 12789e39c5baSBill Taylor /* Free the array of hermon_rsrc_pool_info_t's */ 12799e39c5baSBill Taylor 12809e39c5baSBill Taylor kmem_free(state->hs_rsrc_hdl, HERMON_NUM_RESOURCES * 12819e39c5baSBill Taylor sizeof (hermon_rsrc_pool_info_t)); 12829e39c5baSBill Taylor 12839e39c5baSBill Taylor kmem_cache_destroy(state->hs_rsrc_cache); 12849e39c5baSBill Taylor break; 12859e39c5baSBill Taylor 12869e39c5baSBill Taylor default: 12879e39c5baSBill Taylor HERMON_WARNING(state, "unexpected resource cleanup level"); 12889e39c5baSBill Taylor break; 12899e39c5baSBill Taylor } 12909e39c5baSBill Taylor } 12919e39c5baSBill Taylor 12929e39c5baSBill Taylor 12939e39c5baSBill Taylor /* 12949e39c5baSBill Taylor * hermon_rsrc_mbox_init() 12959e39c5baSBill Taylor * Context: Only called from attach() path context 12969e39c5baSBill Taylor */ 12979e39c5baSBill Taylor static int 12989e39c5baSBill Taylor hermon_rsrc_mbox_init(hermon_state_t *state, hermon_rsrc_mbox_info_t *info) 12999e39c5baSBill Taylor { 13009e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool; 13019e39c5baSBill Taylor hermon_rsrc_priv_mbox_t *priv; 13029e39c5baSBill Taylor 13039e39c5baSBill Taylor ASSERT(state != NULL); 13049e39c5baSBill Taylor ASSERT(info != NULL); 13059e39c5baSBill Taylor 13069e39c5baSBill Taylor rsrc_pool = info->mbi_rsrcpool; 13079e39c5baSBill Taylor ASSERT(rsrc_pool != NULL); 13089e39c5baSBill Taylor 13099e39c5baSBill Taylor /* Allocate and initialize mailbox private structure */ 13109e39c5baSBill Taylor priv = kmem_zalloc(sizeof (hermon_rsrc_priv_mbox_t), KM_SLEEP); 13119e39c5baSBill Taylor priv->pmb_dip = state->hs_dip; 13129e39c5baSBill Taylor priv->pmb_devaccattr = state->hs_reg_accattr; 13139e39c5baSBill Taylor priv->pmb_xfer_mode = DDI_DMA_CONSISTENT; 13149e39c5baSBill Taylor 13159e39c5baSBill Taylor /* 13169e39c5baSBill Taylor * Initialize many of the default DMA attributes. Then set alignment 13179e39c5baSBill Taylor * and scatter-gather restrictions specific for mailbox memory. 13189e39c5baSBill Taylor */ 13199e39c5baSBill Taylor hermon_dma_attr_init(state, &priv->pmb_dmaattr); 13209e39c5baSBill Taylor priv->pmb_dmaattr.dma_attr_align = HERMON_MBOX_ALIGN; 13219e39c5baSBill Taylor priv->pmb_dmaattr.dma_attr_sgllen = 1; 13229e39c5baSBill Taylor priv->pmb_dmaattr.dma_attr_flags = 0; 13239e39c5baSBill Taylor rsrc_pool->rsrc_private = priv; 13249e39c5baSBill Taylor 13259e39c5baSBill Taylor ASSERT(rsrc_pool->rsrc_loc == HERMON_IN_SYSMEM); 13269e39c5baSBill Taylor 13279e39c5baSBill Taylor rsrc_pool->rsrc_start = NULL; 13289e39c5baSBill Taylor rsrc_pool->rsrc_vmp = NULL; 13299e39c5baSBill Taylor 13309e39c5baSBill Taylor return (DDI_SUCCESS); 13319e39c5baSBill Taylor } 13329e39c5baSBill Taylor 13339e39c5baSBill Taylor 13349e39c5baSBill Taylor /* 13359e39c5baSBill Taylor * hermon_rsrc_mbox_fini() 13369e39c5baSBill Taylor * Context: Only called from attach() and/or detach() path contexts 13379e39c5baSBill Taylor */ 13389e39c5baSBill Taylor /* ARGSUSED */ 13399e39c5baSBill Taylor static void 13409e39c5baSBill Taylor hermon_rsrc_mbox_fini(hermon_state_t *state, hermon_rsrc_mbox_info_t *info) 13419e39c5baSBill Taylor { 13429e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool; 13439e39c5baSBill Taylor 13449e39c5baSBill Taylor ASSERT(state != NULL); 13459e39c5baSBill Taylor ASSERT(info != NULL); 13469e39c5baSBill Taylor 13479e39c5baSBill Taylor rsrc_pool = info->mbi_rsrcpool; 13489e39c5baSBill Taylor ASSERT(rsrc_pool != NULL); 13499e39c5baSBill Taylor 13509e39c5baSBill Taylor /* Free up the private struct */ 13519e39c5baSBill Taylor kmem_free(rsrc_pool->rsrc_private, sizeof (hermon_rsrc_priv_mbox_t)); 13529e39c5baSBill Taylor } 13539e39c5baSBill Taylor 13549e39c5baSBill Taylor 13559e39c5baSBill Taylor /* 13569e39c5baSBill Taylor * hermon_rsrc_hw_entries_init() 13579e39c5baSBill Taylor * Context: Only called from attach() path context 13589e39c5baSBill Taylor */ 13599e39c5baSBill Taylor int 13609e39c5baSBill Taylor hermon_rsrc_hw_entries_init(hermon_state_t *state, 13619e39c5baSBill Taylor hermon_rsrc_hw_entry_info_t *info) 13629e39c5baSBill Taylor { 13639e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool; 13649e39c5baSBill Taylor hermon_rsrc_t *rsvd_rsrc = NULL; 13659e39c5baSBill Taylor vmem_t *vmp; 13669e39c5baSBill Taylor uint64_t num_hwentry, max_hwentry, num_prealloc; 13679e39c5baSBill Taylor int status; 13689e39c5baSBill Taylor 13699e39c5baSBill Taylor ASSERT(state != NULL); 13709e39c5baSBill Taylor ASSERT(info != NULL); 13719e39c5baSBill Taylor 13729e39c5baSBill Taylor rsrc_pool = info->hwi_rsrcpool; 13739e39c5baSBill Taylor ASSERT(rsrc_pool != NULL); 13749e39c5baSBill Taylor num_hwentry = info->hwi_num; 13759e39c5baSBill Taylor max_hwentry = info->hwi_max; 13769e39c5baSBill Taylor num_prealloc = info->hwi_prealloc; 13779e39c5baSBill Taylor 13789e39c5baSBill Taylor if (hermon_rsrc_verbose) { 13799e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entries_init: " 13809e39c5baSBill Taylor "rsrc_type (0x%x) num (%llx) max (0x%llx) prealloc " 13819e39c5baSBill Taylor "(0x%llx)", rsrc_pool->rsrc_type, (longlong_t)num_hwentry, 13829e39c5baSBill Taylor (longlong_t)max_hwentry, (longlong_t)num_prealloc); 13839e39c5baSBill Taylor } 13849e39c5baSBill Taylor 13859e39c5baSBill Taylor /* Make sure number of HW entries makes sense */ 13869e39c5baSBill Taylor if (num_hwentry > max_hwentry) { 13879e39c5baSBill Taylor return (DDI_FAILURE); 13889e39c5baSBill Taylor } 13899e39c5baSBill Taylor 13909e39c5baSBill Taylor /* Set this pool's rsrc_start from the initial ICM allocation */ 13919e39c5baSBill Taylor if (rsrc_pool->rsrc_start == 0) { 1392*c7facc54SBill Taylor 1393*c7facc54SBill Taylor /* use a ROUND value that works on both 32 and 64-bit kernels */ 1394*c7facc54SBill Taylor rsrc_pool->rsrc_start = (void *)(uintptr_t)0x10000000; 13959e39c5baSBill Taylor 13969e39c5baSBill Taylor if (hermon_rsrc_verbose) { 13979e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entries_init:" 13989e39c5baSBill Taylor " rsrc_type (0x%x) rsrc_start set (0x%lx)", 13999e39c5baSBill Taylor rsrc_pool->rsrc_type, rsrc_pool->rsrc_start); 14009e39c5baSBill Taylor } 14019e39c5baSBill Taylor } 14029e39c5baSBill Taylor 14039e39c5baSBill Taylor /* 14049e39c5baSBill Taylor * Create new vmem arena for the HW entries table if rsrc_quantum 14059e39c5baSBill Taylor * is non-zero. Otherwise if rsrc_quantum is zero, then these HW 14069e39c5baSBill Taylor * entries are not going to be dynamically allocatable (i.e. they 14079e39c5baSBill Taylor * won't be allocated/freed through hermon_rsrc_alloc/free). This 14089e39c5baSBill Taylor * latter option is used for both ALTC and CMPT resources which 14099e39c5baSBill Taylor * are managed by hardware. 14109e39c5baSBill Taylor */ 14119e39c5baSBill Taylor if (rsrc_pool->rsrc_quantum != 0) { 14129e39c5baSBill Taylor vmp = vmem_create(info->hwi_rsrcname, 14139e39c5baSBill Taylor (void *)(uintptr_t)rsrc_pool->rsrc_start, 14149e39c5baSBill Taylor rsrc_pool->rsrc_pool_size, rsrc_pool->rsrc_quantum, 14159e39c5baSBill Taylor NULL, NULL, NULL, 0, VM_SLEEP); 14169e39c5baSBill Taylor if (vmp == NULL) { 14179e39c5baSBill Taylor /* failed to create vmem arena */ 14189e39c5baSBill Taylor return (DDI_FAILURE); 14199e39c5baSBill Taylor } 14209e39c5baSBill Taylor rsrc_pool->rsrc_vmp = vmp; 14219e39c5baSBill Taylor if (hermon_rsrc_verbose) { 14229e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entries_init:" 14239e39c5baSBill Taylor " rsrc_type (0x%x) created vmem arena for rsrc", 14249e39c5baSBill Taylor rsrc_pool->rsrc_type); 14259e39c5baSBill Taylor } 14269e39c5baSBill Taylor } else { 14279e39c5baSBill Taylor /* we do not require a vmem arena */ 14289e39c5baSBill Taylor rsrc_pool->rsrc_vmp = NULL; 14299e39c5baSBill Taylor if (hermon_rsrc_verbose) { 14309e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entries_init:" 14319e39c5baSBill Taylor " rsrc_type (0x%x) vmem arena not required", 14329e39c5baSBill Taylor rsrc_pool->rsrc_type); 14339e39c5baSBill Taylor } 14349e39c5baSBill Taylor } 14359e39c5baSBill Taylor 14369e39c5baSBill Taylor /* Allocate hardware reserved resources, if any */ 14379e39c5baSBill Taylor if (num_prealloc != 0) { 14389e39c5baSBill Taylor status = hermon_rsrc_alloc(state, rsrc_pool->rsrc_type, 14399e39c5baSBill Taylor num_prealloc, HERMON_SLEEP, &rsvd_rsrc); 14409e39c5baSBill Taylor if (status != DDI_SUCCESS) { 14419e39c5baSBill Taylor /* unable to preallocate the reserved entries */ 14429e39c5baSBill Taylor if (rsrc_pool->rsrc_vmp != NULL) { 14439e39c5baSBill Taylor vmem_destroy(rsrc_pool->rsrc_vmp); 14449e39c5baSBill Taylor } 14459e39c5baSBill Taylor return (DDI_FAILURE); 14469e39c5baSBill Taylor } 14479e39c5baSBill Taylor } 14489e39c5baSBill Taylor rsrc_pool->rsrc_private = rsvd_rsrc; 14499e39c5baSBill Taylor 14509e39c5baSBill Taylor return (DDI_SUCCESS); 14519e39c5baSBill Taylor } 14529e39c5baSBill Taylor 14539e39c5baSBill Taylor 14549e39c5baSBill Taylor /* 14559e39c5baSBill Taylor * hermon_rsrc_hw_entries_fini() 14569e39c5baSBill Taylor * Context: Only called from attach() and/or detach() path contexts 14579e39c5baSBill Taylor */ 14589e39c5baSBill Taylor void 14599e39c5baSBill Taylor hermon_rsrc_hw_entries_fini(hermon_state_t *state, 14609e39c5baSBill Taylor hermon_rsrc_hw_entry_info_t *info) 14619e39c5baSBill Taylor { 14629e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool; 14639e39c5baSBill Taylor hermon_rsrc_t *rsvd_rsrc; 14649e39c5baSBill Taylor 14659e39c5baSBill Taylor ASSERT(state != NULL); 14669e39c5baSBill Taylor ASSERT(info != NULL); 14679e39c5baSBill Taylor 14689e39c5baSBill Taylor rsrc_pool = info->hwi_rsrcpool; 14699e39c5baSBill Taylor ASSERT(rsrc_pool != NULL); 14709e39c5baSBill Taylor 14719e39c5baSBill Taylor /* Free up any "reserved" (i.e. preallocated) HW entries */ 14729e39c5baSBill Taylor rsvd_rsrc = (hermon_rsrc_t *)rsrc_pool->rsrc_private; 14739e39c5baSBill Taylor if (rsvd_rsrc != NULL) { 14749e39c5baSBill Taylor hermon_rsrc_free(state, &rsvd_rsrc); 14759e39c5baSBill Taylor } 14769e39c5baSBill Taylor 14779e39c5baSBill Taylor /* 14789e39c5baSBill Taylor * If we've actually setup a vmem arena for the HW entries, then 14799e39c5baSBill Taylor * destroy it now 14809e39c5baSBill Taylor */ 14819e39c5baSBill Taylor if (rsrc_pool->rsrc_vmp != NULL) { 14829e39c5baSBill Taylor vmem_destroy(rsrc_pool->rsrc_vmp); 14839e39c5baSBill Taylor } 14849e39c5baSBill Taylor } 14859e39c5baSBill Taylor 14869e39c5baSBill Taylor 14879e39c5baSBill Taylor /* 14889e39c5baSBill Taylor * hermon_rsrc_sw_handles_init() 14899e39c5baSBill Taylor * Context: Only called from attach() path context 14909e39c5baSBill Taylor */ 14919e39c5baSBill Taylor /* ARGSUSED */ 14929e39c5baSBill Taylor static int 14939e39c5baSBill Taylor hermon_rsrc_sw_handles_init(hermon_state_t *state, 14949e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t *info) 14959e39c5baSBill Taylor { 14969e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool; 14979e39c5baSBill Taylor uint64_t num_swhdl, max_swhdl, prealloc_sz; 14989e39c5baSBill Taylor 14999e39c5baSBill Taylor ASSERT(state != NULL); 15009e39c5baSBill Taylor ASSERT(info != NULL); 15019e39c5baSBill Taylor 15029e39c5baSBill Taylor rsrc_pool = info->swi_rsrcpool; 15039e39c5baSBill Taylor ASSERT(rsrc_pool != NULL); 15049e39c5baSBill Taylor num_swhdl = info->swi_num; 15059e39c5baSBill Taylor max_swhdl = info->swi_max; 15069e39c5baSBill Taylor prealloc_sz = info->swi_prealloc_sz; 15079e39c5baSBill Taylor 15089e39c5baSBill Taylor 15099e39c5baSBill Taylor /* Make sure number of SW handles makes sense */ 15109e39c5baSBill Taylor if (num_swhdl > max_swhdl) { 15119e39c5baSBill Taylor return (DDI_FAILURE); 15129e39c5baSBill Taylor } 15139e39c5baSBill Taylor 15149e39c5baSBill Taylor /* 15159e39c5baSBill Taylor * Depending on the flags parameter, create a kmem_cache for some 15169e39c5baSBill Taylor * number of software handle structures. Note: kmem_cache_create() 15179e39c5baSBill Taylor * will SLEEP until successful. 15189e39c5baSBill Taylor */ 15199e39c5baSBill Taylor if (info->swi_flags & HERMON_SWHDL_KMEMCACHE_INIT) { 15209e39c5baSBill Taylor rsrc_pool->rsrc_private = kmem_cache_create( 15219e39c5baSBill Taylor info->swi_rsrcname, rsrc_pool->rsrc_quantum, 0, 15229e39c5baSBill Taylor info->swi_constructor, info->swi_destructor, NULL, 15239e39c5baSBill Taylor rsrc_pool->rsrc_state, NULL, 0); 15249e39c5baSBill Taylor } 15259e39c5baSBill Taylor 15269e39c5baSBill Taylor 15279e39c5baSBill Taylor /* Allocate the central list of SW handle pointers */ 15289e39c5baSBill Taylor if (info->swi_flags & HERMON_SWHDL_TABLE_INIT) { 15299e39c5baSBill Taylor info->swi_table_ptr = kmem_zalloc(num_swhdl * prealloc_sz, 15309e39c5baSBill Taylor KM_SLEEP); 15319e39c5baSBill Taylor } 15329e39c5baSBill Taylor 15339e39c5baSBill Taylor return (DDI_SUCCESS); 15349e39c5baSBill Taylor } 15359e39c5baSBill Taylor 15369e39c5baSBill Taylor 15379e39c5baSBill Taylor /* 15389e39c5baSBill Taylor * hermon_rsrc_sw_handles_fini() 15399e39c5baSBill Taylor * Context: Only called from attach() and/or detach() path contexts 15409e39c5baSBill Taylor */ 15419e39c5baSBill Taylor /* ARGSUSED */ 15429e39c5baSBill Taylor static void 15439e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(hermon_state_t *state, 15449e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t *info) 15459e39c5baSBill Taylor { 15469e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool; 15479e39c5baSBill Taylor uint64_t num_swhdl, prealloc_sz; 15489e39c5baSBill Taylor 15499e39c5baSBill Taylor ASSERT(state != NULL); 15509e39c5baSBill Taylor ASSERT(info != NULL); 15519e39c5baSBill Taylor 15529e39c5baSBill Taylor rsrc_pool = info->swi_rsrcpool; 15539e39c5baSBill Taylor num_swhdl = info->swi_num; 15549e39c5baSBill Taylor prealloc_sz = info->swi_prealloc_sz; 15559e39c5baSBill Taylor 15569e39c5baSBill Taylor /* 15579e39c5baSBill Taylor * If a "software handle" kmem_cache exists for this resource, then 15589e39c5baSBill Taylor * destroy it now 15599e39c5baSBill Taylor */ 15609e39c5baSBill Taylor if (rsrc_pool != NULL) { 15619e39c5baSBill Taylor kmem_cache_destroy(rsrc_pool->rsrc_private); 15629e39c5baSBill Taylor } 15639e39c5baSBill Taylor 15649e39c5baSBill Taylor /* Free up this central list of SW handle pointers */ 15659e39c5baSBill Taylor if (info->swi_table_ptr != NULL) { 15669e39c5baSBill Taylor kmem_free(info->swi_table_ptr, num_swhdl * prealloc_sz); 15679e39c5baSBill Taylor } 15689e39c5baSBill Taylor } 15699e39c5baSBill Taylor 15709e39c5baSBill Taylor 15719e39c5baSBill Taylor /* 15729e39c5baSBill Taylor * hermon_rsrc_pd_handles_init() 15739e39c5baSBill Taylor * Context: Only called from attach() path context 15749e39c5baSBill Taylor */ 15759e39c5baSBill Taylor static int 15769e39c5baSBill Taylor hermon_rsrc_pd_handles_init(hermon_state_t *state, 15779e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t *info) 15789e39c5baSBill Taylor { 15799e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool; 15809e39c5baSBill Taylor vmem_t *vmp; 15819e39c5baSBill Taylor char vmem_name[HERMON_RSRC_NAME_MAXLEN]; 15829e39c5baSBill Taylor int status; 15839e39c5baSBill Taylor 15849e39c5baSBill Taylor ASSERT(state != NULL); 15859e39c5baSBill Taylor ASSERT(info != NULL); 15869e39c5baSBill Taylor 15879e39c5baSBill Taylor rsrc_pool = info->swi_rsrcpool; 15889e39c5baSBill Taylor ASSERT(rsrc_pool != NULL); 15899e39c5baSBill Taylor 15909e39c5baSBill Taylor /* Initialize the resource pool for software handle table */ 15919e39c5baSBill Taylor status = hermon_rsrc_sw_handles_init(state, info); 15929e39c5baSBill Taylor if (status != DDI_SUCCESS) { 15939e39c5baSBill Taylor return (DDI_FAILURE); 15949e39c5baSBill Taylor } 15959e39c5baSBill Taylor 15969e39c5baSBill Taylor /* Build vmem arena name from Hermon instance */ 15979e39c5baSBill Taylor HERMON_RSRC_NAME(vmem_name, HERMON_PDHDL_VMEM); 15989e39c5baSBill Taylor 15999e39c5baSBill Taylor /* Create new vmem arena for PD numbers */ 16009e39c5baSBill Taylor vmp = vmem_create(vmem_name, (caddr_t)1, info->swi_num, 1, NULL, 16019e39c5baSBill Taylor NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER); 16029e39c5baSBill Taylor if (vmp == NULL) { 16039e39c5baSBill Taylor /* Unable to create vmem arena */ 16049e39c5baSBill Taylor info->swi_table_ptr = NULL; 16059e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, info); 16069e39c5baSBill Taylor return (DDI_FAILURE); 16079e39c5baSBill Taylor } 16089e39c5baSBill Taylor rsrc_pool->rsrc_vmp = vmp; 16099e39c5baSBill Taylor 16109e39c5baSBill Taylor return (DDI_SUCCESS); 16119e39c5baSBill Taylor } 16129e39c5baSBill Taylor 16139e39c5baSBill Taylor 16149e39c5baSBill Taylor /* 16159e39c5baSBill Taylor * hermon_rsrc_pd_handles_fini() 16169e39c5baSBill Taylor * Context: Only called from attach() and/or detach() path contexts 16179e39c5baSBill Taylor */ 16189e39c5baSBill Taylor static void 16199e39c5baSBill Taylor hermon_rsrc_pd_handles_fini(hermon_state_t *state, 16209e39c5baSBill Taylor hermon_rsrc_sw_hdl_info_t *info) 16219e39c5baSBill Taylor { 16229e39c5baSBill Taylor hermon_rsrc_pool_info_t *rsrc_pool; 16239e39c5baSBill Taylor 16249e39c5baSBill Taylor ASSERT(state != NULL); 16259e39c5baSBill Taylor ASSERT(info != NULL); 16269e39c5baSBill Taylor 16279e39c5baSBill Taylor rsrc_pool = info->swi_rsrcpool; 16289e39c5baSBill Taylor 16299e39c5baSBill Taylor /* Destroy the specially created UAR scratch table vmem arena */ 16309e39c5baSBill Taylor vmem_destroy(rsrc_pool->rsrc_vmp); 16319e39c5baSBill Taylor 16329e39c5baSBill Taylor /* Destroy the "hermon_sw_pd_t" kmem_cache */ 16339e39c5baSBill Taylor hermon_rsrc_sw_handles_fini(state, info); 16349e39c5baSBill Taylor } 16359e39c5baSBill Taylor 16369e39c5baSBill Taylor 16379e39c5baSBill Taylor /* 16389e39c5baSBill Taylor * hermon_rsrc_mbox_alloc() 16399e39c5baSBill Taylor * Context: Only called from attach() path context 16409e39c5baSBill Taylor */ 16419e39c5baSBill Taylor static int 16429e39c5baSBill Taylor hermon_rsrc_mbox_alloc(hermon_rsrc_pool_info_t *pool_info, uint_t num, 16439e39c5baSBill Taylor hermon_rsrc_t *hdl) 16449e39c5baSBill Taylor { 16459e39c5baSBill Taylor hermon_rsrc_priv_mbox_t *priv; 16469e39c5baSBill Taylor caddr_t kaddr; 16479e39c5baSBill Taylor size_t real_len, temp_len; 16489e39c5baSBill Taylor int status; 16499e39c5baSBill Taylor 16509e39c5baSBill Taylor ASSERT(pool_info != NULL); 16519e39c5baSBill Taylor ASSERT(hdl != NULL); 16529e39c5baSBill Taylor 16539e39c5baSBill Taylor /* Get the private pointer for the mailboxes */ 16549e39c5baSBill Taylor priv = pool_info->rsrc_private; 16559e39c5baSBill Taylor ASSERT(priv != NULL); 16569e39c5baSBill Taylor 16579e39c5baSBill Taylor /* Allocate a DMA handle for the mailbox */ 16589e39c5baSBill Taylor status = ddi_dma_alloc_handle(priv->pmb_dip, &priv->pmb_dmaattr, 16599e39c5baSBill Taylor DDI_DMA_SLEEP, NULL, &hdl->hr_dmahdl); 16609e39c5baSBill Taylor if (status != DDI_SUCCESS) { 16619e39c5baSBill Taylor return (DDI_FAILURE); 16629e39c5baSBill Taylor } 16639e39c5baSBill Taylor 16649e39c5baSBill Taylor /* Allocate memory for the mailbox */ 16659e39c5baSBill Taylor temp_len = (num * pool_info->rsrc_quantum); 16669e39c5baSBill Taylor status = ddi_dma_mem_alloc(hdl->hr_dmahdl, temp_len, 16679e39c5baSBill Taylor &priv->pmb_devaccattr, priv->pmb_xfer_mode, DDI_DMA_SLEEP, 16689e39c5baSBill Taylor NULL, &kaddr, &real_len, &hdl->hr_acchdl); 16699e39c5baSBill Taylor if (status != DDI_SUCCESS) { 16709e39c5baSBill Taylor /* No more memory available for mailbox entries */ 16719e39c5baSBill Taylor ddi_dma_free_handle(&hdl->hr_dmahdl); 16729e39c5baSBill Taylor return (DDI_FAILURE); 16739e39c5baSBill Taylor } 16749e39c5baSBill Taylor 16759e39c5baSBill Taylor hdl->hr_addr = (void *)kaddr; 16769e39c5baSBill Taylor hdl->hr_len = (uint32_t)real_len; 16779e39c5baSBill Taylor 16789e39c5baSBill Taylor return (DDI_SUCCESS); 16799e39c5baSBill Taylor } 16809e39c5baSBill Taylor 16819e39c5baSBill Taylor 16829e39c5baSBill Taylor /* 16839e39c5baSBill Taylor * hermon_rsrc_mbox_free() 16849e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 16859e39c5baSBill Taylor */ 16869e39c5baSBill Taylor static void 16879e39c5baSBill Taylor hermon_rsrc_mbox_free(hermon_rsrc_pool_info_t *pool_info, hermon_rsrc_t *hdl) 16889e39c5baSBill Taylor { 16899e39c5baSBill Taylor ASSERT(pool_info != NULL); 16909e39c5baSBill Taylor ASSERT(hdl != NULL); 16919e39c5baSBill Taylor 16929e39c5baSBill Taylor /* Use ddi_dma_mem_free() to free up sys memory for mailbox */ 16939e39c5baSBill Taylor ddi_dma_mem_free(&hdl->hr_acchdl); 16949e39c5baSBill Taylor 16959e39c5baSBill Taylor /* Free the DMA handle for the mailbox */ 16969e39c5baSBill Taylor ddi_dma_free_handle(&hdl->hr_dmahdl); 16979e39c5baSBill Taylor } 16989e39c5baSBill Taylor 16999e39c5baSBill Taylor 17009e39c5baSBill Taylor /* 17019e39c5baSBill Taylor * hermon_rsrc_hw_entry_alloc() 17029e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 17039e39c5baSBill Taylor */ 17049e39c5baSBill Taylor static int 17059e39c5baSBill Taylor hermon_rsrc_hw_entry_alloc(hermon_rsrc_pool_info_t *pool_info, uint_t num, 17069e39c5baSBill Taylor uint_t num_align, ddi_acc_handle_t acc_handle, uint_t sleepflag, 17079e39c5baSBill Taylor hermon_rsrc_t *hdl) 17089e39c5baSBill Taylor { 17099e39c5baSBill Taylor void *addr; 17109e39c5baSBill Taylor uint64_t offset; 17119e39c5baSBill Taylor uint32_t align; 17129e39c5baSBill Taylor int status; 17139e39c5baSBill Taylor int flag; 17149e39c5baSBill Taylor 17159e39c5baSBill Taylor ASSERT(pool_info != NULL); 17169e39c5baSBill Taylor ASSERT(hdl != NULL); 17179e39c5baSBill Taylor 17189e39c5baSBill Taylor /* 17199e39c5baSBill Taylor * Hermon hardware entries (QPC, CQC, EQC, MPT, etc.) do not 17209e39c5baSBill Taylor * generally use the acc_handle (because the entries are not 17219e39c5baSBill Taylor * directly accessed by software). The exception to this rule 17229e39c5baSBill Taylor * are the MTT entries. 17239e39c5baSBill Taylor */ 17249e39c5baSBill Taylor 17259e39c5baSBill Taylor /* 17269e39c5baSBill Taylor * Use vmem_xalloc() to get a properly aligned pointer (based on 17279e39c5baSBill Taylor * the number requested) to the HW entry(ies). This handles the 17289e39c5baSBill Taylor * cases (for special QPCs and for RDB entries) where we need more 17299e39c5baSBill Taylor * than one and need to ensure that they are properly aligned. 17309e39c5baSBill Taylor */ 17319e39c5baSBill Taylor flag = (sleepflag == HERMON_SLEEP) ? VM_SLEEP : VM_NOSLEEP; 17329e39c5baSBill Taylor hdl->hr_len = (num * pool_info->rsrc_quantum); 17339e39c5baSBill Taylor align = (num_align * pool_info->rsrc_quantum); 17349e39c5baSBill Taylor 17359e39c5baSBill Taylor addr = vmem_xalloc(pool_info->rsrc_vmp, hdl->hr_len, 17369e39c5baSBill Taylor align, 0, 0, NULL, NULL, flag | VM_FIRSTFIT); 17379e39c5baSBill Taylor 17389e39c5baSBill Taylor if (addr == NULL) { 17399e39c5baSBill Taylor /* No more HW entries available */ 17409e39c5baSBill Taylor return (DDI_FAILURE); 17419e39c5baSBill Taylor } 17429e39c5baSBill Taylor 17439e39c5baSBill Taylor hdl->hr_acchdl = acc_handle; 17449e39c5baSBill Taylor 17459e39c5baSBill Taylor /* Calculate vaddr and HW table index */ 17469e39c5baSBill Taylor offset = (uintptr_t)addr - (uintptr_t)pool_info->rsrc_start; 17479e39c5baSBill Taylor hdl->hr_addr = addr; 17489e39c5baSBill Taylor hdl->hr_indx = offset >> pool_info->rsrc_shift; 17499e39c5baSBill Taylor 17509e39c5baSBill Taylor if (pool_info->rsrc_loc == HERMON_IN_ICM) { 17519e39c5baSBill Taylor /* confirm ICM is mapped, and allocate if necessary */ 17529e39c5baSBill Taylor status = hermon_rsrc_hw_entry_icm_confirm(pool_info, num, hdl); 17539e39c5baSBill Taylor if (status != DDI_SUCCESS) { 17549e39c5baSBill Taylor return (DDI_FAILURE); 17559e39c5baSBill Taylor } 1756*c7facc54SBill Taylor hdl->hr_addr = NULL; 17579e39c5baSBill Taylor } 17589e39c5baSBill Taylor 17599e39c5baSBill Taylor return (DDI_SUCCESS); 17609e39c5baSBill Taylor } 17619e39c5baSBill Taylor 17629e39c5baSBill Taylor 17639e39c5baSBill Taylor 17649e39c5baSBill Taylor /* 17659e39c5baSBill Taylor * hermon_rsrc_hw_entry_free() 17669e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 17679e39c5baSBill Taylor */ 17689e39c5baSBill Taylor static void 17699e39c5baSBill Taylor hermon_rsrc_hw_entry_free(hermon_rsrc_pool_info_t *pool_info, 17709e39c5baSBill Taylor hermon_rsrc_t *hdl) 17719e39c5baSBill Taylor { 17729e39c5baSBill Taylor void *addr; 17739e39c5baSBill Taylor uint64_t offset; 17749e39c5baSBill Taylor int status; 17759e39c5baSBill Taylor 17769e39c5baSBill Taylor ASSERT(pool_info != NULL); 17779e39c5baSBill Taylor ASSERT(hdl != NULL); 17789e39c5baSBill Taylor 17799e39c5baSBill Taylor /* Calculate the allocated address */ 17809e39c5baSBill Taylor offset = hdl->hr_indx << pool_info->rsrc_shift; 17819e39c5baSBill Taylor addr = (void *)(uintptr_t)(offset + (uintptr_t)pool_info->rsrc_start); 17829e39c5baSBill Taylor 17839e39c5baSBill Taylor /* Use vmem_xfree() to free up the HW table entry */ 17849e39c5baSBill Taylor vmem_xfree(pool_info->rsrc_vmp, addr, hdl->hr_len); 17859e39c5baSBill Taylor 17869e39c5baSBill Taylor if (pool_info->rsrc_loc == HERMON_IN_ICM) { 17879e39c5baSBill Taylor /* free ICM references, and free ICM if required */ 17889e39c5baSBill Taylor status = hermon_rsrc_hw_entry_icm_free(pool_info, hdl); 17899e39c5baSBill Taylor if (status != DDI_SUCCESS) 17909e39c5baSBill Taylor HERMON_WARNING(pool_info->rsrc_state, 17919e39c5baSBill Taylor "failure in hw_entry_free"); 17929e39c5baSBill Taylor } 17939e39c5baSBill Taylor } 17949e39c5baSBill Taylor 17959e39c5baSBill Taylor /* 17969e39c5baSBill Taylor * hermon_rsrc_hw_entry_icm_confirm() 17979e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 17989e39c5baSBill Taylor */ 17999e39c5baSBill Taylor static int 18009e39c5baSBill Taylor hermon_rsrc_hw_entry_icm_confirm(hermon_rsrc_pool_info_t *pool_info, uint_t num, 18019e39c5baSBill Taylor hermon_rsrc_t *hdl) 18029e39c5baSBill Taylor { 18039e39c5baSBill Taylor hermon_state_t *state; 18049e39c5baSBill Taylor hermon_icm_table_t *icm_table; 18059e39c5baSBill Taylor uint8_t *bitmap; 18069e39c5baSBill Taylor hermon_dma_info_t *dma_info; 18079e39c5baSBill Taylor hermon_rsrc_type_t type; 18089e39c5baSBill Taylor uint32_t rindx, span_offset; 18099e39c5baSBill Taylor uint32_t span_avail; 18109e39c5baSBill Taylor int num_backed; 18119e39c5baSBill Taylor int status; 18129e39c5baSBill Taylor uint32_t index1, index2; 18139e39c5baSBill Taylor 18149e39c5baSBill Taylor /* 18159e39c5baSBill Taylor * Utility routine responsible for ensuring that there is memory 18169e39c5baSBill Taylor * backing the ICM resources allocated via hermon_rsrc_hw_entry_alloc(). 18179e39c5baSBill Taylor * Confirm existing ICM mapping(s) or allocate ICM memory for the 18189e39c5baSBill Taylor * given hardware resources being allocated, and increment the 18199e39c5baSBill Taylor * ICM DMA structure(s) reference count. 18209e39c5baSBill Taylor * 18219e39c5baSBill Taylor * We may be allocating more objects than can fit in a single span, 18229e39c5baSBill Taylor * or more than will fit in the remaining contiguous memory (from 18239e39c5baSBill Taylor * the offset indicated by hdl->ar_indx) in the span in question. 18249e39c5baSBill Taylor * In either of these cases, we'll be breaking up our allocation 18259e39c5baSBill Taylor * into multiple spans. 18269e39c5baSBill Taylor */ 18279e39c5baSBill Taylor state = pool_info->rsrc_state; 18289e39c5baSBill Taylor type = pool_info->rsrc_type; 18299e39c5baSBill Taylor icm_table = &state->hs_icm[type]; 18309e39c5baSBill Taylor 18319e39c5baSBill Taylor rindx = hdl->hr_indx; 18329e39c5baSBill Taylor hermon_index(index1, index2, rindx, icm_table, span_offset); 18339e39c5baSBill Taylor 18349e39c5baSBill Taylor if (hermon_rsrc_verbose) { 18359e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entry_icm_confirm: " 18369e39c5baSBill Taylor "type (0x%x) num (0x%x) length (0x%x) index (0x%x, 0x%x): ", 18379e39c5baSBill Taylor type, num, hdl->hr_len, index1, index2); 18389e39c5baSBill Taylor } 18399e39c5baSBill Taylor 18409e39c5baSBill Taylor mutex_enter(&icm_table->icm_table_lock); 18419e39c5baSBill Taylor hermon_bitmap(bitmap, dma_info, icm_table, index1); 18429e39c5baSBill Taylor while (num) { 18439e39c5baSBill Taylor #ifndef __lock_lint 18449e39c5baSBill Taylor while (icm_table->icm_busy) { 18459e39c5baSBill Taylor cv_wait(&icm_table->icm_table_cv, 18469e39c5baSBill Taylor &icm_table->icm_table_lock); 18479e39c5baSBill Taylor } 18489e39c5baSBill Taylor #endif 18499e39c5baSBill Taylor if (!HERMON_BMAP_BIT_ISSET(bitmap, index2)) { 18509e39c5baSBill Taylor /* Allocate ICM for this span */ 18519e39c5baSBill Taylor icm_table->icm_busy = 1; 18529e39c5baSBill Taylor mutex_exit(&icm_table->icm_table_lock); 18539e39c5baSBill Taylor status = hermon_icm_alloc(state, type, index1, index2); 18549e39c5baSBill Taylor mutex_enter(&icm_table->icm_table_lock); 18559e39c5baSBill Taylor icm_table->icm_busy = 0; 18569e39c5baSBill Taylor cv_broadcast(&icm_table->icm_table_cv); 18579e39c5baSBill Taylor if (status != DDI_SUCCESS) { 18589e39c5baSBill Taylor goto fail_alloc; 18599e39c5baSBill Taylor } 18609e39c5baSBill Taylor if (hermon_rsrc_verbose) { 18619e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "hermon_rsrc_" 18629e39c5baSBill Taylor "hw_entry_icm_confirm: ALLOCATED ICM: " 18639e39c5baSBill Taylor "type (0x%x) index (0x%x, 0x%x)", 18649e39c5baSBill Taylor type, index1, index2); 18659e39c5baSBill Taylor } 18669e39c5baSBill Taylor } 18679e39c5baSBill Taylor 18689e39c5baSBill Taylor /* 18699e39c5baSBill Taylor * Mellanox FMR accesses the MPT directly. We set the 18709e39c5baSBill Taylor * access handle here only for this case 18719e39c5baSBill Taylor */ 18729e39c5baSBill Taylor if (type == HERMON_DMPT) 18739e39c5baSBill Taylor hdl->hr_acchdl = dma_info[index2].acc_hdl; 18749e39c5baSBill Taylor 18759e39c5baSBill Taylor /* 18769e39c5baSBill Taylor * We need to increment the refcnt of this span by the 18779e39c5baSBill Taylor * number of objects in this resource allocation that are 18789e39c5baSBill Taylor * backed by this span. Given that the rsrc allocation is 18799e39c5baSBill Taylor * contiguous, this value will be the number of objects in 18809e39c5baSBill Taylor * the span from 'span_offset' onward, either up to a max 18819e39c5baSBill Taylor * of the total number of objects, or the end of the span. 18829e39c5baSBill Taylor * So, determine the number of objects that can be backed 18839e39c5baSBill Taylor * by this span ('span_avail'), then determine the number 18849e39c5baSBill Taylor * of backed resources. 18859e39c5baSBill Taylor */ 18869e39c5baSBill Taylor span_avail = icm_table->span - span_offset; 18879e39c5baSBill Taylor if (num > span_avail) { 18889e39c5baSBill Taylor num_backed = span_avail; 18899e39c5baSBill Taylor } else { 18909e39c5baSBill Taylor num_backed = num; 18919e39c5baSBill Taylor } 18929e39c5baSBill Taylor 18939e39c5baSBill Taylor /* 18949e39c5baSBill Taylor * Now that we know 'num_backed', increment the refcnt, 18959e39c5baSBill Taylor * decrement the total number, and set 'span_offset' to 18969e39c5baSBill Taylor * 0 in case we roll over into the next span. 18979e39c5baSBill Taylor */ 18989e39c5baSBill Taylor dma_info[index2].icm_refcnt += num_backed; 18999e39c5baSBill Taylor rindx += num_backed; 19009e39c5baSBill Taylor num -= num_backed; 19019e39c5baSBill Taylor 19029e39c5baSBill Taylor if (hermon_rsrc_verbose) { 19039e39c5baSBill Taylor IBTF_DPRINTF_L2("ALLOC", "ICM type (0x%x) index " 19049e39c5baSBill Taylor "(0x%x, 0x%x) num_backed (0x%x)", 19059e39c5baSBill Taylor type, index1, index2, num_backed); 19069e39c5baSBill Taylor IBTF_DPRINTF_L2("ALLOC", "ICM type (0x%x) refcnt now " 19079e39c5baSBill Taylor "(0x%x) num_remaining (0x%x)", type, 19089e39c5baSBill Taylor dma_info[index2].icm_refcnt, num); 19099e39c5baSBill Taylor } 19109e39c5baSBill Taylor if (num == 0) 19119e39c5baSBill Taylor break; 19129e39c5baSBill Taylor 19139e39c5baSBill Taylor hermon_index(index1, index2, rindx, icm_table, span_offset); 19149e39c5baSBill Taylor hermon_bitmap(bitmap, dma_info, icm_table, index1); 19159e39c5baSBill Taylor } 19169e39c5baSBill Taylor mutex_exit(&icm_table->icm_table_lock); 19179e39c5baSBill Taylor 19189e39c5baSBill Taylor return (DDI_SUCCESS); 19199e39c5baSBill Taylor 19209e39c5baSBill Taylor fail_alloc: 19219e39c5baSBill Taylor /* JBDB */ 19229e39c5baSBill Taylor if (hermon_rsrc_verbose) { 19239e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "hermon_rsrc_" 19249e39c5baSBill Taylor "hw_entry_icm_confirm: FAILED ICM ALLOC: " 19259e39c5baSBill Taylor "type (0x%x) num remaind (0x%x) index (0x%x, 0x%x)" 19269e39c5baSBill Taylor "refcnt (0x%x)", type, num, index1, index2, 19279e39c5baSBill Taylor icm_table->icm_dma[index1][index2].icm_refcnt); 19289e39c5baSBill Taylor } 19299e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "WARNING: " 19309e39c5baSBill Taylor "unimplemented fail code in hermon_rsrc_hw_entry_icm_alloc\n"); 19319e39c5baSBill Taylor 19329e39c5baSBill Taylor #if needs_work 19339e39c5baSBill Taylor /* free refcnt's and any spans we've allocated */ 19349e39c5baSBill Taylor while (index-- != start) { 19359e39c5baSBill Taylor /* 19369e39c5baSBill Taylor * JBDB - This is a bit tricky. We need to 19379e39c5baSBill Taylor * free refcnt's on any spans that we've 19389e39c5baSBill Taylor * incremented them on, and completely free 19399e39c5baSBill Taylor * spans that we've allocated. How do we do 19409e39c5baSBill Taylor * this here? Does it need to be as involved 19419e39c5baSBill Taylor * as the core of icm_free() below, or can 19429e39c5baSBill Taylor * we leverage breadcrumbs somehow? 19439e39c5baSBill Taylor */ 19449e39c5baSBill Taylor HERMON_WARNING(state, "unable to allocate ICM memory: " 19459e39c5baSBill Taylor "UNIMPLEMENTED HANDLING!!"); 19469e39c5baSBill Taylor } 19479e39c5baSBill Taylor #else 19489e39c5baSBill Taylor cmn_err(CE_WARN, 19499e39c5baSBill Taylor "unimplemented fail code in hermon_rsrc_hw_entry_icm_alloc\n"); 19509e39c5baSBill Taylor #endif 19519e39c5baSBill Taylor mutex_exit(&icm_table->icm_table_lock); 19529e39c5baSBill Taylor 19539e39c5baSBill Taylor HERMON_WARNING(state, "unable to allocate ICM memory"); 19549e39c5baSBill Taylor return (DDI_FAILURE); 19559e39c5baSBill Taylor } 19569e39c5baSBill Taylor 19579e39c5baSBill Taylor /* 19589e39c5baSBill Taylor * hermon_rsrc_hw_entry_icm_free() 19599e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 19609e39c5baSBill Taylor */ 19619e39c5baSBill Taylor static int 19629e39c5baSBill Taylor hermon_rsrc_hw_entry_icm_free(hermon_rsrc_pool_info_t *pool_info, 19639e39c5baSBill Taylor hermon_rsrc_t *hdl) 19649e39c5baSBill Taylor { 19659e39c5baSBill Taylor hermon_state_t *state; 19669e39c5baSBill Taylor hermon_icm_table_t *icm_table; 19679e39c5baSBill Taylor uint8_t *bitmap; 19689e39c5baSBill Taylor hermon_dma_info_t *dma_info; 19699e39c5baSBill Taylor hermon_rsrc_type_t type; 19709e39c5baSBill Taylor uint32_t span_offset; 19719e39c5baSBill Taylor uint32_t span_remain; 19729e39c5baSBill Taylor int num_freed; 19739e39c5baSBill Taylor int num; 19749e39c5baSBill Taylor uint32_t index1, index2, rindx; 19759e39c5baSBill Taylor 19769e39c5baSBill Taylor /* 19779e39c5baSBill Taylor * Utility routine responsible for freeing references to ICM 19789e39c5baSBill Taylor * DMA spans, and freeing the ICM memory if necessary. 19799e39c5baSBill Taylor * 19809e39c5baSBill Taylor * We may have allocated objects in a single contiguous resource 19819e39c5baSBill Taylor * allocation that reside in a number of spans, at any given 19829e39c5baSBill Taylor * starting offset within a span. We therefore must determine 19839e39c5baSBill Taylor * where this allocation starts, and then determine if we need 19849e39c5baSBill Taylor * to free objects in more than one span. 19859e39c5baSBill Taylor */ 19869e39c5baSBill Taylor state = pool_info->rsrc_state; 19879e39c5baSBill Taylor type = pool_info->rsrc_type; 19889e39c5baSBill Taylor icm_table = &state->hs_icm[type]; 19899e39c5baSBill Taylor 19909e39c5baSBill Taylor rindx = hdl->hr_indx; 19919e39c5baSBill Taylor hermon_index(index1, index2, rindx, icm_table, span_offset); 19929e39c5baSBill Taylor hermon_bitmap(bitmap, dma_info, icm_table, index1); 19939e39c5baSBill Taylor 19949e39c5baSBill Taylor /* determine the number of ICM objects in this allocation */ 19959e39c5baSBill Taylor num = hdl->hr_len >> pool_info->rsrc_shift; 19969e39c5baSBill Taylor 19979e39c5baSBill Taylor if (hermon_rsrc_verbose) { 19989e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entry_icm_free: " 19999e39c5baSBill Taylor "type (0x%x) num (0x%x) length (0x%x) index (0x%x, 0x%x)", 20009e39c5baSBill Taylor type, num, hdl->hr_len, index1, index2); 20019e39c5baSBill Taylor } 20029e39c5baSBill Taylor mutex_enter(&icm_table->icm_table_lock); 20039e39c5baSBill Taylor while (num) { 20049e39c5baSBill Taylor /* 20059e39c5baSBill Taylor * As with the ICM confirm code above, we need to 20069e39c5baSBill Taylor * decrement the ICM span(s) by the number of 20079e39c5baSBill Taylor * resources being freed. So, determine the number 20089e39c5baSBill Taylor * of objects that are backed in this span from 20099e39c5baSBill Taylor * 'span_offset' onward, and set 'num_freed' to 20109e39c5baSBill Taylor * the smaller of either that number ('span_remain'), 20119e39c5baSBill Taylor * or the total number of objects being freed. 20129e39c5baSBill Taylor */ 20139e39c5baSBill Taylor span_remain = icm_table->span - span_offset; 20149e39c5baSBill Taylor if (num > span_remain) { 20159e39c5baSBill Taylor num_freed = span_remain; 20169e39c5baSBill Taylor } else { 20179e39c5baSBill Taylor num_freed = num; 20189e39c5baSBill Taylor } 20199e39c5baSBill Taylor 20209e39c5baSBill Taylor /* 20219e39c5baSBill Taylor * Now that we know 'num_freed', decrement the refcnt, 20229e39c5baSBill Taylor * decrement the total number, and set 'span_offset' to 20239e39c5baSBill Taylor * 0 in case we roll over into the next span. 20249e39c5baSBill Taylor */ 20259e39c5baSBill Taylor dma_info[index2].icm_refcnt -= num_freed; 20269e39c5baSBill Taylor num -= num_freed; 20279e39c5baSBill Taylor rindx += num_freed; 20289e39c5baSBill Taylor 20299e39c5baSBill Taylor if (hermon_rsrc_verbose) { 20309e39c5baSBill Taylor IBTF_DPRINTF_L2("FREE", "ICM type (0x%x) index " 20319e39c5baSBill Taylor "(0x%x, 0x%x) num_freed (0x%x)", type, 20329e39c5baSBill Taylor index1, index2, num_freed); 20339e39c5baSBill Taylor IBTF_DPRINTF_L2("FREE", "ICM type (0x%x) refcnt now " 20349e39c5baSBill Taylor "(0x%x) num remaining (0x%x)", type, 20359e39c5baSBill Taylor icm_table->icm_dma[index1][index2].icm_refcnt, num); 20369e39c5baSBill Taylor } 20379e39c5baSBill Taylor 20389e39c5baSBill Taylor #if HERMON_ICM_FREE_ENABLED 20399e39c5baSBill Taylor /* If we've freed the last object in this span, free it */ 20409e39c5baSBill Taylor if ((index1 != 0 || index2 != 0) && 20419e39c5baSBill Taylor (dma_info[index2].icm_refcnt == 0)) { 20429e39c5baSBill Taylor if (hermon_rsrc_verbose) { 20439e39c5baSBill Taylor IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entry" 20449e39c5baSBill Taylor "_icm_free: freeing ICM type (0x%x) index" 20459e39c5baSBill Taylor " (0x%x, 0x%x)", type, index1, index2); 20469e39c5baSBill Taylor } 20479e39c5baSBill Taylor hermon_icm_free(state, type, index1, index2); 20489e39c5baSBill Taylor } 20499e39c5baSBill Taylor #endif 20509e39c5baSBill Taylor if (num == 0) 20519e39c5baSBill Taylor break; 20529e39c5baSBill Taylor 20539e39c5baSBill Taylor hermon_index(index1, index2, rindx, icm_table, span_offset); 20549e39c5baSBill Taylor hermon_bitmap(bitmap, dma_info, icm_table, index1); 20559e39c5baSBill Taylor } 20569e39c5baSBill Taylor mutex_exit(&icm_table->icm_table_lock); 20579e39c5baSBill Taylor 20589e39c5baSBill Taylor return (DDI_SUCCESS); 20599e39c5baSBill Taylor } 20609e39c5baSBill Taylor 20619e39c5baSBill Taylor 20629e39c5baSBill Taylor 20639e39c5baSBill Taylor /* 20649e39c5baSBill Taylor * hermon_rsrc_swhdl_alloc() 20659e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 20669e39c5baSBill Taylor */ 20679e39c5baSBill Taylor static int 20689e39c5baSBill Taylor hermon_rsrc_swhdl_alloc(hermon_rsrc_pool_info_t *pool_info, uint_t sleepflag, 20699e39c5baSBill Taylor hermon_rsrc_t *hdl) 20709e39c5baSBill Taylor { 20719e39c5baSBill Taylor void *addr; 20729e39c5baSBill Taylor int flag; 20739e39c5baSBill Taylor 20749e39c5baSBill Taylor ASSERT(pool_info != NULL); 20759e39c5baSBill Taylor ASSERT(hdl != NULL); 20769e39c5baSBill Taylor 20779e39c5baSBill Taylor /* Allocate the software handle structure */ 20789e39c5baSBill Taylor flag = (sleepflag == HERMON_SLEEP) ? KM_SLEEP : KM_NOSLEEP; 20799e39c5baSBill Taylor addr = kmem_cache_alloc(pool_info->rsrc_private, flag); 20809e39c5baSBill Taylor if (addr == NULL) { 20819e39c5baSBill Taylor return (DDI_FAILURE); 20829e39c5baSBill Taylor } 20839e39c5baSBill Taylor hdl->hr_len = pool_info->rsrc_quantum; 20849e39c5baSBill Taylor hdl->hr_addr = addr; 20859e39c5baSBill Taylor 20869e39c5baSBill Taylor return (DDI_SUCCESS); 20879e39c5baSBill Taylor } 20889e39c5baSBill Taylor 20899e39c5baSBill Taylor 20909e39c5baSBill Taylor /* 20919e39c5baSBill Taylor * hermon_rsrc_swhdl_free() 20929e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 20939e39c5baSBill Taylor */ 20949e39c5baSBill Taylor static void 20959e39c5baSBill Taylor hermon_rsrc_swhdl_free(hermon_rsrc_pool_info_t *pool_info, hermon_rsrc_t *hdl) 20969e39c5baSBill Taylor { 20979e39c5baSBill Taylor ASSERT(pool_info != NULL); 20989e39c5baSBill Taylor ASSERT(hdl != NULL); 20999e39c5baSBill Taylor 21009e39c5baSBill Taylor /* Free the software handle structure */ 21019e39c5baSBill Taylor kmem_cache_free(pool_info->rsrc_private, hdl->hr_addr); 21029e39c5baSBill Taylor } 21039e39c5baSBill Taylor 21049e39c5baSBill Taylor 21059e39c5baSBill Taylor /* 21069e39c5baSBill Taylor * hermon_rsrc_pdhdl_alloc() 21079e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 21089e39c5baSBill Taylor */ 21099e39c5baSBill Taylor static int 21109e39c5baSBill Taylor hermon_rsrc_pdhdl_alloc(hermon_rsrc_pool_info_t *pool_info, uint_t sleepflag, 21119e39c5baSBill Taylor hermon_rsrc_t *hdl) 21129e39c5baSBill Taylor { 21139e39c5baSBill Taylor hermon_pdhdl_t addr; 21149e39c5baSBill Taylor void *tmpaddr; 21159e39c5baSBill Taylor int flag, status; 21169e39c5baSBill Taylor 21179e39c5baSBill Taylor ASSERT(pool_info != NULL); 21189e39c5baSBill Taylor ASSERT(hdl != NULL); 21199e39c5baSBill Taylor 21209e39c5baSBill Taylor /* Allocate the software handle */ 21219e39c5baSBill Taylor status = hermon_rsrc_swhdl_alloc(pool_info, sleepflag, hdl); 21229e39c5baSBill Taylor if (status != DDI_SUCCESS) { 21239e39c5baSBill Taylor return (DDI_FAILURE); 21249e39c5baSBill Taylor } 21259e39c5baSBill Taylor addr = (hermon_pdhdl_t)hdl->hr_addr; 21269e39c5baSBill Taylor _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*addr)) 21279e39c5baSBill Taylor 21289e39c5baSBill Taylor /* Allocate a PD number for the handle */ 21299e39c5baSBill Taylor flag = (sleepflag == HERMON_SLEEP) ? VM_SLEEP : VM_NOSLEEP; 21309e39c5baSBill Taylor tmpaddr = vmem_alloc(pool_info->rsrc_vmp, 1, flag); 21319e39c5baSBill Taylor if (tmpaddr == NULL) { 21329e39c5baSBill Taylor /* No more PD number entries available */ 21339e39c5baSBill Taylor hermon_rsrc_swhdl_free(pool_info, hdl); 21349e39c5baSBill Taylor return (DDI_FAILURE); 21359e39c5baSBill Taylor } 21369e39c5baSBill Taylor addr->pd_pdnum = (uint32_t)(uintptr_t)tmpaddr; 21379e39c5baSBill Taylor addr->pd_rsrcp = hdl; 21389e39c5baSBill Taylor hdl->hr_indx = addr->pd_pdnum; 21399e39c5baSBill Taylor 21409e39c5baSBill Taylor return (DDI_SUCCESS); 21419e39c5baSBill Taylor } 21429e39c5baSBill Taylor 21439e39c5baSBill Taylor 21449e39c5baSBill Taylor /* 21459e39c5baSBill Taylor * hermon_rsrc_pdhdl_free() 21469e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 21479e39c5baSBill Taylor */ 21489e39c5baSBill Taylor static void 21499e39c5baSBill Taylor hermon_rsrc_pdhdl_free(hermon_rsrc_pool_info_t *pool_info, hermon_rsrc_t *hdl) 21509e39c5baSBill Taylor { 21519e39c5baSBill Taylor ASSERT(pool_info != NULL); 21529e39c5baSBill Taylor ASSERT(hdl != NULL); 21539e39c5baSBill Taylor 21549e39c5baSBill Taylor /* Use vmem_free() to free up the PD number */ 21559e39c5baSBill Taylor vmem_free(pool_info->rsrc_vmp, (void *)(uintptr_t)hdl->hr_indx, 1); 21569e39c5baSBill Taylor 21579e39c5baSBill Taylor /* Free the software handle structure */ 21589e39c5baSBill Taylor hermon_rsrc_swhdl_free(pool_info, hdl); 21599e39c5baSBill Taylor } 21609e39c5baSBill Taylor 21619e39c5baSBill Taylor 21629e39c5baSBill Taylor /* 21639e39c5baSBill Taylor * hermon_rsrc_pdhdl_constructor() 21649e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 21659e39c5baSBill Taylor */ 21669e39c5baSBill Taylor /* ARGSUSED */ 21679e39c5baSBill Taylor static int 21689e39c5baSBill Taylor hermon_rsrc_pdhdl_constructor(void *pd, void *priv, int flags) 21699e39c5baSBill Taylor { 21709e39c5baSBill Taylor hermon_pdhdl_t pdhdl; 21719e39c5baSBill Taylor hermon_state_t *state; 21729e39c5baSBill Taylor 21739e39c5baSBill Taylor pdhdl = (hermon_pdhdl_t)pd; 21749e39c5baSBill Taylor state = (hermon_state_t *)priv; 21759e39c5baSBill Taylor 21769e39c5baSBill Taylor mutex_init(&pdhdl->pd_lock, NULL, MUTEX_DRIVER, 21779e39c5baSBill Taylor DDI_INTR_PRI(state->hs_intrmsi_pri)); 21789e39c5baSBill Taylor 21799e39c5baSBill Taylor return (DDI_SUCCESS); 21809e39c5baSBill Taylor } 21819e39c5baSBill Taylor 21829e39c5baSBill Taylor 21839e39c5baSBill Taylor /* 21849e39c5baSBill Taylor * hermon_rsrc_pdhdl_destructor() 21859e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 21869e39c5baSBill Taylor */ 21879e39c5baSBill Taylor /* ARGSUSED */ 21889e39c5baSBill Taylor static void 21899e39c5baSBill Taylor hermon_rsrc_pdhdl_destructor(void *pd, void *priv) 21909e39c5baSBill Taylor { 21919e39c5baSBill Taylor hermon_pdhdl_t pdhdl; 21929e39c5baSBill Taylor 21939e39c5baSBill Taylor pdhdl = (hermon_pdhdl_t)pd; 21949e39c5baSBill Taylor 21959e39c5baSBill Taylor mutex_destroy(&pdhdl->pd_lock); 21969e39c5baSBill Taylor } 21979e39c5baSBill Taylor 21989e39c5baSBill Taylor 21999e39c5baSBill Taylor /* 22009e39c5baSBill Taylor * hermon_rsrc_cqhdl_constructor() 22019e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 22029e39c5baSBill Taylor */ 22039e39c5baSBill Taylor /* ARGSUSED */ 22049e39c5baSBill Taylor static int 22059e39c5baSBill Taylor hermon_rsrc_cqhdl_constructor(void *cq, void *priv, int flags) 22069e39c5baSBill Taylor { 22079e39c5baSBill Taylor hermon_cqhdl_t cqhdl; 22089e39c5baSBill Taylor hermon_state_t *state; 22099e39c5baSBill Taylor 22109e39c5baSBill Taylor cqhdl = (hermon_cqhdl_t)cq; 22119e39c5baSBill Taylor state = (hermon_state_t *)priv; 22129e39c5baSBill Taylor 22139e39c5baSBill Taylor mutex_init(&cqhdl->cq_lock, NULL, MUTEX_DRIVER, 22149e39c5baSBill Taylor DDI_INTR_PRI(state->hs_intrmsi_pri)); 22159e39c5baSBill Taylor 22169e39c5baSBill Taylor return (DDI_SUCCESS); 22179e39c5baSBill Taylor } 22189e39c5baSBill Taylor 22199e39c5baSBill Taylor 22209e39c5baSBill Taylor /* 22219e39c5baSBill Taylor * hermon_rsrc_cqhdl_destructor() 22229e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 22239e39c5baSBill Taylor */ 22249e39c5baSBill Taylor /* ARGSUSED */ 22259e39c5baSBill Taylor static void 22269e39c5baSBill Taylor hermon_rsrc_cqhdl_destructor(void *cq, void *priv) 22279e39c5baSBill Taylor { 22289e39c5baSBill Taylor hermon_cqhdl_t cqhdl; 22299e39c5baSBill Taylor 22309e39c5baSBill Taylor cqhdl = (hermon_cqhdl_t)cq; 22319e39c5baSBill Taylor 22329e39c5baSBill Taylor mutex_destroy(&cqhdl->cq_lock); 22339e39c5baSBill Taylor } 22349e39c5baSBill Taylor 22359e39c5baSBill Taylor 22369e39c5baSBill Taylor /* 22379e39c5baSBill Taylor * hermon_rsrc_qphdl_constructor() 22389e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 22399e39c5baSBill Taylor */ 22409e39c5baSBill Taylor /* ARGSUSED */ 22419e39c5baSBill Taylor static int 22429e39c5baSBill Taylor hermon_rsrc_qphdl_constructor(void *qp, void *priv, int flags) 22439e39c5baSBill Taylor { 22449e39c5baSBill Taylor hermon_qphdl_t qphdl; 22459e39c5baSBill Taylor hermon_state_t *state; 22469e39c5baSBill Taylor 22479e39c5baSBill Taylor qphdl = (hermon_qphdl_t)qp; 22489e39c5baSBill Taylor state = (hermon_state_t *)priv; 22499e39c5baSBill Taylor 22509e39c5baSBill Taylor mutex_init(&qphdl->qp_lock, NULL, MUTEX_DRIVER, 22519e39c5baSBill Taylor DDI_INTR_PRI(state->hs_intrmsi_pri)); 22529e39c5baSBill Taylor 22539e39c5baSBill Taylor return (DDI_SUCCESS); 22549e39c5baSBill Taylor } 22559e39c5baSBill Taylor 22569e39c5baSBill Taylor 22579e39c5baSBill Taylor /* 22589e39c5baSBill Taylor * hermon_rsrc_qphdl_destructor() 22599e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 22609e39c5baSBill Taylor */ 22619e39c5baSBill Taylor /* ARGSUSED */ 22629e39c5baSBill Taylor static void 22639e39c5baSBill Taylor hermon_rsrc_qphdl_destructor(void *qp, void *priv) 22649e39c5baSBill Taylor { 22659e39c5baSBill Taylor hermon_qphdl_t qphdl; 22669e39c5baSBill Taylor 22679e39c5baSBill Taylor qphdl = (hermon_qphdl_t)qp; 22689e39c5baSBill Taylor 22699e39c5baSBill Taylor mutex_destroy(&qphdl->qp_lock); 22709e39c5baSBill Taylor } 22719e39c5baSBill Taylor 22729e39c5baSBill Taylor 22739e39c5baSBill Taylor /* 22749e39c5baSBill Taylor * hermon_rsrc_srqhdl_constructor() 22759e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 22769e39c5baSBill Taylor */ 22779e39c5baSBill Taylor /* ARGSUSED */ 22789e39c5baSBill Taylor static int 22799e39c5baSBill Taylor hermon_rsrc_srqhdl_constructor(void *srq, void *priv, int flags) 22809e39c5baSBill Taylor { 22819e39c5baSBill Taylor hermon_srqhdl_t srqhdl; 22829e39c5baSBill Taylor hermon_state_t *state; 22839e39c5baSBill Taylor 22849e39c5baSBill Taylor srqhdl = (hermon_srqhdl_t)srq; 22859e39c5baSBill Taylor state = (hermon_state_t *)priv; 22869e39c5baSBill Taylor 22879e39c5baSBill Taylor mutex_init(&srqhdl->srq_lock, NULL, MUTEX_DRIVER, 22889e39c5baSBill Taylor DDI_INTR_PRI(state->hs_intrmsi_pri)); 22899e39c5baSBill Taylor 22909e39c5baSBill Taylor return (DDI_SUCCESS); 22919e39c5baSBill Taylor } 22929e39c5baSBill Taylor 22939e39c5baSBill Taylor 22949e39c5baSBill Taylor /* 22959e39c5baSBill Taylor * hermon_rsrc_srqhdl_destructor() 22969e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 22979e39c5baSBill Taylor */ 22989e39c5baSBill Taylor /* ARGSUSED */ 22999e39c5baSBill Taylor static void 23009e39c5baSBill Taylor hermon_rsrc_srqhdl_destructor(void *srq, void *priv) 23019e39c5baSBill Taylor { 23029e39c5baSBill Taylor hermon_srqhdl_t srqhdl; 23039e39c5baSBill Taylor 23049e39c5baSBill Taylor srqhdl = (hermon_srqhdl_t)srq; 23059e39c5baSBill Taylor 23069e39c5baSBill Taylor mutex_destroy(&srqhdl->srq_lock); 23079e39c5baSBill Taylor } 23089e39c5baSBill Taylor 23099e39c5baSBill Taylor 23109e39c5baSBill Taylor /* 23119e39c5baSBill Taylor * hermon_rsrc_refcnt_constructor() 23129e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 23139e39c5baSBill Taylor */ 23149e39c5baSBill Taylor /* ARGSUSED */ 23159e39c5baSBill Taylor static int 23169e39c5baSBill Taylor hermon_rsrc_refcnt_constructor(void *rc, void *priv, int flags) 23179e39c5baSBill Taylor { 23189e39c5baSBill Taylor hermon_sw_refcnt_t *refcnt; 23199e39c5baSBill Taylor hermon_state_t *state; 23209e39c5baSBill Taylor 23219e39c5baSBill Taylor refcnt = (hermon_sw_refcnt_t *)rc; 23229e39c5baSBill Taylor state = (hermon_state_t *)priv; 23239e39c5baSBill Taylor 23249e39c5baSBill Taylor mutex_init(&refcnt->swrc_lock, NULL, MUTEX_DRIVER, 23259e39c5baSBill Taylor DDI_INTR_PRI(state->hs_intrmsi_pri)); 23269e39c5baSBill Taylor 23279e39c5baSBill Taylor return (DDI_SUCCESS); 23289e39c5baSBill Taylor } 23299e39c5baSBill Taylor 23309e39c5baSBill Taylor 23319e39c5baSBill Taylor /* 23329e39c5baSBill Taylor * hermon_rsrc_refcnt_destructor() 23339e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 23349e39c5baSBill Taylor */ 23359e39c5baSBill Taylor /* ARGSUSED */ 23369e39c5baSBill Taylor static void 23379e39c5baSBill Taylor hermon_rsrc_refcnt_destructor(void *rc, void *priv) 23389e39c5baSBill Taylor { 23399e39c5baSBill Taylor hermon_sw_refcnt_t *refcnt; 23409e39c5baSBill Taylor 23419e39c5baSBill Taylor refcnt = (hermon_sw_refcnt_t *)rc; 23429e39c5baSBill Taylor 23439e39c5baSBill Taylor mutex_destroy(&refcnt->swrc_lock); 23449e39c5baSBill Taylor } 23459e39c5baSBill Taylor 23469e39c5baSBill Taylor 23479e39c5baSBill Taylor /* 23489e39c5baSBill Taylor * hermon_rsrc_ahhdl_constructor() 23499e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 23509e39c5baSBill Taylor */ 23519e39c5baSBill Taylor /* ARGSUSED */ 23529e39c5baSBill Taylor static int 23539e39c5baSBill Taylor hermon_rsrc_ahhdl_constructor(void *ah, void *priv, int flags) 23549e39c5baSBill Taylor { 23559e39c5baSBill Taylor hermon_ahhdl_t ahhdl; 23569e39c5baSBill Taylor hermon_state_t *state; 23579e39c5baSBill Taylor 23589e39c5baSBill Taylor ahhdl = (hermon_ahhdl_t)ah; 23599e39c5baSBill Taylor state = (hermon_state_t *)priv; 23609e39c5baSBill Taylor 23619e39c5baSBill Taylor mutex_init(&ahhdl->ah_lock, NULL, MUTEX_DRIVER, 23629e39c5baSBill Taylor DDI_INTR_PRI(state->hs_intrmsi_pri)); 23639e39c5baSBill Taylor return (DDI_SUCCESS); 23649e39c5baSBill Taylor } 23659e39c5baSBill Taylor 23669e39c5baSBill Taylor 23679e39c5baSBill Taylor /* 23689e39c5baSBill Taylor * hermon_rsrc_ahhdl_destructor() 23699e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 23709e39c5baSBill Taylor */ 23719e39c5baSBill Taylor /* ARGSUSED */ 23729e39c5baSBill Taylor static void 23739e39c5baSBill Taylor hermon_rsrc_ahhdl_destructor(void *ah, void *priv) 23749e39c5baSBill Taylor { 23759e39c5baSBill Taylor hermon_ahhdl_t ahhdl; 23769e39c5baSBill Taylor 23779e39c5baSBill Taylor ahhdl = (hermon_ahhdl_t)ah; 23789e39c5baSBill Taylor 23799e39c5baSBill Taylor mutex_destroy(&ahhdl->ah_lock); 23809e39c5baSBill Taylor } 23819e39c5baSBill Taylor 23829e39c5baSBill Taylor 23839e39c5baSBill Taylor /* 23849e39c5baSBill Taylor * hermon_rsrc_mrhdl_constructor() 23859e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 23869e39c5baSBill Taylor */ 23879e39c5baSBill Taylor /* ARGSUSED */ 23889e39c5baSBill Taylor static int 23899e39c5baSBill Taylor hermon_rsrc_mrhdl_constructor(void *mr, void *priv, int flags) 23909e39c5baSBill Taylor { 23919e39c5baSBill Taylor hermon_mrhdl_t mrhdl; 23929e39c5baSBill Taylor hermon_state_t *state; 23939e39c5baSBill Taylor 23949e39c5baSBill Taylor mrhdl = (hermon_mrhdl_t)mr; 23959e39c5baSBill Taylor state = (hermon_state_t *)priv; 23969e39c5baSBill Taylor 23979e39c5baSBill Taylor mutex_init(&mrhdl->mr_lock, NULL, MUTEX_DRIVER, 23989e39c5baSBill Taylor DDI_INTR_PRI(state->hs_intrmsi_pri)); 23999e39c5baSBill Taylor 24009e39c5baSBill Taylor return (DDI_SUCCESS); 24019e39c5baSBill Taylor } 24029e39c5baSBill Taylor 24039e39c5baSBill Taylor 24049e39c5baSBill Taylor /* 24059e39c5baSBill Taylor * hermon_rsrc_mrhdl_destructor() 24069e39c5baSBill Taylor * Context: Can be called from interrupt or base context. 24079e39c5baSBill Taylor */ 24089e39c5baSBill Taylor /* ARGSUSED */ 24099e39c5baSBill Taylor static void 24109e39c5baSBill Taylor hermon_rsrc_mrhdl_destructor(void *mr, void *priv) 24119e39c5baSBill Taylor { 24129e39c5baSBill Taylor hermon_mrhdl_t mrhdl; 24139e39c5baSBill Taylor 24149e39c5baSBill Taylor mrhdl = (hermon_mrhdl_t)mr; 24159e39c5baSBill Taylor 24169e39c5baSBill Taylor mutex_destroy(&mrhdl->mr_lock); 24179e39c5baSBill Taylor } 24189e39c5baSBill Taylor 24199e39c5baSBill Taylor 24209e39c5baSBill Taylor /* 24219e39c5baSBill Taylor * hermon_rsrc_mcg_entry_get_size() 24229e39c5baSBill Taylor */ 24239e39c5baSBill Taylor static int 24249e39c5baSBill Taylor hermon_rsrc_mcg_entry_get_size(hermon_state_t *state, uint_t *mcg_size_shift) 24259e39c5baSBill Taylor { 24269e39c5baSBill Taylor uint_t num_qp_per_mcg, max_qp_per_mcg, log2; 24279e39c5baSBill Taylor 24289e39c5baSBill Taylor /* 24299e39c5baSBill Taylor * Round the configured number of QP per MCG to next larger 24309e39c5baSBill Taylor * power-of-2 size and update. 24319e39c5baSBill Taylor */ 24329e39c5baSBill Taylor num_qp_per_mcg = state->hs_cfg_profile->cp_num_qp_per_mcg + 8; 24339e39c5baSBill Taylor log2 = highbit(num_qp_per_mcg); 24349e39c5baSBill Taylor if ((num_qp_per_mcg & (num_qp_per_mcg - 1)) == 0) { 24359e39c5baSBill Taylor log2 = log2 - 1; 24369e39c5baSBill Taylor } 24379e39c5baSBill Taylor state->hs_cfg_profile->cp_num_qp_per_mcg = (1 << log2) - 8; 24389e39c5baSBill Taylor 24399e39c5baSBill Taylor /* Now make sure number of QP per MCG makes sense */ 24409e39c5baSBill Taylor num_qp_per_mcg = state->hs_cfg_profile->cp_num_qp_per_mcg; 24419e39c5baSBill Taylor max_qp_per_mcg = (1 << state->hs_devlim.log_max_qp_mcg); 24429e39c5baSBill Taylor if (num_qp_per_mcg > max_qp_per_mcg) { 24439e39c5baSBill Taylor return (DDI_FAILURE); 24449e39c5baSBill Taylor } 24459e39c5baSBill Taylor 24469e39c5baSBill Taylor /* Return the (shift) size of an individual MCG HW entry */ 24479e39c5baSBill Taylor *mcg_size_shift = log2 + 2; 24489e39c5baSBill Taylor 24499e39c5baSBill Taylor return (DDI_SUCCESS); 24509e39c5baSBill Taylor } 2451