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