19517SBill.Taylor@Sun.COM /*
29517SBill.Taylor@Sun.COM * CDDL HEADER START
39517SBill.Taylor@Sun.COM *
49517SBill.Taylor@Sun.COM * The contents of this file are subject to the terms of the
59517SBill.Taylor@Sun.COM * Common Development and Distribution License (the "License").
69517SBill.Taylor@Sun.COM * You may not use this file except in compliance with the License.
79517SBill.Taylor@Sun.COM *
89517SBill.Taylor@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99517SBill.Taylor@Sun.COM * or http://www.opensolaris.org/os/licensing.
109517SBill.Taylor@Sun.COM * See the License for the specific language governing permissions
119517SBill.Taylor@Sun.COM * and limitations under the License.
129517SBill.Taylor@Sun.COM *
139517SBill.Taylor@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
149517SBill.Taylor@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159517SBill.Taylor@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
169517SBill.Taylor@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
179517SBill.Taylor@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
189517SBill.Taylor@Sun.COM *
199517SBill.Taylor@Sun.COM * CDDL HEADER END
209517SBill.Taylor@Sun.COM */
219517SBill.Taylor@Sun.COM
229517SBill.Taylor@Sun.COM /*
2312965SWilliam.Taylor@Oracle.COM * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
249517SBill.Taylor@Sun.COM */
259517SBill.Taylor@Sun.COM
269517SBill.Taylor@Sun.COM /*
279517SBill.Taylor@Sun.COM * hermon_cfg.c
289517SBill.Taylor@Sun.COM * Hermon Configuration Profile Routines
299517SBill.Taylor@Sun.COM *
309517SBill.Taylor@Sun.COM * Implements the routines necessary for initializing and (later) tearing
319517SBill.Taylor@Sun.COM * down the list of Hermon configuration information.
329517SBill.Taylor@Sun.COM */
339517SBill.Taylor@Sun.COM
349517SBill.Taylor@Sun.COM #include <sys/types.h>
359517SBill.Taylor@Sun.COM #include <sys/conf.h>
369517SBill.Taylor@Sun.COM #include <sys/ddi.h>
379517SBill.Taylor@Sun.COM #include <sys/sunddi.h>
389517SBill.Taylor@Sun.COM #include <sys/modctl.h>
399517SBill.Taylor@Sun.COM #include <sys/bitmap.h>
409517SBill.Taylor@Sun.COM
419517SBill.Taylor@Sun.COM #include <sys/ib/adapters/hermon/hermon.h>
429517SBill.Taylor@Sun.COM
439517SBill.Taylor@Sun.COM /*
449517SBill.Taylor@Sun.COM * Below are the elements that make up the Hermon configuration profile.
459517SBill.Taylor@Sun.COM * For advanced users who wish to alter these values, this can be done via
469517SBill.Taylor@Sun.COM * the /etc/system file. By default, values are assigned to the number of
479517SBill.Taylor@Sun.COM * supported resources, either from the HCA's reported capacities or by
489517SBill.Taylor@Sun.COM * a by-design limit in the driver.
499517SBill.Taylor@Sun.COM */
509517SBill.Taylor@Sun.COM
519517SBill.Taylor@Sun.COM /* Number of supported QPs, CQs and SRQs */
529517SBill.Taylor@Sun.COM uint32_t hermon_log_num_qp = HERMON_NUM_QP_SHIFT;
539517SBill.Taylor@Sun.COM uint32_t hermon_log_num_cq = HERMON_NUM_CQ_SHIFT;
549517SBill.Taylor@Sun.COM uint32_t hermon_log_num_srq = HERMON_NUM_SRQ_SHIFT;
559517SBill.Taylor@Sun.COM
569517SBill.Taylor@Sun.COM /* Number of supported SGL per WQE for SQ/RQ, and for SRQ */
579517SBill.Taylor@Sun.COM /* XXX use the same for all queues if limitation in srq.h is resolved */
589517SBill.Taylor@Sun.COM uint32_t hermon_wqe_max_sgl = HERMON_NUM_SGL_PER_WQE;
599517SBill.Taylor@Sun.COM uint32_t hermon_srq_max_sgl = HERMON_SRQ_MAX_SGL;
609517SBill.Taylor@Sun.COM
619517SBill.Taylor@Sun.COM /* Maximum "responder resources" (in) and "initiator depth" (out) per QP */
629517SBill.Taylor@Sun.COM uint32_t hermon_log_num_rdb_per_qp = HERMON_LOG_NUM_RDB_PER_QP;
639517SBill.Taylor@Sun.COM
649517SBill.Taylor@Sun.COM /*
659517SBill.Taylor@Sun.COM * Number of multicast groups (MCGs), number of QP per MCG, and the number
669517SBill.Taylor@Sun.COM * of entries (from the total number) in the multicast group "hash table"
679517SBill.Taylor@Sun.COM */
689517SBill.Taylor@Sun.COM uint32_t hermon_log_num_mcg = HERMON_NUM_MCG_SHIFT;
699517SBill.Taylor@Sun.COM uint32_t hermon_num_qp_per_mcg = HERMON_NUM_QP_PER_MCG;
7010009SGiri.Adari@Sun.COM uint32_t hermon_log_num_mcg_hash = HERMON_NUM_MCG_HASH_SHIFT;
719517SBill.Taylor@Sun.COM
729517SBill.Taylor@Sun.COM /* Number of UD AVs */
739517SBill.Taylor@Sun.COM uint32_t hermon_log_num_ah = HERMON_NUM_AH_SHIFT;
749517SBill.Taylor@Sun.COM
759517SBill.Taylor@Sun.COM /* Number of EQs and their default size */
769517SBill.Taylor@Sun.COM uint32_t hermon_log_num_eq = HERMON_NUM_EQ_SHIFT;
779517SBill.Taylor@Sun.COM uint32_t hermon_log_eq_sz = HERMON_DEFAULT_EQ_SZ_SHIFT;
789517SBill.Taylor@Sun.COM
799517SBill.Taylor@Sun.COM /*
809517SBill.Taylor@Sun.COM * Number of supported MPTs, MTTs and also the maximum MPT size.
819517SBill.Taylor@Sun.COM */
829517SBill.Taylor@Sun.COM uint32_t hermon_log_num_mtt = HERMON_NUM_MTT_SHIFT;
839517SBill.Taylor@Sun.COM uint32_t hermon_log_num_dmpt = HERMON_NUM_DMPT_SHIFT;
849517SBill.Taylor@Sun.COM uint32_t hermon_log_max_mrw_sz = HERMON_MAX_MEM_MPT_SHIFT;
859517SBill.Taylor@Sun.COM
869517SBill.Taylor@Sun.COM /*
879517SBill.Taylor@Sun.COM * Number of supported UAR (User Access Regions) for this HCA.
889517SBill.Taylor@Sun.COM * We could in the future read in uar_sz from devlim, and thus
899517SBill.Taylor@Sun.COM * derive the number of UAR. Since this is derived from PAGESIZE,
909517SBill.Taylor@Sun.COM * however, this means that x86 systems would have twice as many
919517SBill.Taylor@Sun.COM * UARs as SPARC systems. Therefore for consistency's sake, we will
929517SBill.Taylor@Sun.COM * just use 1024 pages, which is the maximum on SPARC systems.
939517SBill.Taylor@Sun.COM */
949517SBill.Taylor@Sun.COM uint32_t hermon_log_num_uar = HERMON_NUM_UAR_SHIFT;
959517SBill.Taylor@Sun.COM
969517SBill.Taylor@Sun.COM /*
979517SBill.Taylor@Sun.COM * Number of remaps allowed for FMR before a sync is required. This value
989517SBill.Taylor@Sun.COM * determines how many times we can fmr_deregister() before the underlying fmr
999517SBill.Taylor@Sun.COM * framework places the region to wait for an MTT_SYNC operation, cleaning up
1009517SBill.Taylor@Sun.COM * the old mappings.
1019517SBill.Taylor@Sun.COM */
1029517SBill.Taylor@Sun.COM uint32_t hermon_fmr_num_remaps = HERMON_FMR_MAX_REMAPS;
1039517SBill.Taylor@Sun.COM
1049517SBill.Taylor@Sun.COM /*
1059517SBill.Taylor@Sun.COM * Number of supported Hermon mailboxes ("In" and "Out") and their maximum
1069517SBill.Taylor@Sun.COM * sizes, respectively
1079517SBill.Taylor@Sun.COM */
1089517SBill.Taylor@Sun.COM uint32_t hermon_log_num_inmbox = HERMON_NUM_MAILBOXES_SHIFT;
1099517SBill.Taylor@Sun.COM uint32_t hermon_log_num_outmbox = HERMON_NUM_MAILBOXES_SHIFT;
1109517SBill.Taylor@Sun.COM uint32_t hermon_log_inmbox_size = HERMON_MBOX_SIZE_SHIFT;
1119517SBill.Taylor@Sun.COM uint32_t hermon_log_outmbox_size = HERMON_MBOX_SIZE_SHIFT;
1129517SBill.Taylor@Sun.COM uint32_t hermon_log_num_intr_inmbox = HERMON_NUM_INTR_MAILBOXES_SHIFT;
1139517SBill.Taylor@Sun.COM uint32_t hermon_log_num_intr_outmbox = HERMON_NUM_INTR_MAILBOXES_SHIFT;
1149517SBill.Taylor@Sun.COM
1159517SBill.Taylor@Sun.COM /* Number of supported Protection Domains (PD) */
1169517SBill.Taylor@Sun.COM uint32_t hermon_log_num_pd = HERMON_NUM_PD_SHIFT;
1179517SBill.Taylor@Sun.COM
1189517SBill.Taylor@Sun.COM /*
1199517SBill.Taylor@Sun.COM * Number of total supported PKeys per PKey table (i.e.
1209517SBill.Taylor@Sun.COM * per port). Also the number of SGID per GID table.
1219517SBill.Taylor@Sun.COM */
1229517SBill.Taylor@Sun.COM uint32_t hermon_log_max_pkeytbl = HERMON_NUM_PKEYTBL_SHIFT;
1239517SBill.Taylor@Sun.COM uint32_t hermon_log_max_gidtbl = HERMON_NUM_GIDTBL_SHIFT;
1249517SBill.Taylor@Sun.COM
1259517SBill.Taylor@Sun.COM /* Maximum supported MTU and portwidth */
1269517SBill.Taylor@Sun.COM uint32_t hermon_max_mtu = HERMON_MAX_MTU;
1279517SBill.Taylor@Sun.COM uint32_t hermon_max_port_width = HERMON_MAX_PORT_WIDTH;
1289517SBill.Taylor@Sun.COM
1299517SBill.Taylor@Sun.COM /* Number of supported Virtual Lanes (VL) */
1309517SBill.Taylor@Sun.COM uint32_t hermon_max_vlcap = HERMON_MAX_VLCAP;
1319517SBill.Taylor@Sun.COM
1329517SBill.Taylor@Sun.COM /*
1339517SBill.Taylor@Sun.COM * Whether or not to use the built-in (i.e. in firmware) agents for QP0 and
1349517SBill.Taylor@Sun.COM * QP1, respectively.
1359517SBill.Taylor@Sun.COM */
1369891SRajkumar.Sivaprakasam@Sun.COM uint32_t hermon_qp0_agents_in_fw = 0;
1379517SBill.Taylor@Sun.COM uint32_t hermon_qp1_agents_in_fw = 0;
1389517SBill.Taylor@Sun.COM
1399517SBill.Taylor@Sun.COM /*
1409517SBill.Taylor@Sun.COM * Whether DMA mappings should bypass the PCI IOMMU or not.
1419517SBill.Taylor@Sun.COM * hermon_iommu_bypass is a global setting for all memory addresses.
1429517SBill.Taylor@Sun.COM */
1439517SBill.Taylor@Sun.COM uint32_t hermon_iommu_bypass = 1;
1449517SBill.Taylor@Sun.COM
1459517SBill.Taylor@Sun.COM /*
1469517SBill.Taylor@Sun.COM * Whether *DATA* buffers should be bound w/ Relaxed Ordering (RO) turned on
1479517SBill.Taylor@Sun.COM * via the SW workaround (HCAs don't support RO in HW). Defaulted on,
1489517SBill.Taylor@Sun.COM * though care must be taken w/ some Userland clients that *MAY* have
1499517SBill.Taylor@Sun.COM * peeked in the data to understand when data xfer was done - MPI does
1509517SBill.Taylor@Sun.COM * as an efficiency
1519517SBill.Taylor@Sun.COM */
1529517SBill.Taylor@Sun.COM
1539517SBill.Taylor@Sun.COM uint32_t hermon_kernel_data_ro = HERMON_RO_ENABLED; /* default */
1549517SBill.Taylor@Sun.COM uint32_t hermon_user_data_ro = HERMON_RO_ENABLED; /* default */
1559517SBill.Taylor@Sun.COM
1569517SBill.Taylor@Sun.COM /*
1579517SBill.Taylor@Sun.COM * Whether Hermon should use MSI (Message Signaled Interrupts), if available.
1589517SBill.Taylor@Sun.COM * Note: 0 indicates 'legacy interrupt', 1 indicates MSI (if available)
1599517SBill.Taylor@Sun.COM */
1609517SBill.Taylor@Sun.COM uint32_t hermon_use_msi_if_avail = 1;
1619517SBill.Taylor@Sun.COM
1629517SBill.Taylor@Sun.COM /*
1639517SBill.Taylor@Sun.COM * This is a patchable variable that determines the time we will wait after
1649517SBill.Taylor@Sun.COM * initiating SW reset before we do our first read from Hermon config space.
1659517SBill.Taylor@Sun.COM * If this value is set too small (less than the default 100ms), it is
1669517SBill.Taylor@Sun.COM * possible for Hermon hardware to be unready to respond to the config cycle
1679517SBill.Taylor@Sun.COM * reads. This could cause master abort on the PCI bridge. Note: If
1689517SBill.Taylor@Sun.COM * "hermon_sw_reset_delay" is set to zero, then no software reset of the Hermon
1699517SBill.Taylor@Sun.COM * device will be attempted.
1709517SBill.Taylor@Sun.COM */
1719517SBill.Taylor@Sun.COM uint32_t hermon_sw_reset_delay = HERMON_SW_RESET_DELAY;
1729517SBill.Taylor@Sun.COM
1739517SBill.Taylor@Sun.COM /*
1749517SBill.Taylor@Sun.COM * These are patchable variables for hermon command polling. The poll_delay is
1759517SBill.Taylor@Sun.COM * the number of usec to wait in-between calls to poll the 'go' bit. The
1769517SBill.Taylor@Sun.COM * poll_max is the total number of usec to loop in waiting for the 'go' bit to
1779517SBill.Taylor@Sun.COM * clear.
1789517SBill.Taylor@Sun.COM */
1799517SBill.Taylor@Sun.COM uint32_t hermon_cmd_poll_delay = HERMON_CMD_POLL_DELAY;
1809517SBill.Taylor@Sun.COM uint32_t hermon_cmd_poll_max = HERMON_CMD_POLL_MAX;
1819517SBill.Taylor@Sun.COM
1829517SBill.Taylor@Sun.COM /*
1839517SBill.Taylor@Sun.COM * This is a patchable variable that determines the frequency with which
1849517SBill.Taylor@Sun.COM * the AckReq bit will be set in outgoing RC packets. The AckReq bit will be
1859517SBill.Taylor@Sun.COM * set in at least every 2^hermon_qp_ackreq_freq packets (but at least once
1869517SBill.Taylor@Sun.COM * per message, i.e. in the last packet). Tuning this value can increase
1879517SBill.Taylor@Sun.COM * IB fabric utilization by cutting down on the number of unnecessary ACKs.
1889517SBill.Taylor@Sun.COM */
1899517SBill.Taylor@Sun.COM uint32_t hermon_qp_ackreq_freq = HERMON_QP_ACKREQ_FREQ;
1909517SBill.Taylor@Sun.COM
1919517SBill.Taylor@Sun.COM static void hermon_cfg_wqe_sizes(hermon_state_t *state,
1929517SBill.Taylor@Sun.COM hermon_cfg_profile_t *cp);
1939517SBill.Taylor@Sun.COM #ifdef __sparc
1949517SBill.Taylor@Sun.COM static void hermon_check_iommu_bypass(hermon_state_t *state,
1959517SBill.Taylor@Sun.COM hermon_cfg_profile_t *cp);
1969517SBill.Taylor@Sun.COM #endif
1979517SBill.Taylor@Sun.COM
1989517SBill.Taylor@Sun.COM /*
1999517SBill.Taylor@Sun.COM * hermon_cfg_profile_init_phase1()
2009517SBill.Taylor@Sun.COM * Context: Only called from attach() path context
2019517SBill.Taylor@Sun.COM */
2029517SBill.Taylor@Sun.COM int
hermon_cfg_profile_init_phase1(hermon_state_t * state)2039517SBill.Taylor@Sun.COM hermon_cfg_profile_init_phase1(hermon_state_t *state)
2049517SBill.Taylor@Sun.COM {
2059517SBill.Taylor@Sun.COM hermon_cfg_profile_t *cp;
2069517SBill.Taylor@Sun.COM
2079517SBill.Taylor@Sun.COM /*
2089517SBill.Taylor@Sun.COM * Allocate space for the configuration profile structure
2099517SBill.Taylor@Sun.COM */
2109517SBill.Taylor@Sun.COM cp = (hermon_cfg_profile_t *)kmem_zalloc(sizeof (hermon_cfg_profile_t),
2119517SBill.Taylor@Sun.COM KM_SLEEP);
2129517SBill.Taylor@Sun.COM
2139517SBill.Taylor@Sun.COM /*
2149517SBill.Taylor@Sun.COM * Common to all profiles.
2159517SBill.Taylor@Sun.COM */
2169517SBill.Taylor@Sun.COM cp->cp_qp0_agents_in_fw = hermon_qp0_agents_in_fw;
2179517SBill.Taylor@Sun.COM cp->cp_qp1_agents_in_fw = hermon_qp1_agents_in_fw;
2189517SBill.Taylor@Sun.COM cp->cp_sw_reset_delay = hermon_sw_reset_delay;
2199517SBill.Taylor@Sun.COM cp->cp_cmd_poll_delay = hermon_cmd_poll_delay;
2209517SBill.Taylor@Sun.COM cp->cp_cmd_poll_max = hermon_cmd_poll_max;
2219517SBill.Taylor@Sun.COM cp->cp_ackreq_freq = hermon_qp_ackreq_freq;
2229517SBill.Taylor@Sun.COM cp->cp_fmr_max_remaps = hermon_fmr_num_remaps;
2239517SBill.Taylor@Sun.COM
2249517SBill.Taylor@Sun.COM /*
2259517SBill.Taylor@Sun.COM * Although most of the configuration is enabled in "phase2" of the
2269517SBill.Taylor@Sun.COM * cfg_profile_init, we have to setup the OUT mailboxes soon, since
2279517SBill.Taylor@Sun.COM * they are used immediately after this "phase1" completes, to run the
2289517SBill.Taylor@Sun.COM * firmware and get the device limits, which we'll need for 'phase2'.
2299517SBill.Taylor@Sun.COM * That's done in rsrc_init_phase1, called shortly after we do this
2309517SBill.Taylor@Sun.COM * and the sw reset - see hermon.c
2319517SBill.Taylor@Sun.COM */
2329517SBill.Taylor@Sun.COM if (state->hs_cfg_profile_setting == HERMON_CFG_MEMFREE) {
2339517SBill.Taylor@Sun.COM cp->cp_log_num_outmbox = hermon_log_num_outmbox;
2349517SBill.Taylor@Sun.COM cp->cp_log_outmbox_size = hermon_log_outmbox_size;
2359517SBill.Taylor@Sun.COM cp->cp_log_num_inmbox = hermon_log_num_inmbox;
2369517SBill.Taylor@Sun.COM cp->cp_log_inmbox_size = hermon_log_inmbox_size;
2379517SBill.Taylor@Sun.COM cp->cp_log_num_intr_inmbox = hermon_log_num_intr_inmbox;
2389517SBill.Taylor@Sun.COM cp->cp_log_num_intr_outmbox = hermon_log_num_intr_outmbox;
2399517SBill.Taylor@Sun.COM
2409517SBill.Taylor@Sun.COM } else {
2419517SBill.Taylor@Sun.COM return (DDI_FAILURE);
2429517SBill.Taylor@Sun.COM }
2439517SBill.Taylor@Sun.COM
24411972SBill.Taylor@Sun.COM /*
24511972SBill.Taylor@Sun.COM * Set IOMMU bypass or not. Ensure consistency of flags with
24611972SBill.Taylor@Sun.COM * architecture type.
24711972SBill.Taylor@Sun.COM */
24811972SBill.Taylor@Sun.COM #ifdef __sparc
24911972SBill.Taylor@Sun.COM if (hermon_iommu_bypass == 1) {
25011972SBill.Taylor@Sun.COM hermon_check_iommu_bypass(state, cp);
25111972SBill.Taylor@Sun.COM } else {
25211972SBill.Taylor@Sun.COM cp->cp_iommu_bypass = HERMON_BINDMEM_NORMAL;
25311972SBill.Taylor@Sun.COM }
25411972SBill.Taylor@Sun.COM #else
25511972SBill.Taylor@Sun.COM cp->cp_iommu_bypass = HERMON_BINDMEM_NORMAL;
25611972SBill.Taylor@Sun.COM #endif
25711972SBill.Taylor@Sun.COM
2589517SBill.Taylor@Sun.COM /* Attach the configuration profile to Hermon softstate */
2599517SBill.Taylor@Sun.COM state->hs_cfg_profile = cp;
2609517SBill.Taylor@Sun.COM
2619517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
2629517SBill.Taylor@Sun.COM }
2639517SBill.Taylor@Sun.COM
2649517SBill.Taylor@Sun.COM /*
2659517SBill.Taylor@Sun.COM * hermon_cfg_profile_init_phase2()
2669517SBill.Taylor@Sun.COM * Context: Only called from attach() path context
2679517SBill.Taylor@Sun.COM */
2689517SBill.Taylor@Sun.COM int
hermon_cfg_profile_init_phase2(hermon_state_t * state)2699517SBill.Taylor@Sun.COM hermon_cfg_profile_init_phase2(hermon_state_t *state)
2709517SBill.Taylor@Sun.COM {
2719517SBill.Taylor@Sun.COM hermon_cfg_profile_t *cp;
2729517SBill.Taylor@Sun.COM hermon_hw_querydevlim_t *devlim;
2739517SBill.Taylor@Sun.COM hermon_hw_query_port_t *port;
2749517SBill.Taylor@Sun.COM uint32_t num, size;
2759517SBill.Taylor@Sun.COM int i;
2769517SBill.Taylor@Sun.COM
2779517SBill.Taylor@Sun.COM /* Read in the device limits */
2789517SBill.Taylor@Sun.COM devlim = &state->hs_devlim;
2799517SBill.Taylor@Sun.COM /* and the port information */
2809517SBill.Taylor@Sun.COM port = &state->hs_queryport;
2819517SBill.Taylor@Sun.COM
2829517SBill.Taylor@Sun.COM /* Read the configuration profile */
2839517SBill.Taylor@Sun.COM cp = state->hs_cfg_profile;
2849517SBill.Taylor@Sun.COM
2859517SBill.Taylor@Sun.COM /*
2869517SBill.Taylor@Sun.COM * We configure all Hermon HCAs with the same profile, which
2879517SBill.Taylor@Sun.COM * is based upon the default value assignments above. If we want to
2889517SBill.Taylor@Sun.COM * add additional profiles in the future, they can be added here.
2899517SBill.Taylor@Sun.COM * Note the reference to "Memfree" is a holdover from Arbel/Sinai
2909517SBill.Taylor@Sun.COM */
2919517SBill.Taylor@Sun.COM if (state->hs_cfg_profile_setting != HERMON_CFG_MEMFREE) {
2929517SBill.Taylor@Sun.COM return (DDI_FAILURE);
2939517SBill.Taylor@Sun.COM }
2949517SBill.Taylor@Sun.COM
2959517SBill.Taylor@Sun.COM /*
2969517SBill.Taylor@Sun.COM * Note for most configuration parameters, we use the lesser of our
2979517SBill.Taylor@Sun.COM * desired configuration value or the device-defined maximum value.
2989517SBill.Taylor@Sun.COM */
2999517SBill.Taylor@Sun.COM cp->cp_log_num_mtt = min(hermon_log_num_mtt, devlim->log_max_mtt);
3009517SBill.Taylor@Sun.COM cp->cp_log_num_dmpt = min(hermon_log_num_dmpt, devlim->log_max_dmpt);
3019517SBill.Taylor@Sun.COM cp->cp_log_num_cmpt = HERMON_LOG_CMPT_PER_TYPE + 2; /* times 4, */
3029517SBill.Taylor@Sun.COM /* per PRM */
3039517SBill.Taylor@Sun.COM cp->cp_log_max_mrw_sz = min(hermon_log_max_mrw_sz,
3049517SBill.Taylor@Sun.COM devlim->log_max_mrw_sz);
3059517SBill.Taylor@Sun.COM cp->cp_log_num_pd = min(hermon_log_num_pd, devlim->log_max_pd);
3069517SBill.Taylor@Sun.COM cp->cp_log_num_qp = min(hermon_log_num_qp, devlim->log_max_qp);
3079517SBill.Taylor@Sun.COM cp->cp_log_num_cq = min(hermon_log_num_cq, devlim->log_max_cq);
3089517SBill.Taylor@Sun.COM cp->cp_log_num_srq = min(hermon_log_num_srq, devlim->log_max_srq);
3099517SBill.Taylor@Sun.COM cp->cp_log_num_eq = min(hermon_log_num_eq, devlim->log_max_eq);
3109517SBill.Taylor@Sun.COM cp->cp_log_eq_sz = min(hermon_log_eq_sz, devlim->log_max_eq_sz);
3119517SBill.Taylor@Sun.COM cp->cp_log_num_rdb = cp->cp_log_num_qp +
3129517SBill.Taylor@Sun.COM min(hermon_log_num_rdb_per_qp, devlim->log_max_ra_req_qp);
3139517SBill.Taylor@Sun.COM cp->cp_hca_max_rdma_in_qp = cp->cp_hca_max_rdma_out_qp =
3149517SBill.Taylor@Sun.COM 1 << min(hermon_log_num_rdb_per_qp, devlim->log_max_ra_req_qp);
31510009SGiri.Adari@Sun.COM cp->cp_num_qp_per_mcg = max(hermon_num_qp_per_mcg,
31610009SGiri.Adari@Sun.COM HERMON_NUM_QP_PER_MCG_MIN);
31710009SGiri.Adari@Sun.COM cp->cp_num_qp_per_mcg = min(cp->cp_num_qp_per_mcg,
31810009SGiri.Adari@Sun.COM (1 << devlim->log_max_qp_mcg) - 8);
31910009SGiri.Adari@Sun.COM cp->cp_num_qp_per_mcg = (1 << highbit(cp->cp_num_qp_per_mcg + 7)) - 8;
3209517SBill.Taylor@Sun.COM cp->cp_log_num_mcg = min(hermon_log_num_mcg, devlim->log_max_mcg);
3219517SBill.Taylor@Sun.COM cp->cp_log_num_mcg_hash = hermon_log_num_mcg_hash;
3229517SBill.Taylor@Sun.COM
3239517SBill.Taylor@Sun.COM /* until srq_resize is debugged, disable it */
3249517SBill.Taylor@Sun.COM cp->cp_srq_resize_enabled = 0;
3259517SBill.Taylor@Sun.COM
3269517SBill.Taylor@Sun.COM /* cp->cp_log_num_uar = hermon_log_num_uar; */
3279517SBill.Taylor@Sun.COM /*
3289517SBill.Taylor@Sun.COM * now, we HAVE to calculate the number of UAR pages, so that we can
3299517SBill.Taylor@Sun.COM * get the blueflame stuff correct as well
3309517SBill.Taylor@Sun.COM */
3319517SBill.Taylor@Sun.COM
3329517SBill.Taylor@Sun.COM size = devlim->log_max_uar_sz;
3339517SBill.Taylor@Sun.COM /* 1MB (2^^20) times size (2^^size) / sparc_pg (2^^13) */
3349517SBill.Taylor@Sun.COM num = (20 + size) - 13; /* XXX - consider using PAGESHIFT */
3359517SBill.Taylor@Sun.COM if (devlim->blu_flm)
3369517SBill.Taylor@Sun.COM num -= 1; /* if blueflame, only half the size for UARs */
3379517SBill.Taylor@Sun.COM cp->cp_log_num_uar = min(hermon_log_num_uar, num);
3389517SBill.Taylor@Sun.COM
3399517SBill.Taylor@Sun.COM
3409517SBill.Taylor@Sun.COM /* while we're at it, calculate the index of the kernel uar page */
3419517SBill.Taylor@Sun.COM /* either the reserved uar's or 128, whichever is smaller */
3429517SBill.Taylor@Sun.COM state->hs_kernel_uar_index = (devlim->num_rsvd_uar > 128) ?
3439517SBill.Taylor@Sun.COM devlim->num_rsvd_uar : 128;
3449517SBill.Taylor@Sun.COM
3459517SBill.Taylor@Sun.COM cp->cp_log_max_pkeytbl = port->log_max_pkey;
3469517SBill.Taylor@Sun.COM
3479517SBill.Taylor@Sun.COM cp->cp_log_max_qp_sz = devlim->log_max_qp_sz;
3489517SBill.Taylor@Sun.COM cp->cp_log_max_cq_sz = devlim->log_max_cq_sz;
3499517SBill.Taylor@Sun.COM cp->cp_log_max_srq_sz = devlim->log_max_srq_sz;
3509517SBill.Taylor@Sun.COM cp->cp_log_max_gidtbl = port->log_max_gid;
3519517SBill.Taylor@Sun.COM cp->cp_max_mtu = port->ib_mtu; /* XXX now from query_port */
3529517SBill.Taylor@Sun.COM cp->cp_max_port_width = port->ib_port_wid; /* now from query_port */
3539517SBill.Taylor@Sun.COM cp->cp_max_vlcap = port->max_vl;
35412965SWilliam.Taylor@Oracle.COM cp->cp_log_num_ah = hermon_log_num_ah;
35512965SWilliam.Taylor@Oracle.COM
35612965SWilliam.Taylor@Oracle.COM /* Paranoia, ensure no arrays indexed by port_num are out of bounds */
3579517SBill.Taylor@Sun.COM cp->cp_num_ports = devlim->num_ports;
35812965SWilliam.Taylor@Oracle.COM if (cp->cp_num_ports > HERMON_MAX_PORTS) {
35912965SWilliam.Taylor@Oracle.COM cmn_err(CE_CONT, "device has more ports (%d) than are "
36012965SWilliam.Taylor@Oracle.COM "supported; Using %d ports\n",
36112965SWilliam.Taylor@Oracle.COM cp->cp_num_ports, HERMON_MAX_PORTS);
36212965SWilliam.Taylor@Oracle.COM cp->cp_num_ports = HERMON_MAX_PORTS;
36312965SWilliam.Taylor@Oracle.COM };
3649517SBill.Taylor@Sun.COM
3659517SBill.Taylor@Sun.COM /* allocate variable sized arrays */
3669517SBill.Taylor@Sun.COM for (i = 0; i < HERMON_MAX_PORTS; i++) {
3679517SBill.Taylor@Sun.COM state->hs_pkey[i] = kmem_zalloc((1 << cp->cp_log_max_pkeytbl) *
3689517SBill.Taylor@Sun.COM sizeof (ib_pkey_t), KM_SLEEP);
3699517SBill.Taylor@Sun.COM state->hs_guid[i] = kmem_zalloc((1 << cp->cp_log_max_gidtbl) *
3709517SBill.Taylor@Sun.COM sizeof (ib_guid_t), KM_SLEEP);
3719517SBill.Taylor@Sun.COM }
3729517SBill.Taylor@Sun.COM
3739517SBill.Taylor@Sun.COM /* Determine WQE sizes from requested max SGLs */
3749517SBill.Taylor@Sun.COM hermon_cfg_wqe_sizes(state, cp);
3759517SBill.Taylor@Sun.COM
3769517SBill.Taylor@Sun.COM /* Set whether to use MSIs or not */
3779517SBill.Taylor@Sun.COM cp->cp_use_msi_if_avail = hermon_use_msi_if_avail;
3789517SBill.Taylor@Sun.COM
379*13121SWilliam.Taylor@Oracle.COM #if !defined(_ELF64)
380*13121SWilliam.Taylor@Oracle.COM /*
381*13121SWilliam.Taylor@Oracle.COM * Need to reduce the hermon kernel virtual memory footprint
382*13121SWilliam.Taylor@Oracle.COM * on 32-bit kernels.
383*13121SWilliam.Taylor@Oracle.COM */
384*13121SWilliam.Taylor@Oracle.COM cp->cp_log_num_mtt -= 6;
385*13121SWilliam.Taylor@Oracle.COM cp->cp_log_num_dmpt -= 6;
386*13121SWilliam.Taylor@Oracle.COM cp->cp_log_num_pd -= 6;
387*13121SWilliam.Taylor@Oracle.COM cp->cp_log_num_qp -= 6;
388*13121SWilliam.Taylor@Oracle.COM cp->cp_log_num_cq -= 6;
389*13121SWilliam.Taylor@Oracle.COM cp->cp_log_num_srq -= 6;
390*13121SWilliam.Taylor@Oracle.COM cp->cp_log_num_rdb = cp->cp_log_num_qp +
391*13121SWilliam.Taylor@Oracle.COM min(hermon_log_num_rdb_per_qp, devlim->log_max_ra_req_qp);
392*13121SWilliam.Taylor@Oracle.COM cp->cp_hca_max_rdma_in_qp = cp->cp_hca_max_rdma_out_qp =
393*13121SWilliam.Taylor@Oracle.COM 1 << min(hermon_log_num_rdb_per_qp, devlim->log_max_ra_req_qp);
394*13121SWilliam.Taylor@Oracle.COM #endif
395*13121SWilliam.Taylor@Oracle.COM
3969517SBill.Taylor@Sun.COM return (DDI_SUCCESS);
3979517SBill.Taylor@Sun.COM }
3989517SBill.Taylor@Sun.COM
3999517SBill.Taylor@Sun.COM
4009517SBill.Taylor@Sun.COM /*
4019517SBill.Taylor@Sun.COM * hermon_cfg_profile_fini()
4029517SBill.Taylor@Sun.COM * Context: Only called from attach() and/or detach() path contexts
4039517SBill.Taylor@Sun.COM */
4049517SBill.Taylor@Sun.COM void
hermon_cfg_profile_fini(hermon_state_t * state)4059517SBill.Taylor@Sun.COM hermon_cfg_profile_fini(hermon_state_t *state)
4069517SBill.Taylor@Sun.COM {
4079517SBill.Taylor@Sun.COM /*
4089517SBill.Taylor@Sun.COM * Free up the space for configuration profile
4099517SBill.Taylor@Sun.COM */
4109517SBill.Taylor@Sun.COM kmem_free(state->hs_cfg_profile, sizeof (hermon_cfg_profile_t));
4119517SBill.Taylor@Sun.COM }
4129517SBill.Taylor@Sun.COM
4139517SBill.Taylor@Sun.COM
4149517SBill.Taylor@Sun.COM /*
4159517SBill.Taylor@Sun.COM * hermon_cfg_wqe_sizes()
4169517SBill.Taylor@Sun.COM * Context: Only called from attach() path context
4179517SBill.Taylor@Sun.COM */
4189517SBill.Taylor@Sun.COM static void
hermon_cfg_wqe_sizes(hermon_state_t * state,hermon_cfg_profile_t * cp)4199517SBill.Taylor@Sun.COM hermon_cfg_wqe_sizes(hermon_state_t *state, hermon_cfg_profile_t *cp)
4209517SBill.Taylor@Sun.COM {
4219517SBill.Taylor@Sun.COM uint_t max_size, log2;
4229517SBill.Taylor@Sun.COM uint_t max_sgl, real_max_sgl;
4239517SBill.Taylor@Sun.COM
4249517SBill.Taylor@Sun.COM /*
4259517SBill.Taylor@Sun.COM * Get the requested maximum number SGL per WQE from the Hermon
4269517SBill.Taylor@Sun.COM * patchable variable
4279517SBill.Taylor@Sun.COM */
4289517SBill.Taylor@Sun.COM max_sgl = hermon_wqe_max_sgl;
4299517SBill.Taylor@Sun.COM
4309517SBill.Taylor@Sun.COM /*
4319517SBill.Taylor@Sun.COM * Use requested maximum number of SGL to calculate the max descriptor
4329517SBill.Taylor@Sun.COM * size (while guaranteeing that the descriptor size is a power-of-2
4339517SBill.Taylor@Sun.COM * cachelines). We have to use the calculation for QP1 MLX transport
4349517SBill.Taylor@Sun.COM * because the possibility that we might need to inline a GRH, along
4359517SBill.Taylor@Sun.COM * with all the other headers and alignment restrictions, sets the
4369517SBill.Taylor@Sun.COM * maximum for the number of SGLs that we can advertise support for.
4379517SBill.Taylor@Sun.COM */
4389517SBill.Taylor@Sun.COM max_size = (HERMON_QP_WQE_MLX_QP1_HDRS + (max_sgl << 4));
4399517SBill.Taylor@Sun.COM log2 = highbit(max_size);
4409517SBill.Taylor@Sun.COM if ((max_size & (max_size - 1)) == 0) {
4419517SBill.Taylor@Sun.COM log2 = log2 - 1;
4429517SBill.Taylor@Sun.COM }
4439517SBill.Taylor@Sun.COM max_size = (1 << log2);
4449517SBill.Taylor@Sun.COM
4459517SBill.Taylor@Sun.COM max_size = min(max_size, state->hs_devlim.max_desc_sz_sq);
4469517SBill.Taylor@Sun.COM
4479517SBill.Taylor@Sun.COM /*
4489517SBill.Taylor@Sun.COM * Then use the calculated max descriptor size to determine the "real"
4499517SBill.Taylor@Sun.COM * maximum SGL (the number beyond which we would roll over to the next
4509517SBill.Taylor@Sun.COM * power-of-2).
4519517SBill.Taylor@Sun.COM */
4529517SBill.Taylor@Sun.COM real_max_sgl = (max_size - HERMON_QP_WQE_MLX_QP1_HDRS) >> 4;
4539517SBill.Taylor@Sun.COM
4549517SBill.Taylor@Sun.COM /* Then save away this configuration information */
4559517SBill.Taylor@Sun.COM cp->cp_wqe_max_sgl = max_sgl;
4569517SBill.Taylor@Sun.COM cp->cp_wqe_real_max_sgl = real_max_sgl;
4579517SBill.Taylor@Sun.COM
4589517SBill.Taylor@Sun.COM /* SRQ SGL gets set to it's own patchable variable value */
4599517SBill.Taylor@Sun.COM cp->cp_srq_max_sgl = hermon_srq_max_sgl;
4609517SBill.Taylor@Sun.COM }
4619517SBill.Taylor@Sun.COM
4629517SBill.Taylor@Sun.COM #ifdef __sparc
4639517SBill.Taylor@Sun.COM /*
4649517SBill.Taylor@Sun.COM * hermon_check_iommu_bypass()
4659517SBill.Taylor@Sun.COM * Context: Only called from attach() path context
4669517SBill.Taylor@Sun.COM * XXX This is a DMA allocation routine outside the normal
4679517SBill.Taylor@Sun.COM * path. FMA hardening will not like this.
4689517SBill.Taylor@Sun.COM */
4699517SBill.Taylor@Sun.COM static void
hermon_check_iommu_bypass(hermon_state_t * state,hermon_cfg_profile_t * cp)4709517SBill.Taylor@Sun.COM hermon_check_iommu_bypass(hermon_state_t *state, hermon_cfg_profile_t *cp)
4719517SBill.Taylor@Sun.COM {
4729517SBill.Taylor@Sun.COM ddi_dma_handle_t dmahdl;
4739517SBill.Taylor@Sun.COM ddi_dma_attr_t dma_attr;
4749517SBill.Taylor@Sun.COM int status;
4759517SBill.Taylor@Sun.COM ddi_acc_handle_t acc_hdl;
4769517SBill.Taylor@Sun.COM caddr_t kaddr;
4779517SBill.Taylor@Sun.COM size_t actual_len;
4789517SBill.Taylor@Sun.COM ddi_dma_cookie_t cookie;
4799517SBill.Taylor@Sun.COM uint_t cookiecnt;
4809517SBill.Taylor@Sun.COM
4819517SBill.Taylor@Sun.COM hermon_dma_attr_init(state, &dma_attr);
4829517SBill.Taylor@Sun.COM
4839517SBill.Taylor@Sun.COM /* Try mapping for IOMMU bypass (Force Physical) */
4849517SBill.Taylor@Sun.COM dma_attr.dma_attr_flags = DDI_DMA_FORCE_PHYSICAL |
4859517SBill.Taylor@Sun.COM DDI_DMA_RELAXED_ORDERING;
4869517SBill.Taylor@Sun.COM
4879517SBill.Taylor@Sun.COM /*
4889517SBill.Taylor@Sun.COM * Call ddi_dma_alloc_handle(). If this returns DDI_DMA_BADATTR then
4899517SBill.Taylor@Sun.COM * it is not possible to use IOMMU bypass with our PCI bridge parent.
4909517SBill.Taylor@Sun.COM * Since the function we are in can only be called if iommu bypass was
4919517SBill.Taylor@Sun.COM * requested in the config profile, we configure for bypass if the
4929517SBill.Taylor@Sun.COM * ddi_dma_alloc_handle() was successful. Otherwise, we configure
4939517SBill.Taylor@Sun.COM * for non-bypass (ie: normal) mapping.
4949517SBill.Taylor@Sun.COM */
4959517SBill.Taylor@Sun.COM status = ddi_dma_alloc_handle(state->hs_dip, &dma_attr,
4969517SBill.Taylor@Sun.COM DDI_DMA_SLEEP, NULL, &dmahdl);
4979517SBill.Taylor@Sun.COM if (status == DDI_DMA_BADATTR) {
4989517SBill.Taylor@Sun.COM cp->cp_iommu_bypass = HERMON_BINDMEM_NORMAL;
4999517SBill.Taylor@Sun.COM return;
5009517SBill.Taylor@Sun.COM } else if (status != DDI_SUCCESS) { /* failed somehow */
5019517SBill.Taylor@Sun.COM hermon_kernel_data_ro = HERMON_RO_DISABLED;
5029517SBill.Taylor@Sun.COM hermon_user_data_ro = HERMON_RO_DISABLED;
5039517SBill.Taylor@Sun.COM cp->cp_iommu_bypass = HERMON_BINDMEM_BYPASS;
5049517SBill.Taylor@Sun.COM return;
5059517SBill.Taylor@Sun.COM } else {
5069517SBill.Taylor@Sun.COM cp->cp_iommu_bypass = HERMON_BINDMEM_BYPASS;
5079517SBill.Taylor@Sun.COM }
5089517SBill.Taylor@Sun.COM
5099517SBill.Taylor@Sun.COM status = ddi_dma_mem_alloc(dmahdl, 256,
5109517SBill.Taylor@Sun.COM &state->hs_reg_accattr, DDI_DMA_CONSISTENT,
5119517SBill.Taylor@Sun.COM DDI_DMA_SLEEP, NULL, (caddr_t *)&kaddr, &actual_len, &acc_hdl);
5129517SBill.Taylor@Sun.COM
5139517SBill.Taylor@Sun.COM if (status != DDI_SUCCESS) { /* failed somehow */
5149517SBill.Taylor@Sun.COM hermon_kernel_data_ro = HERMON_RO_DISABLED;
5159517SBill.Taylor@Sun.COM hermon_user_data_ro = HERMON_RO_DISABLED;
5169517SBill.Taylor@Sun.COM ddi_dma_free_handle(&dmahdl);
5179517SBill.Taylor@Sun.COM return;
5189517SBill.Taylor@Sun.COM }
5199517SBill.Taylor@Sun.COM
5209517SBill.Taylor@Sun.COM status = ddi_dma_addr_bind_handle(dmahdl, NULL, kaddr, actual_len,
5219517SBill.Taylor@Sun.COM DDI_DMA_RDWR, DDI_DMA_SLEEP, NULL, &cookie, &cookiecnt);
5229517SBill.Taylor@Sun.COM
5239517SBill.Taylor@Sun.COM if (status == DDI_DMA_MAPPED) {
5249517SBill.Taylor@Sun.COM (void) ddi_dma_unbind_handle(dmahdl);
5259517SBill.Taylor@Sun.COM } else {
5269517SBill.Taylor@Sun.COM hermon_kernel_data_ro = HERMON_RO_DISABLED;
5279517SBill.Taylor@Sun.COM hermon_user_data_ro = HERMON_RO_DISABLED;
5289517SBill.Taylor@Sun.COM }
5299517SBill.Taylor@Sun.COM
5309517SBill.Taylor@Sun.COM ddi_dma_mem_free(&acc_hdl);
5319517SBill.Taylor@Sun.COM ddi_dma_free_handle(&dmahdl);
5329517SBill.Taylor@Sun.COM }
5339517SBill.Taylor@Sun.COM #endif
534