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 /*
23c7facc54SBill 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 * tavor_cfg.c
299e39c5baSBill Taylor * Tavor Configuration Profile Routines
309e39c5baSBill Taylor *
319e39c5baSBill Taylor * Implements the routines necessary for initializing and (later) tearing
329e39c5baSBill Taylor * down the list of Tavor configuration information.
339e39c5baSBill Taylor */
349e39c5baSBill Taylor
35*de710d24SJosef 'Jeff' Sipek #include <sys/sysmacros.h>
369e39c5baSBill Taylor #include <sys/types.h>
379e39c5baSBill Taylor #include <sys/conf.h>
389e39c5baSBill Taylor #include <sys/ddi.h>
399e39c5baSBill Taylor #include <sys/sunddi.h>
409e39c5baSBill Taylor #include <sys/modctl.h>
419e39c5baSBill Taylor #include <sys/bitmap.h>
429e39c5baSBill Taylor
439e39c5baSBill Taylor #include <sys/ib/adapters/tavor/tavor.h>
449e39c5baSBill Taylor
459e39c5baSBill Taylor /* Set to enable alternative configurations: 0 = automatic config, 1 = manual */
469e39c5baSBill Taylor uint32_t tavor_alt_config_enable = 0;
479e39c5baSBill Taylor
489e39c5baSBill Taylor /* Number of supported QPs and their maximum size */
499e39c5baSBill Taylor uint32_t tavor_log_num_qp = TAVOR_NUM_QP_SHIFT_128;
509e39c5baSBill Taylor uint32_t tavor_log_max_qp_sz = TAVOR_QP_SZ_SHIFT;
519e39c5baSBill Taylor
529e39c5baSBill Taylor /* Number of supported SGL per WQE */
539e39c5baSBill Taylor uint32_t tavor_wqe_max_sgl = TAVOR_NUM_WQE_SGL;
549e39c5baSBill Taylor
559e39c5baSBill Taylor /* Number of supported CQs and their maximum size */
569e39c5baSBill Taylor uint32_t tavor_log_num_cq = TAVOR_NUM_CQ_SHIFT_128;
579e39c5baSBill Taylor uint32_t tavor_log_max_cq_sz = TAVOR_CQ_SZ_SHIFT;
589e39c5baSBill Taylor
599e39c5baSBill Taylor /* Select to enable SRQ or not; NOTE: 0 for disabled, 1 for enabled */
609e39c5baSBill Taylor uint32_t tavor_srq_enable = 1;
619e39c5baSBill Taylor
629e39c5baSBill Taylor /* Number of supported SRQs and their maximum size */
639e39c5baSBill Taylor uint32_t tavor_log_num_srq = TAVOR_NUM_SRQ_SHIFT_128;
649e39c5baSBill Taylor uint32_t tavor_log_max_srq_sz = TAVOR_SRQ_SZ_SHIFT;
659e39c5baSBill Taylor uint32_t tavor_srq_max_sgl = TAVOR_SRQ_MAX_SGL;
669e39c5baSBill Taylor
679e39c5baSBill Taylor /* Default size for all EQs */
689e39c5baSBill Taylor uint32_t tavor_log_default_eq_sz = TAVOR_DEFAULT_EQ_SZ_SHIFT;
699e39c5baSBill Taylor
709e39c5baSBill Taylor /* Number of supported RDB (for incoming RDMA Read/Atomic) */
719e39c5baSBill Taylor uint32_t tavor_log_num_rdb = TAVOR_NUM_RDB_SHIFT_128;
729e39c5baSBill Taylor
739e39c5baSBill Taylor /*
749e39c5baSBill Taylor * Number of support multicast groups, number of QP per multicast group, and
759e39c5baSBill Taylor * the number of entries (from the total number) in the multicast group "hash
769e39c5baSBill Taylor * table"
779e39c5baSBill Taylor */
789e39c5baSBill Taylor uint32_t tavor_log_num_mcg = TAVOR_NUM_MCG_SHIFT;
799e39c5baSBill Taylor uint32_t tavor_num_qp_per_mcg = TAVOR_NUM_QP_PER_MCG;
809e39c5baSBill Taylor uint32_t tavor_log_num_mcg_hash = TAVOR_NUM_MCG_HASH_SHIFT;
819e39c5baSBill Taylor
829e39c5baSBill Taylor /*
839e39c5baSBill Taylor * Number of supported MPTs (memory regions and windows) and their maximum
849e39c5baSBill Taylor * size. Also the number of MTT per "MTT segment" (see tavor_mr.h for more
859e39c5baSBill Taylor * details)
869e39c5baSBill Taylor */
879e39c5baSBill Taylor uint32_t tavor_log_num_mpt = TAVOR_NUM_MPT_SHIFT_128;
889e39c5baSBill Taylor uint32_t tavor_log_max_mrw_sz = TAVOR_MAX_MEM_MPT_SHIFT_128;
899e39c5baSBill Taylor uint32_t tavor_log_num_mttseg = TAVOR_NUM_MTTSEG_SHIFT;
909e39c5baSBill Taylor
919e39c5baSBill Taylor /*
929e39c5baSBill Taylor * Number of supported Tavor mailboxes ("In" and "Out") and their maximum
939e39c5baSBill Taylor * sizes, respectively
949e39c5baSBill Taylor */
959e39c5baSBill Taylor uint32_t tavor_log_num_inmbox = TAVOR_NUM_MAILBOXES_SHIFT;
969e39c5baSBill Taylor uint32_t tavor_log_num_outmbox = TAVOR_NUM_MAILBOXES_SHIFT;
979e39c5baSBill Taylor uint32_t tavor_log_num_intr_inmbox = TAVOR_NUM_INTR_MAILBOXES_SHIFT;
989e39c5baSBill Taylor uint32_t tavor_log_num_intr_outmbox = TAVOR_NUM_INTR_MAILBOXES_SHIFT;
999e39c5baSBill Taylor uint32_t tavor_log_inmbox_size = TAVOR_MBOX_SIZE_SHIFT;
1009e39c5baSBill Taylor uint32_t tavor_log_outmbox_size = TAVOR_MBOX_SIZE_SHIFT;
1019e39c5baSBill Taylor
1029e39c5baSBill Taylor /* Number of supported UAR pages */
1039e39c5baSBill Taylor uint32_t tavor_log_num_uar = TAVOR_NUM_UAR_SHIFT;
1049e39c5baSBill Taylor
1059e39c5baSBill Taylor /* Number of supported Protection Domains (PD) */
1069e39c5baSBill Taylor uint32_t tavor_log_num_pd = TAVOR_NUM_PD_SHIFT;
1079e39c5baSBill Taylor
1089e39c5baSBill Taylor /* Number of supported Address Handles (AH) */
1099e39c5baSBill Taylor uint32_t tavor_log_num_ah = TAVOR_NUM_AH_SHIFT;
1109e39c5baSBill Taylor
1119e39c5baSBill Taylor /*
1129e39c5baSBill Taylor * Number of total supported PKeys per PKey table (i.e.
1139e39c5baSBill Taylor * per port). Also the number of SGID per GID table.
1149e39c5baSBill Taylor */
1159e39c5baSBill Taylor uint32_t tavor_log_max_pkeytbl = TAVOR_NUM_PKEYTBL_SHIFT;
1169e39c5baSBill Taylor uint32_t tavor_log_max_gidtbl = TAVOR_NUM_GIDTBL_SHIFT;
1179e39c5baSBill Taylor
1189e39c5baSBill Taylor /* Maximum "responder resources" (in) and "initiator depth" (out) per QP */
1199e39c5baSBill Taylor uint32_t tavor_hca_max_rdma_in_qp = TAVOR_HCA_MAX_RDMA_IN_QP;
1209e39c5baSBill Taylor uint32_t tavor_hca_max_rdma_out_qp = TAVOR_HCA_MAX_RDMA_OUT_QP;
1219e39c5baSBill Taylor
1229e39c5baSBill Taylor /* Maximum supported MTU and portwidth */
1239e39c5baSBill Taylor uint32_t tavor_max_mtu = TAVOR_MAX_MTU;
1249e39c5baSBill Taylor uint32_t tavor_max_port_width = TAVOR_MAX_PORT_WIDTH;
1259e39c5baSBill Taylor
1269e39c5baSBill Taylor /* Number of supported Virtual Lanes (VL) */
1279e39c5baSBill Taylor uint32_t tavor_max_vlcap = TAVOR_MAX_VLCAP;
1289e39c5baSBill Taylor
1299e39c5baSBill Taylor /* Number of supported ports (1 or 2) */
1309e39c5baSBill Taylor uint32_t tavor_num_ports = TAVOR_NUM_PORTS;
1319e39c5baSBill Taylor
1329e39c5baSBill Taylor /*
1339e39c5baSBill Taylor * Whether or not to use the built-in (i.e. in firmware) agents for QP0 and
1349e39c5baSBill Taylor * QP1, respectively.
1359e39c5baSBill Taylor */
1369e39c5baSBill Taylor uint32_t tavor_qp0_agents_in_fw = 1;
1379e39c5baSBill Taylor uint32_t tavor_qp1_agents_in_fw = 0;
1389e39c5baSBill Taylor
1399e39c5baSBill Taylor /*
1409e39c5baSBill Taylor * Whether DMA mappings should be made with DDI_DMA_STREAMING or with
1419e39c5baSBill Taylor * DDI_DMA_CONSISTENT mode. Note: 0 for "streaming", 1 for "consistent"
1429e39c5baSBill Taylor */
1439e39c5baSBill Taylor uint32_t tavor_streaming_consistent = 1;
1449e39c5baSBill Taylor
1459e39c5baSBill Taylor /*
1469e39c5baSBill Taylor * For DMA mappings made with DDI_DMA_CONSISTENT, this flag determines
1479e39c5baSBill Taylor * whether to override the necessity for calls to ddi_dma_sync().
1489e39c5baSBill Taylor */
1499e39c5baSBill Taylor uint32_t tavor_consistent_syncoverride = 0;
1509e39c5baSBill Taylor
1519e39c5baSBill Taylor /*
1529e39c5baSBill Taylor * Whether DMA mappings should bypass the PCI IOMMU or not.
1539e39c5baSBill Taylor * tavor_iommu_bypass is a global setting for all memory addresses. However,
1549e39c5baSBill Taylor * if set to BYPASS, memory attempted to be registered for streaming (ie:
1559e39c5baSBill Taylor * NON-COHERENT) will necessarily turn off BYPASS for that registration. To
1569e39c5baSBill Taylor * instead disable streaming in this situation the
1579e39c5baSBill Taylor * 'tavor_disable_streaming_on_bypass' can be set to 1. This setting will
1589e39c5baSBill Taylor * change the memory mapping to be implicitly consistent (ie: COHERENT), and
1599e39c5baSBill Taylor * will still perform the iommu BYPASS operation.
1609e39c5baSBill Taylor */
1619e39c5baSBill Taylor uint32_t tavor_iommu_bypass = 1;
1629e39c5baSBill Taylor uint32_t tavor_disable_streaming_on_bypass = 0;
1639e39c5baSBill Taylor
1649e39c5baSBill Taylor /*
1659e39c5baSBill Taylor * Whether QP work queues should be allocated from system memory or
1669e39c5baSBill Taylor * from Tavor DDR memory. Note: 0 for system memory, 1 for DDR memory
1679e39c5baSBill Taylor */
1689e39c5baSBill Taylor uint32_t tavor_qp_wq_inddr = 0;
1699e39c5baSBill Taylor
1709e39c5baSBill Taylor /*
1719e39c5baSBill Taylor * Whether SRQ work queues should be allocated from system memory or
1729e39c5baSBill Taylor * from Tavor DDR memory. Note: 0 for system memory, 1 for DDR memory
1739e39c5baSBill Taylor */
1749e39c5baSBill Taylor uint32_t tavor_srq_wq_inddr = 0;
1759e39c5baSBill Taylor
1769e39c5baSBill Taylor /*
1779e39c5baSBill Taylor * Whether Tavor should use MSI (Message Signaled Interrupts), if available.
1789e39c5baSBill Taylor * Note: 0 indicates 'legacy interrupt', 1 indicates MSI (if available)
1799e39c5baSBill Taylor */
1809e39c5baSBill Taylor uint32_t tavor_use_msi_if_avail = 1;
1819e39c5baSBill Taylor
1829e39c5baSBill Taylor /*
1839e39c5baSBill Taylor * This is a patchable variable that determines the time we will wait after
1849e39c5baSBill Taylor * initiating SW reset before we do our first read from Tavor config space.
1859e39c5baSBill Taylor * If this value is set too small (less than the default 100ms), it is
1869e39c5baSBill Taylor * possible for Tavor hardware to be unready to respond to the config cycle
1879e39c5baSBill Taylor * reads. This could cause master abort on the PCI bridge. Note: If
1889e39c5baSBill Taylor * "tavor_sw_reset_delay" is set to zero, then no software reset of the Tavor
1899e39c5baSBill Taylor * device will be attempted.
1909e39c5baSBill Taylor */
1919e39c5baSBill Taylor uint32_t tavor_sw_reset_delay = TAVOR_SW_RESET_DELAY;
1929e39c5baSBill Taylor
1939e39c5baSBill Taylor /*
1949e39c5baSBill Taylor * These are patchable variables for tavor command polling. The poll_delay is
1959e39c5baSBill Taylor * the number of usec to wait in-between calls to poll the 'go' bit. The
1969e39c5baSBill Taylor * poll_max is the total number of usec to loop in waiting for the 'go' bit to
1979e39c5baSBill Taylor * clear.
1989e39c5baSBill Taylor */
1999e39c5baSBill Taylor uint32_t tavor_cmd_poll_delay = TAVOR_CMD_POLL_DELAY;
2009e39c5baSBill Taylor uint32_t tavor_cmd_poll_max = TAVOR_CMD_POLL_MAX;
2019e39c5baSBill Taylor
2029e39c5baSBill Taylor /*
2039e39c5baSBill Taylor * This is a patchable variable that determines the frequency with which
2049e39c5baSBill Taylor * the AckReq bit will be set in outgoing RC packets. The AckReq bit will be
2059e39c5baSBill Taylor * set in at least every 2^tavor_qp_ackreq_freq packets (but at least once
2069e39c5baSBill Taylor * per message, i.e. in the last packet). Tuning this value can increase
2079e39c5baSBill Taylor * IB fabric utilization by cutting down on the number of unnecessary ACKs.
2089e39c5baSBill Taylor */
2099e39c5baSBill Taylor uint32_t tavor_qp_ackreq_freq = TAVOR_QP_ACKREQ_FREQ;
2109e39c5baSBill Taylor
2119e39c5baSBill Taylor /*
2129e39c5baSBill Taylor * This is a patchable variable that determines the default value for the
2139e39c5baSBill Taylor * maximum number of outstanding split transactions. The number of
2149e39c5baSBill Taylor * outstanding split transations (i.e. PCI reads) has an affect on device
2159e39c5baSBill Taylor * throughput. The value here should not be modified as it defines the
2169e39c5baSBill Taylor * default (least common denominator - one (1) PCI read) behavior that is
2179e39c5baSBill Taylor * guaranteed to work, regardless of how the Tavor firmware has been
2189e39c5baSBill Taylor * initialized. The format for this variable is the same as the corresponding
2199e39c5baSBill Taylor * field in the "PCI-X Command Register".
2209e39c5baSBill Taylor */
2219e39c5baSBill Taylor #ifdef __sparc
2229e39c5baSBill Taylor /*
2239e39c5baSBill Taylor * Default SPARC platforms to be 1 outstanding PCI read.
2249e39c5baSBill Taylor */
2259e39c5baSBill Taylor int tavor_max_out_splt_trans = 0;
2269e39c5baSBill Taylor #else
2279e39c5baSBill Taylor /*
2289e39c5baSBill Taylor * Default non-SPARC platforms to be the default as set in tavor firmware
2299e39c5baSBill Taylor * number of outstanding PCI reads.
2309e39c5baSBill Taylor */
2319e39c5baSBill Taylor int tavor_max_out_splt_trans = -1;
2329e39c5baSBill Taylor #endif
2339e39c5baSBill Taylor
2349e39c5baSBill Taylor /*
2359e39c5baSBill Taylor * This is a patchable variable that determines the default value for the
2369e39c5baSBill Taylor * maximum size of PCI read burst. This maximum size has an affect on
2379e39c5baSBill Taylor * device throughput. The value here should not be modified as it defines
2389e39c5baSBill Taylor * the default (least common denominator - 512B read) behavior that is
2399e39c5baSBill Taylor * guaranteed to work, regardless of how the Tavor device has been
2409e39c5baSBill Taylor * initialized. The format for this variable is the same as the corresponding
2419e39c5baSBill Taylor * field in the "PCI-X Command Register".
2429e39c5baSBill Taylor */
2439e39c5baSBill Taylor #ifdef __sparc
2449e39c5baSBill Taylor /*
2459e39c5baSBill Taylor * Default SPARC platforms to be 512B read.
2469e39c5baSBill Taylor */
2479e39c5baSBill Taylor int tavor_max_mem_rd_byte_cnt = 0;
2489e39c5baSBill Taylor static void tavor_check_iommu_bypass(tavor_state_t *state,
2499e39c5baSBill Taylor tavor_cfg_profile_t *cp);
2509e39c5baSBill Taylor #else
2519e39c5baSBill Taylor /*
2529e39c5baSBill Taylor * Default non-SPARC platforms to be the default as set in tavor firmware.
2539e39c5baSBill Taylor *
2549e39c5baSBill Taylor */
2559e39c5baSBill Taylor int tavor_max_mem_rd_byte_cnt = -1;
2569e39c5baSBill Taylor #endif
2579e39c5baSBill Taylor
2589e39c5baSBill Taylor static void tavor_cfg_wqe_sizes(tavor_cfg_profile_t *cp);
2599e39c5baSBill Taylor static void tavor_cfg_prop_lookup(tavor_state_t *state,
2609e39c5baSBill Taylor tavor_cfg_profile_t *cp);
2619e39c5baSBill Taylor
2629e39c5baSBill Taylor /*
2639e39c5baSBill Taylor * tavor_cfg_profile_init_phase1()
2649e39c5baSBill Taylor * Context: Only called from attach() path context
2659e39c5baSBill Taylor */
2669e39c5baSBill Taylor int
tavor_cfg_profile_init_phase1(tavor_state_t * state)2679e39c5baSBill Taylor tavor_cfg_profile_init_phase1(tavor_state_t *state)
2689e39c5baSBill Taylor {
2699e39c5baSBill Taylor tavor_cfg_profile_t *cp;
2709e39c5baSBill Taylor
2719e39c5baSBill Taylor /*
2729e39c5baSBill Taylor * Allocate space for the configuration profile structure
2739e39c5baSBill Taylor */
2749e39c5baSBill Taylor cp = (tavor_cfg_profile_t *)kmem_zalloc(sizeof (tavor_cfg_profile_t),
2759e39c5baSBill Taylor KM_SLEEP);
2769e39c5baSBill Taylor
2779e39c5baSBill Taylor cp->cp_qp0_agents_in_fw = tavor_qp0_agents_in_fw;
2789e39c5baSBill Taylor cp->cp_qp1_agents_in_fw = tavor_qp1_agents_in_fw;
2799e39c5baSBill Taylor cp->cp_sw_reset_delay = tavor_sw_reset_delay;
2809e39c5baSBill Taylor cp->cp_cmd_poll_delay = tavor_cmd_poll_delay;
2819e39c5baSBill Taylor cp->cp_cmd_poll_max = tavor_cmd_poll_max;
2829e39c5baSBill Taylor cp->cp_ackreq_freq = tavor_qp_ackreq_freq;
2839e39c5baSBill Taylor cp->cp_max_out_splt_trans = tavor_max_out_splt_trans;
2849e39c5baSBill Taylor cp->cp_max_mem_rd_byte_cnt = tavor_max_mem_rd_byte_cnt;
2859e39c5baSBill Taylor cp->cp_srq_enable = tavor_srq_enable;
286c7facc54SBill Taylor cp->cp_fmr_enable = 0;
287c7facc54SBill Taylor cp->cp_fmr_max_remaps = 0;
2889e39c5baSBill Taylor
2899e39c5baSBill Taylor /*
2909e39c5baSBill Taylor * Although most of the configuration is enabled in "phase2" of the
2919e39c5baSBill Taylor * cfg_profile_init, we have to setup the OUT mailboxes here, since
2929e39c5baSBill Taylor * they are used immediately after this "phase1" completes. Check for
2939e39c5baSBill Taylor * alt_config_enable, and set the values appropriately. Otherwise, the
2949e39c5baSBill Taylor * config profile is setup using the values based on the dimm size.
2959e39c5baSBill Taylor * While it is expected that the mailbox size and number will remain
2969e39c5baSBill Taylor * the same independent of dimm size, we separate it out here anyway
2979e39c5baSBill Taylor * for completeness.
2989e39c5baSBill Taylor *
2999e39c5baSBill Taylor * We have to setup SRQ settings here because MOD_STAT_CFG must be
3009e39c5baSBill Taylor * called before our call to QUERY_DEVLIM. If SRQ is enabled, then we
3019e39c5baSBill Taylor * must enable it in the firmware so that the phase2 settings will have
3029e39c5baSBill Taylor * the right device limits.
3039e39c5baSBill Taylor */
3049e39c5baSBill Taylor if (tavor_alt_config_enable) {
3059e39c5baSBill Taylor cp->cp_log_num_outmbox = tavor_log_num_outmbox;
3069e39c5baSBill Taylor cp->cp_log_num_intr_outmbox = tavor_log_num_intr_outmbox;
3079e39c5baSBill Taylor cp->cp_log_outmbox_size = tavor_log_outmbox_size;
3089e39c5baSBill Taylor cp->cp_log_num_inmbox = tavor_log_num_inmbox;
3099e39c5baSBill Taylor cp->cp_log_num_intr_inmbox = tavor_log_num_intr_inmbox;
3109e39c5baSBill Taylor cp->cp_log_inmbox_size = tavor_log_inmbox_size;
3119e39c5baSBill Taylor cp->cp_log_num_srq = tavor_log_num_srq;
3129e39c5baSBill Taylor cp->cp_log_max_srq_sz = tavor_log_max_srq_sz;
3139e39c5baSBill Taylor
3149e39c5baSBill Taylor } else if (state->ts_cfg_profile_setting >= TAVOR_DDR_SIZE_256) {
3159e39c5baSBill Taylor cp->cp_log_num_outmbox = TAVOR_NUM_MAILBOXES_SHIFT;
3169e39c5baSBill Taylor cp->cp_log_num_intr_outmbox =
3179e39c5baSBill Taylor TAVOR_NUM_INTR_MAILBOXES_SHIFT;
3189e39c5baSBill Taylor cp->cp_log_outmbox_size = TAVOR_MBOX_SIZE_SHIFT;
3199e39c5baSBill Taylor cp->cp_log_num_inmbox = TAVOR_NUM_MAILBOXES_SHIFT;
3209e39c5baSBill Taylor cp->cp_log_num_intr_inmbox =
3219e39c5baSBill Taylor TAVOR_NUM_INTR_MAILBOXES_SHIFT;
3229e39c5baSBill Taylor cp->cp_log_inmbox_size = TAVOR_MBOX_SIZE_SHIFT;
3239e39c5baSBill Taylor cp->cp_log_num_srq = TAVOR_NUM_SRQ_SHIFT_256;
3249e39c5baSBill Taylor cp->cp_log_max_srq_sz = TAVOR_SRQ_SZ_SHIFT;
3259e39c5baSBill Taylor
3269e39c5baSBill Taylor } else if (state->ts_cfg_profile_setting == TAVOR_DDR_SIZE_128) {
3279e39c5baSBill Taylor cp->cp_log_num_outmbox = TAVOR_NUM_MAILBOXES_SHIFT;
3289e39c5baSBill Taylor cp->cp_log_num_intr_outmbox =
3299e39c5baSBill Taylor TAVOR_NUM_INTR_MAILBOXES_SHIFT;
3309e39c5baSBill Taylor cp->cp_log_outmbox_size = TAVOR_MBOX_SIZE_SHIFT;
3319e39c5baSBill Taylor cp->cp_log_num_inmbox = TAVOR_NUM_MAILBOXES_SHIFT;
3329e39c5baSBill Taylor cp->cp_log_num_intr_inmbox =
3339e39c5baSBill Taylor TAVOR_NUM_INTR_MAILBOXES_SHIFT;
3349e39c5baSBill Taylor cp->cp_log_inmbox_size = TAVOR_MBOX_SIZE_SHIFT;
3359e39c5baSBill Taylor cp->cp_log_num_srq = TAVOR_NUM_SRQ_SHIFT_128;
3369e39c5baSBill Taylor cp->cp_log_max_srq_sz = TAVOR_SRQ_SZ_SHIFT;
3379e39c5baSBill Taylor
3389e39c5baSBill Taylor } else if (state->ts_cfg_profile_setting == TAVOR_DDR_SIZE_MIN) {
3399e39c5baSBill Taylor cp->cp_log_num_outmbox = TAVOR_NUM_MAILBOXES_SHIFT;
3409e39c5baSBill Taylor cp->cp_log_num_intr_outmbox =
3419e39c5baSBill Taylor TAVOR_NUM_INTR_MAILBOXES_SHIFT;
3429e39c5baSBill Taylor cp->cp_log_outmbox_size = TAVOR_MBOX_SIZE_SHIFT;
3439e39c5baSBill Taylor cp->cp_log_num_inmbox = TAVOR_NUM_MAILBOXES_SHIFT;
3449e39c5baSBill Taylor cp->cp_log_num_intr_inmbox =
3459e39c5baSBill Taylor TAVOR_NUM_INTR_MAILBOXES_SHIFT;
3469e39c5baSBill Taylor cp->cp_log_inmbox_size = TAVOR_MBOX_SIZE_SHIFT;
3479e39c5baSBill Taylor cp->cp_log_num_srq = TAVOR_NUM_SRQ_SHIFT_MIN;
3489e39c5baSBill Taylor cp->cp_log_max_srq_sz = TAVOR_SRQ_SZ_SHIFT_MIN;
3499e39c5baSBill Taylor
3509e39c5baSBill Taylor } else {
3519e39c5baSBill Taylor return (DDI_FAILURE);
3529e39c5baSBill Taylor }
3539e39c5baSBill Taylor
3549e39c5baSBill Taylor /*
3559e39c5baSBill Taylor * Set default DMA mapping mode. Ensure consistency of flags
3569e39c5baSBill Taylor * with both architecture type and other configuration flags.
3579e39c5baSBill Taylor */
3589e39c5baSBill Taylor if (tavor_streaming_consistent == 0) {
3599e39c5baSBill Taylor #ifdef __sparc
3609e39c5baSBill Taylor cp->cp_streaming_consistent = DDI_DMA_STREAMING;
3619e39c5baSBill Taylor
3629e39c5baSBill Taylor /* Can't do both "streaming" and IOMMU bypass */
3639e39c5baSBill Taylor if (tavor_iommu_bypass != 0) {
3649e39c5baSBill Taylor kmem_free(cp, sizeof (tavor_cfg_profile_t));
3659e39c5baSBill Taylor return (DDI_FAILURE);
3669e39c5baSBill Taylor }
3679e39c5baSBill Taylor #else
3689e39c5baSBill Taylor cp->cp_streaming_consistent = DDI_DMA_CONSISTENT;
3699e39c5baSBill Taylor #endif
3709e39c5baSBill Taylor } else {
3719e39c5baSBill Taylor cp->cp_streaming_consistent = DDI_DMA_CONSISTENT;
3729e39c5baSBill Taylor }
3739e39c5baSBill Taylor
3749e39c5baSBill Taylor /* Determine whether to override ddi_dma_sync() */
3759e39c5baSBill Taylor cp->cp_consistent_syncoverride = tavor_consistent_syncoverride;
3769e39c5baSBill Taylor
3779e39c5baSBill Taylor /* Attach the configuration profile to Tavor softstate */
3789e39c5baSBill Taylor state->ts_cfg_profile = cp;
3799e39c5baSBill Taylor
3809e39c5baSBill Taylor return (DDI_SUCCESS);
3819e39c5baSBill Taylor }
3829e39c5baSBill Taylor
3839e39c5baSBill Taylor /*
3849e39c5baSBill Taylor * tavor_cfg_profile_init_phase2()
3859e39c5baSBill Taylor * Context: Only called from attach() path context
3869e39c5baSBill Taylor */
3879e39c5baSBill Taylor int
tavor_cfg_profile_init_phase2(tavor_state_t * state)3889e39c5baSBill Taylor tavor_cfg_profile_init_phase2(tavor_state_t *state)
3899e39c5baSBill Taylor {
3909e39c5baSBill Taylor tavor_cfg_profile_t *cp;
3919e39c5baSBill Taylor
3929e39c5baSBill Taylor /* Read the configuration profile from Tavor softstate */
3939e39c5baSBill Taylor cp = state->ts_cfg_profile;
3949e39c5baSBill Taylor
3959e39c5baSBill Taylor /*
3969e39c5baSBill Taylor * Verify the config profile setting. The 'setting' should already be
3979e39c5baSBill Taylor * set, during a call to ddi_dev_regsize() to get the size of DDR
3989e39c5baSBill Taylor * memory, or during a fallback to a smaller supported size. If it is
3999e39c5baSBill Taylor * not set, we should not have reached this 'phase2'. So we assert
4009e39c5baSBill Taylor * here.
4019e39c5baSBill Taylor */
4029e39c5baSBill Taylor ASSERT(state->ts_cfg_profile_setting != 0);
4039e39c5baSBill Taylor
4049e39c5baSBill Taylor /*
4059e39c5baSBill Taylor * The automatic configuration override is the
4069e39c5baSBill Taylor * 'tavor_alt_config_enable' variable. If this is set, we no longer
4079e39c5baSBill Taylor * use the DIMM size to enable the correct profile. Instead, all of
4089e39c5baSBill Taylor * the tavor config options at the top of this file are used directly.
4099e39c5baSBill Taylor *
4109e39c5baSBill Taylor * This allows customization for a user who knows what they are doing
4119e39c5baSBill Taylor * to set tavor configuration values manually.
4129e39c5baSBill Taylor *
4139e39c5baSBill Taylor * If this variable is 0, we do automatic config for both 128MB and
4149e39c5baSBill Taylor * 256MB DIMM sizes.
4159e39c5baSBill Taylor */
4169e39c5baSBill Taylor if (tavor_alt_config_enable) {
4179e39c5baSBill Taylor /*
4189e39c5baSBill Taylor * Initialize the configuration profile
4199e39c5baSBill Taylor */
4209e39c5baSBill Taylor cp->cp_log_num_qp = tavor_log_num_qp;
4219e39c5baSBill Taylor cp->cp_log_max_qp_sz = tavor_log_max_qp_sz;
4229e39c5baSBill Taylor
4239e39c5baSBill Taylor /* Determine WQE sizes from requested max SGLs */
4249e39c5baSBill Taylor tavor_cfg_wqe_sizes(cp);
4259e39c5baSBill Taylor
4269e39c5baSBill Taylor cp->cp_log_num_cq = tavor_log_num_cq;
4279e39c5baSBill Taylor cp->cp_log_max_cq_sz = tavor_log_max_cq_sz;
4289e39c5baSBill Taylor cp->cp_log_default_eq_sz = tavor_log_default_eq_sz;
4299e39c5baSBill Taylor cp->cp_log_num_rdb = tavor_log_num_rdb;
4309e39c5baSBill Taylor cp->cp_log_num_mcg = tavor_log_num_mcg;
4319e39c5baSBill Taylor cp->cp_num_qp_per_mcg = tavor_num_qp_per_mcg;
4329e39c5baSBill Taylor cp->cp_log_num_mcg_hash = tavor_log_num_mcg_hash;
4339e39c5baSBill Taylor cp->cp_log_num_mpt = tavor_log_num_mpt;
4349e39c5baSBill Taylor cp->cp_log_max_mrw_sz = tavor_log_max_mrw_sz;
4359e39c5baSBill Taylor cp->cp_log_num_mttseg = tavor_log_num_mttseg;
4369e39c5baSBill Taylor cp->cp_log_num_uar = tavor_log_num_uar;
4379e39c5baSBill Taylor cp->cp_log_num_pd = tavor_log_num_pd;
4389e39c5baSBill Taylor cp->cp_log_num_ah = tavor_log_num_ah;
4399e39c5baSBill Taylor cp->cp_log_max_pkeytbl = tavor_log_max_pkeytbl;
4409e39c5baSBill Taylor cp->cp_log_max_gidtbl = tavor_log_max_gidtbl;
4419e39c5baSBill Taylor cp->cp_hca_max_rdma_in_qp = tavor_hca_max_rdma_in_qp;
4429e39c5baSBill Taylor cp->cp_hca_max_rdma_out_qp = tavor_hca_max_rdma_out_qp;
4439e39c5baSBill Taylor cp->cp_max_mtu = tavor_max_mtu;
4449e39c5baSBill Taylor cp->cp_max_port_width = tavor_max_port_width;
4459e39c5baSBill Taylor cp->cp_max_vlcap = tavor_max_vlcap;
4469e39c5baSBill Taylor cp->cp_num_ports = tavor_num_ports;
4479e39c5baSBill Taylor cp->cp_qp0_agents_in_fw = tavor_qp0_agents_in_fw;
4489e39c5baSBill Taylor cp->cp_qp1_agents_in_fw = tavor_qp1_agents_in_fw;
4499e39c5baSBill Taylor cp->cp_sw_reset_delay = tavor_sw_reset_delay;
4509e39c5baSBill Taylor cp->cp_ackreq_freq = tavor_qp_ackreq_freq;
4519e39c5baSBill Taylor cp->cp_max_out_splt_trans = tavor_max_out_splt_trans;
4529e39c5baSBill Taylor cp->cp_max_mem_rd_byte_cnt = tavor_max_mem_rd_byte_cnt;
4539e39c5baSBill Taylor
4549e39c5baSBill Taylor } else if (state->ts_cfg_profile_setting >= TAVOR_DDR_SIZE_256) {
4559e39c5baSBill Taylor /*
4569e39c5baSBill Taylor * Initialize the configuration profile
4579e39c5baSBill Taylor */
4589e39c5baSBill Taylor cp->cp_log_num_qp = TAVOR_NUM_QP_SHIFT_256;
4599e39c5baSBill Taylor cp->cp_log_max_qp_sz = TAVOR_QP_SZ_SHIFT;
4609e39c5baSBill Taylor
4619e39c5baSBill Taylor /* Determine WQE sizes from requested max SGLs */
4629e39c5baSBill Taylor tavor_cfg_wqe_sizes(cp);
4639e39c5baSBill Taylor
4649e39c5baSBill Taylor cp->cp_log_num_cq = TAVOR_NUM_CQ_SHIFT_256;
4659e39c5baSBill Taylor cp->cp_log_max_cq_sz = TAVOR_CQ_SZ_SHIFT;
4669e39c5baSBill Taylor cp->cp_log_default_eq_sz = TAVOR_DEFAULT_EQ_SZ_SHIFT;
4679e39c5baSBill Taylor cp->cp_log_num_rdb = TAVOR_NUM_RDB_SHIFT_256;
4689e39c5baSBill Taylor cp->cp_log_num_mcg = TAVOR_NUM_MCG_SHIFT;
4699e39c5baSBill Taylor cp->cp_num_qp_per_mcg = TAVOR_NUM_QP_PER_MCG;
4709e39c5baSBill Taylor cp->cp_log_num_mcg_hash = TAVOR_NUM_MCG_HASH_SHIFT;
4719e39c5baSBill Taylor cp->cp_log_num_mpt = TAVOR_NUM_MPT_SHIFT_256;
4729e39c5baSBill Taylor cp->cp_log_max_mrw_sz = TAVOR_MAX_MEM_MPT_SHIFT_256;
4739e39c5baSBill Taylor cp->cp_log_num_mttseg = TAVOR_NUM_MTTSEG_SHIFT;
4749e39c5baSBill Taylor cp->cp_log_num_uar = TAVOR_NUM_UAR_SHIFT;
4759e39c5baSBill Taylor cp->cp_log_num_pd = TAVOR_NUM_PD_SHIFT;
4769e39c5baSBill Taylor cp->cp_log_num_ah = TAVOR_NUM_AH_SHIFT;
4779e39c5baSBill Taylor cp->cp_log_max_pkeytbl = TAVOR_NUM_PKEYTBL_SHIFT;
4789e39c5baSBill Taylor cp->cp_log_max_gidtbl = TAVOR_NUM_GIDTBL_SHIFT;
4799e39c5baSBill Taylor cp->cp_hca_max_rdma_in_qp = TAVOR_HCA_MAX_RDMA_IN_QP;
4809e39c5baSBill Taylor cp->cp_hca_max_rdma_out_qp = TAVOR_HCA_MAX_RDMA_OUT_QP;
4819e39c5baSBill Taylor cp->cp_max_mtu = TAVOR_MAX_MTU;
4829e39c5baSBill Taylor cp->cp_max_port_width = TAVOR_MAX_PORT_WIDTH;
4839e39c5baSBill Taylor cp->cp_max_vlcap = TAVOR_MAX_VLCAP;
4849e39c5baSBill Taylor cp->cp_num_ports = TAVOR_NUM_PORTS;
4859e39c5baSBill Taylor cp->cp_qp0_agents_in_fw = tavor_qp0_agents_in_fw;
4869e39c5baSBill Taylor cp->cp_qp1_agents_in_fw = tavor_qp1_agents_in_fw;
4879e39c5baSBill Taylor cp->cp_sw_reset_delay = tavor_sw_reset_delay;
4889e39c5baSBill Taylor cp->cp_ackreq_freq = tavor_qp_ackreq_freq;
4899e39c5baSBill Taylor cp->cp_max_out_splt_trans = tavor_max_out_splt_trans;
4909e39c5baSBill Taylor cp->cp_max_mem_rd_byte_cnt = tavor_max_mem_rd_byte_cnt;
4919e39c5baSBill Taylor
4929e39c5baSBill Taylor } else if (state->ts_cfg_profile_setting == TAVOR_DDR_SIZE_128) {
4939e39c5baSBill Taylor /*
4949e39c5baSBill Taylor * Initialize the configuration profile
4959e39c5baSBill Taylor */
4969e39c5baSBill Taylor cp->cp_log_num_qp = TAVOR_NUM_QP_SHIFT_128;
4979e39c5baSBill Taylor cp->cp_log_max_qp_sz = TAVOR_QP_SZ_SHIFT;
4989e39c5baSBill Taylor
4999e39c5baSBill Taylor /* Determine WQE sizes from requested max SGLs */
5009e39c5baSBill Taylor tavor_cfg_wqe_sizes(cp);
5019e39c5baSBill Taylor
5029e39c5baSBill Taylor cp->cp_log_num_cq = TAVOR_NUM_CQ_SHIFT_128;
5039e39c5baSBill Taylor cp->cp_log_max_cq_sz = TAVOR_CQ_SZ_SHIFT;
5049e39c5baSBill Taylor cp->cp_log_default_eq_sz = TAVOR_DEFAULT_EQ_SZ_SHIFT;
5059e39c5baSBill Taylor cp->cp_log_num_rdb = TAVOR_NUM_RDB_SHIFT_128;
5069e39c5baSBill Taylor cp->cp_log_num_mcg = TAVOR_NUM_MCG_SHIFT;
5079e39c5baSBill Taylor cp->cp_num_qp_per_mcg = TAVOR_NUM_QP_PER_MCG;
5089e39c5baSBill Taylor cp->cp_log_num_mcg_hash = TAVOR_NUM_MCG_HASH_SHIFT;
5099e39c5baSBill Taylor cp->cp_log_num_mpt = TAVOR_NUM_MPT_SHIFT_128;
5109e39c5baSBill Taylor cp->cp_log_max_mrw_sz = TAVOR_MAX_MEM_MPT_SHIFT_128;
5119e39c5baSBill Taylor cp->cp_log_num_mttseg = TAVOR_NUM_MTTSEG_SHIFT;
5129e39c5baSBill Taylor cp->cp_log_num_uar = TAVOR_NUM_UAR_SHIFT;
5139e39c5baSBill Taylor cp->cp_log_num_pd = TAVOR_NUM_PD_SHIFT;
5149e39c5baSBill Taylor cp->cp_log_num_ah = TAVOR_NUM_AH_SHIFT;
5159e39c5baSBill Taylor cp->cp_log_max_pkeytbl = TAVOR_NUM_PKEYTBL_SHIFT;
5169e39c5baSBill Taylor cp->cp_log_max_gidtbl = TAVOR_NUM_GIDTBL_SHIFT;
5179e39c5baSBill Taylor cp->cp_hca_max_rdma_in_qp = TAVOR_HCA_MAX_RDMA_IN_QP;
5189e39c5baSBill Taylor cp->cp_hca_max_rdma_out_qp = TAVOR_HCA_MAX_RDMA_OUT_QP;
5199e39c5baSBill Taylor cp->cp_max_mtu = TAVOR_MAX_MTU;
5209e39c5baSBill Taylor cp->cp_max_port_width = TAVOR_MAX_PORT_WIDTH;
5219e39c5baSBill Taylor cp->cp_max_vlcap = TAVOR_MAX_VLCAP;
5229e39c5baSBill Taylor cp->cp_num_ports = TAVOR_NUM_PORTS;
5239e39c5baSBill Taylor cp->cp_qp0_agents_in_fw = tavor_qp0_agents_in_fw;
5249e39c5baSBill Taylor cp->cp_qp1_agents_in_fw = tavor_qp1_agents_in_fw;
5259e39c5baSBill Taylor cp->cp_sw_reset_delay = tavor_sw_reset_delay;
5269e39c5baSBill Taylor cp->cp_ackreq_freq = tavor_qp_ackreq_freq;
5279e39c5baSBill Taylor cp->cp_max_out_splt_trans = tavor_max_out_splt_trans;
5289e39c5baSBill Taylor cp->cp_max_mem_rd_byte_cnt = tavor_max_mem_rd_byte_cnt;
5299e39c5baSBill Taylor
5309e39c5baSBill Taylor } else if (state->ts_cfg_profile_setting == TAVOR_DDR_SIZE_MIN) {
5319e39c5baSBill Taylor /*
5329e39c5baSBill Taylor * Initialize the configuration profile for minimal footprint.
5339e39c5baSBill Taylor */
5349e39c5baSBill Taylor
5359e39c5baSBill Taylor cp->cp_log_num_qp = TAVOR_NUM_QP_SHIFT_MIN;
5369e39c5baSBill Taylor cp->cp_log_max_qp_sz = TAVOR_QP_SZ_SHIFT_MIN;
5379e39c5baSBill Taylor
5389e39c5baSBill Taylor /* Determine WQE sizes from requested max SGLs */
5399e39c5baSBill Taylor tavor_cfg_wqe_sizes(cp);
5409e39c5baSBill Taylor
5419e39c5baSBill Taylor cp->cp_log_num_cq = TAVOR_NUM_CQ_SHIFT_MIN;
5429e39c5baSBill Taylor cp->cp_log_max_cq_sz = TAVOR_CQ_SZ_SHIFT_MIN;
5439e39c5baSBill Taylor cp->cp_log_default_eq_sz = TAVOR_DEFAULT_EQ_SZ_SHIFT;
5449e39c5baSBill Taylor cp->cp_log_num_rdb = TAVOR_NUM_RDB_SHIFT_MIN;
5459e39c5baSBill Taylor cp->cp_log_num_mcg = TAVOR_NUM_MCG_SHIFT_MIN;
5469e39c5baSBill Taylor cp->cp_num_qp_per_mcg = TAVOR_NUM_QP_PER_MCG_MIN;
5479e39c5baSBill Taylor cp->cp_log_num_mcg_hash = TAVOR_NUM_MCG_HASH_SHIFT_MIN;
5489e39c5baSBill Taylor cp->cp_log_num_mpt = TAVOR_NUM_MPT_SHIFT_MIN;
5499e39c5baSBill Taylor cp->cp_log_max_mrw_sz = TAVOR_MAX_MEM_MPT_SHIFT_MIN;
5509e39c5baSBill Taylor cp->cp_log_num_mttseg = TAVOR_NUM_MTTSEG_SHIFT_MIN;
5519e39c5baSBill Taylor cp->cp_log_num_uar = TAVOR_NUM_UAR_SHIFT_MIN;
5529e39c5baSBill Taylor cp->cp_log_num_pd = TAVOR_NUM_PD_SHIFT;
5539e39c5baSBill Taylor cp->cp_log_num_ah = TAVOR_NUM_AH_SHIFT_MIN;
5549e39c5baSBill Taylor cp->cp_log_max_pkeytbl = TAVOR_NUM_PKEYTBL_SHIFT;
5559e39c5baSBill Taylor cp->cp_log_max_gidtbl = TAVOR_NUM_GIDTBL_SHIFT;
5569e39c5baSBill Taylor cp->cp_hca_max_rdma_in_qp = TAVOR_HCA_MAX_RDMA_IN_QP;
5579e39c5baSBill Taylor cp->cp_hca_max_rdma_out_qp = TAVOR_HCA_MAX_RDMA_OUT_QP;
5589e39c5baSBill Taylor cp->cp_max_mtu = TAVOR_MAX_MTU;
5599e39c5baSBill Taylor cp->cp_max_port_width = TAVOR_MAX_PORT_WIDTH;
5609e39c5baSBill Taylor cp->cp_max_vlcap = TAVOR_MAX_VLCAP;
5619e39c5baSBill Taylor cp->cp_num_ports = TAVOR_NUM_PORTS;
5629e39c5baSBill Taylor cp->cp_qp0_agents_in_fw = tavor_qp0_agents_in_fw;
5639e39c5baSBill Taylor cp->cp_qp1_agents_in_fw = tavor_qp1_agents_in_fw;
5649e39c5baSBill Taylor cp->cp_sw_reset_delay = tavor_sw_reset_delay;
5659e39c5baSBill Taylor cp->cp_ackreq_freq = tavor_qp_ackreq_freq;
5669e39c5baSBill Taylor cp->cp_max_out_splt_trans = tavor_max_out_splt_trans;
5679e39c5baSBill Taylor cp->cp_max_mem_rd_byte_cnt = tavor_max_mem_rd_byte_cnt;
5689e39c5baSBill Taylor
5699e39c5baSBill Taylor } else {
5709e39c5baSBill Taylor return (DDI_FAILURE);
5719e39c5baSBill Taylor }
5729e39c5baSBill Taylor
5739e39c5baSBill Taylor /*
5749e39c5baSBill Taylor * Set IOMMU bypass or not. Ensure consistency of flags with
5759e39c5baSBill Taylor * architecture type.
5769e39c5baSBill Taylor */
5779e39c5baSBill Taylor #ifdef __sparc
5789e39c5baSBill Taylor if (tavor_iommu_bypass == 1) {
5799e39c5baSBill Taylor tavor_check_iommu_bypass(state, cp);
5809e39c5baSBill Taylor } else {
5819e39c5baSBill Taylor cp->cp_iommu_bypass = TAVOR_BINDMEM_NORMAL;
5829e39c5baSBill Taylor cp->cp_disable_streaming_on_bypass = 0;
5839e39c5baSBill Taylor }
5849e39c5baSBill Taylor #else
5859e39c5baSBill Taylor cp->cp_iommu_bypass = TAVOR_BINDMEM_NORMAL;
5869e39c5baSBill Taylor cp->cp_disable_streaming_on_bypass = 0;
5879e39c5baSBill Taylor #endif
5889e39c5baSBill Taylor /* Set whether QP WQEs will be in DDR or not */
5899e39c5baSBill Taylor cp->cp_qp_wq_inddr = (tavor_qp_wq_inddr == 0) ?
5909e39c5baSBill Taylor TAVOR_QUEUE_LOCATION_NORMAL : TAVOR_QUEUE_LOCATION_INDDR;
5919e39c5baSBill Taylor
5929e39c5baSBill Taylor /* Set whether SRQ WQEs will be in DDR or not */
5939e39c5baSBill Taylor cp->cp_srq_wq_inddr = (tavor_srq_wq_inddr == 0) ?
5949e39c5baSBill Taylor TAVOR_QUEUE_LOCATION_NORMAL : TAVOR_QUEUE_LOCATION_INDDR;
5959e39c5baSBill Taylor
5969e39c5baSBill Taylor cp->cp_use_msi_if_avail = tavor_use_msi_if_avail;
5979e39c5baSBill Taylor
5989e39c5baSBill Taylor /* Determine additional configuration from optional properties */
5999e39c5baSBill Taylor tavor_cfg_prop_lookup(state, cp);
6009e39c5baSBill Taylor
6019e39c5baSBill Taylor return (DDI_SUCCESS);
6029e39c5baSBill Taylor }
6039e39c5baSBill Taylor
6049e39c5baSBill Taylor
6059e39c5baSBill Taylor /*
6069e39c5baSBill Taylor * tavor_cfg_profile_fini()
6079e39c5baSBill Taylor * Context: Only called from attach() and/or detach() path contexts
6089e39c5baSBill Taylor */
6099e39c5baSBill Taylor void
tavor_cfg_profile_fini(tavor_state_t * state)6109e39c5baSBill Taylor tavor_cfg_profile_fini(tavor_state_t *state)
6119e39c5baSBill Taylor {
6129e39c5baSBill Taylor /*
6139e39c5baSBill Taylor * Free up the space for configuration profile
6149e39c5baSBill Taylor */
6159e39c5baSBill Taylor kmem_free(state->ts_cfg_profile, sizeof (tavor_cfg_profile_t));
6169e39c5baSBill Taylor }
6179e39c5baSBill Taylor
6189e39c5baSBill Taylor
6199e39c5baSBill Taylor /*
6209e39c5baSBill Taylor * tavor_cfg_wqe_sizes()
6219e39c5baSBill Taylor * Context: Only called from attach() path context
6229e39c5baSBill Taylor */
6239e39c5baSBill Taylor static void
tavor_cfg_wqe_sizes(tavor_cfg_profile_t * cp)6249e39c5baSBill Taylor tavor_cfg_wqe_sizes(tavor_cfg_profile_t *cp)
6259e39c5baSBill Taylor {
6269e39c5baSBill Taylor uint_t max_size, log2;
6279e39c5baSBill Taylor uint_t max_sgl, real_max_sgl;
6289e39c5baSBill Taylor
6299e39c5baSBill Taylor /*
6309e39c5baSBill Taylor * Get the requested maximum number SGL per WQE from the Tavor
6319e39c5baSBill Taylor * patchable variable
6329e39c5baSBill Taylor */
6339e39c5baSBill Taylor max_sgl = tavor_wqe_max_sgl;
6349e39c5baSBill Taylor
6359e39c5baSBill Taylor /*
6369e39c5baSBill Taylor * Use requested maximum number of SGL to calculate the max descriptor
6379e39c5baSBill Taylor * size (while guaranteeing that the descriptor size is a power-of-2
6389e39c5baSBill Taylor * cachelines). We have to use the calculation for QP1 MLX transport
6399e39c5baSBill Taylor * because the possibility that we might need to inline a GRH, along
6409e39c5baSBill Taylor * with all the other headers and alignment restrictions, sets the
6419e39c5baSBill Taylor * maximum for the number of SGLs that we can advertise support for.
6429e39c5baSBill Taylor */
6439e39c5baSBill Taylor max_size = (TAVOR_QP_WQE_MLX_QP1_HDRS + (max_sgl << 4));
6449e39c5baSBill Taylor log2 = highbit(max_size);
645*de710d24SJosef 'Jeff' Sipek if (ISP2(max_size)) {
6469e39c5baSBill Taylor log2 = log2 - 1;
6479e39c5baSBill Taylor }
6489e39c5baSBill Taylor max_size = (1 << log2);
6499e39c5baSBill Taylor
6509e39c5baSBill Taylor /*
6519e39c5baSBill Taylor * Now clip the maximum descriptor size based on Tavor HW maximum
6529e39c5baSBill Taylor */
6539e39c5baSBill Taylor max_size = min(max_size, TAVOR_QP_WQE_MAX_SIZE);
6549e39c5baSBill Taylor
6559e39c5baSBill Taylor /*
6569e39c5baSBill Taylor * Then use the calculated max descriptor size to determine the "real"
6579e39c5baSBill Taylor * maximum SGL (the number beyond which we would roll over to the next
6589e39c5baSBill Taylor * power-of-2).
6599e39c5baSBill Taylor */
6609e39c5baSBill Taylor real_max_sgl = (max_size - TAVOR_QP_WQE_MLX_QP1_HDRS) >> 4;
6619e39c5baSBill Taylor
6629e39c5baSBill Taylor /* Then save away this configuration information */
6639e39c5baSBill Taylor cp->cp_wqe_max_sgl = max_sgl;
6649e39c5baSBill Taylor cp->cp_wqe_real_max_sgl = real_max_sgl;
6659e39c5baSBill Taylor
6669e39c5baSBill Taylor /* SRQ SGL gets set to it's own patchable variable value */
6679e39c5baSBill Taylor cp->cp_srq_max_sgl = tavor_srq_max_sgl;
6689e39c5baSBill Taylor }
6699e39c5baSBill Taylor
6709e39c5baSBill Taylor
6719e39c5baSBill Taylor /*
6729e39c5baSBill Taylor * tavor_cfg_prop_lookup()
6739e39c5baSBill Taylor * Context: Only called from attach() path context
6749e39c5baSBill Taylor */
6759e39c5baSBill Taylor static void
tavor_cfg_prop_lookup(tavor_state_t * state,tavor_cfg_profile_t * cp)6769e39c5baSBill Taylor tavor_cfg_prop_lookup(tavor_state_t *state, tavor_cfg_profile_t *cp)
6779e39c5baSBill Taylor {
6789e39c5baSBill Taylor uint_t num_ports, nelementsp;
6799e39c5baSBill Taylor uchar_t *datap;
6809e39c5baSBill Taylor int status;
6819e39c5baSBill Taylor
6829e39c5baSBill Taylor /*
6839e39c5baSBill Taylor * Read the property defining the number of Tavor ports to
6849e39c5baSBill Taylor * support. If the property is undefined or invalid, then return.
6859e39c5baSBill Taylor * We return here assuming also that OBP is not supposed to be setting
6869e39c5baSBill Taylor * up other properties in this case (eg: HCA plugin cards). But if
6879e39c5baSBill Taylor * this property is valid, then we print out a message for the other
6889e39c5baSBill Taylor * properties to show an OBP error.
6899e39c5baSBill Taylor */
6909e39c5baSBill Taylor num_ports = ddi_prop_get_int(DDI_DEV_T_ANY, state->ts_dip,
6919e39c5baSBill Taylor DDI_PROP_DONTPASS, "#ports", 0);
6929e39c5baSBill Taylor if ((num_ports > TAVOR_NUM_PORTS) || (num_ports == 0)) {
6939e39c5baSBill Taylor return;
6949e39c5baSBill Taylor }
6959e39c5baSBill Taylor cp->cp_num_ports = num_ports;
6969e39c5baSBill Taylor
6979e39c5baSBill Taylor /*
6989e39c5baSBill Taylor * The system image guid is not currently supported in the 1275
6999e39c5baSBill Taylor * binding. So we leave this commented out for now.
7009e39c5baSBill Taylor */
7019e39c5baSBill Taylor #ifdef SUPPORTED_IN_1275_BINDING
7029e39c5baSBill Taylor /*
7039e39c5baSBill Taylor * Read the property defining the value to use later to override the
7049e39c5baSBill Taylor * default SystemImageGUID (in firmware). If the property is
7059e39c5baSBill Taylor * undefined, then return.
7069e39c5baSBill Taylor */
7079e39c5baSBill Taylor status = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, state->ts_dip,
7089e39c5baSBill Taylor DDI_PROP_DONTPASS, "system-image-guid", &datap, &nelementsp);
7099e39c5baSBill Taylor if (status == DDI_PROP_SUCCESS) {
7109e39c5baSBill Taylor cp->cp_sysimgguid = ((uint64_t *)datap)[0];
7119e39c5baSBill Taylor ddi_prop_free(datap);
7129e39c5baSBill Taylor } else {
7139e39c5baSBill Taylor cmn_err(CE_NOTE,
7149e39c5baSBill Taylor "Unable to read OBP system-image-guid property");
7159e39c5baSBill Taylor }
7169e39c5baSBill Taylor #endif
7179e39c5baSBill Taylor
7189e39c5baSBill Taylor /*
7199e39c5baSBill Taylor * Read the property defining the value to use later to override
7209e39c5baSBill Taylor * the default SystemImageGUID (in firmware). If the property is
7219e39c5baSBill Taylor * undefined, then return.
7229e39c5baSBill Taylor */
7239e39c5baSBill Taylor status = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, state->ts_dip,
7249e39c5baSBill Taylor DDI_PROP_DONTPASS, "node-guid", &datap, &nelementsp);
7259e39c5baSBill Taylor if (status == DDI_PROP_SUCCESS) {
7269e39c5baSBill Taylor cp->cp_nodeguid = ((uint64_t *)datap)[0];
7279e39c5baSBill Taylor ddi_prop_free(datap);
7289e39c5baSBill Taylor } else {
7299e39c5baSBill Taylor cmn_err(CE_NOTE, "Unable to read OBP node-guid property");
7309e39c5baSBill Taylor }
7319e39c5baSBill Taylor
7329e39c5baSBill Taylor /*
7339e39c5baSBill Taylor * Using the value for the number of ports (above) read the properties
7349e39c5baSBill Taylor * used to later to override the default PortGUIDs for each Tavor port.
7359e39c5baSBill Taylor * If either of these properties are undefined, then return.
7369e39c5baSBill Taylor */
7379e39c5baSBill Taylor if (num_ports == TAVOR_NUM_PORTS) {
7389e39c5baSBill Taylor status = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY,
7399e39c5baSBill Taylor state->ts_dip, DDI_PROP_DONTPASS, "port-2-guid", &datap,
7409e39c5baSBill Taylor &nelementsp);
7419e39c5baSBill Taylor if (status == DDI_PROP_SUCCESS) {
7429e39c5baSBill Taylor cp->cp_portguid[1] = ((uint64_t *)datap)[0];
7439e39c5baSBill Taylor ddi_prop_free(datap);
7449e39c5baSBill Taylor } else {
7459e39c5baSBill Taylor cmn_err(CE_NOTE,
7469e39c5baSBill Taylor "Unable to read OBP port-2-guid property");
7479e39c5baSBill Taylor }
7489e39c5baSBill Taylor }
7499e39c5baSBill Taylor status = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, state->ts_dip,
7509e39c5baSBill Taylor DDI_PROP_DONTPASS, "port-1-guid", &datap, &nelementsp);
7519e39c5baSBill Taylor if (status == DDI_PROP_SUCCESS) {
7529e39c5baSBill Taylor cp->cp_portguid[0] = ((uint64_t *)datap)[0];
7539e39c5baSBill Taylor ddi_prop_free(datap);
7549e39c5baSBill Taylor } else {
7559e39c5baSBill Taylor cmn_err(CE_NOTE, "Unable to read OBP port-1-guid property");
7569e39c5baSBill Taylor }
7579e39c5baSBill Taylor }
7589e39c5baSBill Taylor
7599e39c5baSBill Taylor #ifdef __sparc
7609e39c5baSBill Taylor /*
7619e39c5baSBill Taylor * tavor_check_iommu_bypass()
7629e39c5baSBill Taylor * Context: Only called from attach() path context
7639e39c5baSBill Taylor */
7649e39c5baSBill Taylor static void
tavor_check_iommu_bypass(tavor_state_t * state,tavor_cfg_profile_t * cp)7659e39c5baSBill Taylor tavor_check_iommu_bypass(tavor_state_t *state, tavor_cfg_profile_t *cp)
7669e39c5baSBill Taylor {
7679e39c5baSBill Taylor ddi_dma_handle_t dmahdl;
7689e39c5baSBill Taylor ddi_dma_attr_t dma_attr;
7699e39c5baSBill Taylor int status;
7709e39c5baSBill Taylor
7719e39c5baSBill Taylor tavor_dma_attr_init(&dma_attr);
7729e39c5baSBill Taylor
7739e39c5baSBill Taylor /* Try mapping for IOMMU bypass (Force Physical) */
7749e39c5baSBill Taylor dma_attr.dma_attr_flags = DDI_DMA_FORCE_PHYSICAL;
7759e39c5baSBill Taylor
7769e39c5baSBill Taylor /*
7779e39c5baSBill Taylor * Call ddi_dma_alloc_handle(). If this returns DDI_DMA_BADATTR then
7789e39c5baSBill Taylor * it is not possible to use IOMMU bypass with our PCI bridge parent.
7799e39c5baSBill Taylor * For example, certain versions of Tomatillo do not support IOMMU
7809e39c5baSBill Taylor * bypass. Since the function we are in can only be called if iommu
7819e39c5baSBill Taylor * bypass was requested in the config profile, we configure for bypass
7829e39c5baSBill Taylor * if the ddi_dma_alloc_handle() was successful. Otherwise, we
7839e39c5baSBill Taylor * configure for non-bypass (ie: normal) mapping.
7849e39c5baSBill Taylor */
7859e39c5baSBill Taylor status = ddi_dma_alloc_handle(state->ts_dip, &dma_attr,
7869e39c5baSBill Taylor DDI_DMA_SLEEP, NULL, &dmahdl);
7879e39c5baSBill Taylor if (status == DDI_DMA_BADATTR) {
7889e39c5baSBill Taylor cp->cp_iommu_bypass = TAVOR_BINDMEM_NORMAL;
7899e39c5baSBill Taylor cp->cp_disable_streaming_on_bypass = 0;
7909e39c5baSBill Taylor } else {
7919e39c5baSBill Taylor cp->cp_iommu_bypass = TAVOR_BINDMEM_BYPASS;
7929e39c5baSBill Taylor cp->cp_disable_streaming_on_bypass =
7939e39c5baSBill Taylor tavor_disable_streaming_on_bypass;
7949e39c5baSBill Taylor
7959e39c5baSBill Taylor if (status == DDI_SUCCESS) {
7969e39c5baSBill Taylor ddi_dma_free_handle(&dmahdl);
7979e39c5baSBill Taylor }
7989e39c5baSBill Taylor }
7999e39c5baSBill Taylor }
8009e39c5baSBill Taylor #endif
801