xref: /onnv-gate/usr/src/uts/common/sys/ib/adapters/hermon/hermon.h (revision 12965:b65a8427f8fe)
19517SBill.Taylor@Sun.COM /*
29517SBill.Taylor@Sun.COM  * CDDL HEADER START
39517SBill.Taylor@Sun.COM  *
49517SBill.Taylor@Sun.COM  * The contents of this file are subject to the terms of the
59517SBill.Taylor@Sun.COM  * Common Development and Distribution License (the "License").
69517SBill.Taylor@Sun.COM  * You may not use this file except in compliance with the License.
79517SBill.Taylor@Sun.COM  *
89517SBill.Taylor@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99517SBill.Taylor@Sun.COM  * or http://www.opensolaris.org/os/licensing.
109517SBill.Taylor@Sun.COM  * See the License for the specific language governing permissions
119517SBill.Taylor@Sun.COM  * and limitations under the License.
129517SBill.Taylor@Sun.COM  *
139517SBill.Taylor@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
149517SBill.Taylor@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159517SBill.Taylor@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
169517SBill.Taylor@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
179517SBill.Taylor@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
189517SBill.Taylor@Sun.COM  *
199517SBill.Taylor@Sun.COM  * CDDL HEADER END
209517SBill.Taylor@Sun.COM  */
219517SBill.Taylor@Sun.COM 
229517SBill.Taylor@Sun.COM /*
2312688SWilliam.Taylor@Oracle.COM  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
249517SBill.Taylor@Sun.COM  */
259517SBill.Taylor@Sun.COM 
269517SBill.Taylor@Sun.COM #ifndef	_SYS_IB_ADAPTERS_HERMON_H
279517SBill.Taylor@Sun.COM #define	_SYS_IB_ADAPTERS_HERMON_H
289517SBill.Taylor@Sun.COM 
299517SBill.Taylor@Sun.COM /*
309517SBill.Taylor@Sun.COM  * hermon.h
319517SBill.Taylor@Sun.COM  *    Contains the #defines and typedefs necessary for the Hermon softstate
329517SBill.Taylor@Sun.COM  *    structure and for proper attach() and detach() processing.  Also
339517SBill.Taylor@Sun.COM  *    includes all the other Hermon header files (and so is the only header
349517SBill.Taylor@Sun.COM  *    file that is directly included by the Hermon source files).
359517SBill.Taylor@Sun.COM  *    Lastly, this file includes everything necessary for implementing the
369517SBill.Taylor@Sun.COM  *    devmap interface and for maintaining the "mapped resource database".
379517SBill.Taylor@Sun.COM  */
389517SBill.Taylor@Sun.COM 
399517SBill.Taylor@Sun.COM #include <sys/types.h>
409517SBill.Taylor@Sun.COM #include <sys/conf.h>
419517SBill.Taylor@Sun.COM #include <sys/ddi.h>
429517SBill.Taylor@Sun.COM #include <sys/sunddi.h>
439517SBill.Taylor@Sun.COM #include <sys/tnf_probe.h>
449517SBill.Taylor@Sun.COM #include <sys/taskq.h>
459517SBill.Taylor@Sun.COM #include <sys/atomic.h>
469517SBill.Taylor@Sun.COM #ifdef FMA_TEST
479517SBill.Taylor@Sun.COM #include <sys/modhash.h>
489517SBill.Taylor@Sun.COM #endif
499517SBill.Taylor@Sun.COM 
509517SBill.Taylor@Sun.COM #include <sys/ib/ibtl/ibci.h>
519517SBill.Taylor@Sun.COM #include <sys/ib/ibtl/impl/ibtl_util.h>
529517SBill.Taylor@Sun.COM #include <sys/ib/adapters/mlnx_umap.h>
539517SBill.Taylor@Sun.COM 
549517SBill.Taylor@Sun.COM /*
559517SBill.Taylor@Sun.COM  * First include all the Hermon typedefs, then include all the other Hermon
569517SBill.Taylor@Sun.COM  * specific headers (many of which depend on the typedefs having already
579517SBill.Taylor@Sun.COM  * been defined).
589517SBill.Taylor@Sun.COM  */
599517SBill.Taylor@Sun.COM #include <sys/ib/adapters/hermon/hermon_typedef.h>
609517SBill.Taylor@Sun.COM #include <sys/ib/adapters/hermon/hermon_hw.h>
619517SBill.Taylor@Sun.COM 
629517SBill.Taylor@Sun.COM #include <sys/ib/adapters/hermon/hermon_agents.h>
639517SBill.Taylor@Sun.COM #include <sys/ib/adapters/hermon/hermon_cfg.h>
649517SBill.Taylor@Sun.COM #include <sys/ib/adapters/hermon/hermon_cmd.h>
659517SBill.Taylor@Sun.COM #include <sys/ib/adapters/hermon/hermon_cq.h>
669517SBill.Taylor@Sun.COM #include <sys/ib/adapters/hermon/hermon_event.h>
67*12965SWilliam.Taylor@Oracle.COM #include <sys/ib/adapters/hermon/hermon_fcoib.h>
689517SBill.Taylor@Sun.COM #include <sys/ib/adapters/hermon/hermon_ioctl.h>
699517SBill.Taylor@Sun.COM #include <sys/ib/adapters/hermon/hermon_misc.h>
709517SBill.Taylor@Sun.COM #include <sys/ib/adapters/hermon/hermon_mr.h>
719517SBill.Taylor@Sun.COM #include <sys/ib/adapters/hermon/hermon_wr.h>
729517SBill.Taylor@Sun.COM #include <sys/ib/adapters/hermon/hermon_qp.h>
739517SBill.Taylor@Sun.COM #include <sys/ib/adapters/hermon/hermon_srq.h>
749517SBill.Taylor@Sun.COM #include <sys/ib/adapters/hermon/hermon_rsrc.h>
759517SBill.Taylor@Sun.COM #include <sys/ib/adapters/hermon/hermon_fm.h>
769517SBill.Taylor@Sun.COM 
779517SBill.Taylor@Sun.COM #ifdef __cplusplus
789517SBill.Taylor@Sun.COM extern "C" {
799517SBill.Taylor@Sun.COM #endif
809517SBill.Taylor@Sun.COM 
819517SBill.Taylor@Sun.COM /*
829517SBill.Taylor@Sun.COM  * Number of initial states to setup. Used in call to ddi_soft_state_init()
839517SBill.Taylor@Sun.COM  */
849517SBill.Taylor@Sun.COM #define	HERMON_INITIAL_STATES		3
859517SBill.Taylor@Sun.COM 
869517SBill.Taylor@Sun.COM /*
879517SBill.Taylor@Sun.COM  * Macro and defines used to calculate device instance number from minor
889517SBill.Taylor@Sun.COM  * number (and vice versa).
899517SBill.Taylor@Sun.COM  */
909517SBill.Taylor@Sun.COM #define	HERMON_MINORNUM_SHIFT		3
919517SBill.Taylor@Sun.COM #define	HERMON_DEV_INSTANCE(dev)	(getminor((dev)) &	\
929517SBill.Taylor@Sun.COM 	((1 << HERMON_MINORNUM_SHIFT) - 1))
939517SBill.Taylor@Sun.COM 
949517SBill.Taylor@Sun.COM /*
959517SBill.Taylor@Sun.COM  * Locations for the various Hermon hardware CMD,UAR & MSIx PCIe BARs
969517SBill.Taylor@Sun.COM  */
979517SBill.Taylor@Sun.COM #define	HERMON_CMD_BAR			1 /* device config space */
989517SBill.Taylor@Sun.COM #define	HERMON_UAR_BAR			2 /* UAR Region */
999517SBill.Taylor@Sun.COM #define	HERMON_MSIX_BAR			3 /* MSI-X Table */
1009517SBill.Taylor@Sun.COM 
1019517SBill.Taylor@Sun.COM #define	HERMON_ONCLOSE_FLASH_INPROGRESS		(1 << 0)
1029517SBill.Taylor@Sun.COM 
103*12965SWilliam.Taylor@Oracle.COM #define	HERMON_MSIX_MAX			256 /* max # of interrupt vectors */
1049517SBill.Taylor@Sun.COM 
1059517SBill.Taylor@Sun.COM /*
1069517SBill.Taylor@Sun.COM  * VPD header size - or more rightfully, the area of interest for fwflash
1079517SBill.Taylor@Sun.COM  * 	There's more, but we don't need it for our use so we don't read it
1089517SBill.Taylor@Sun.COM  */
1099517SBill.Taylor@Sun.COM #define	HERMON_VPD_HDR_DWSIZE		0x10 /* 16 Dwords */
1109517SBill.Taylor@Sun.COM #define	HERMON_VPD_HDR_BSIZE		0x40 /* 64 Bytes */
1119517SBill.Taylor@Sun.COM 
1129517SBill.Taylor@Sun.COM /*
1139517SBill.Taylor@Sun.COM  * Offsets to be used w/ reset to save/restore PCI capability stuff
1149517SBill.Taylor@Sun.COM  */
1159517SBill.Taylor@Sun.COM #define	HERMON_PCI_CAP_DEV_OFFS		0x08
1169517SBill.Taylor@Sun.COM #define	HERMON_PCI_CAP_LNK_OFFS		0x10
1179517SBill.Taylor@Sun.COM 
1189517SBill.Taylor@Sun.COM 
1199517SBill.Taylor@Sun.COM /*
1209517SBill.Taylor@Sun.COM  * Some defines for the software reset.  These define the value that should
1219517SBill.Taylor@Sun.COM  * be written to begin the reset (HERMON_SW_RESET_START), the delay before
1229517SBill.Taylor@Sun.COM  * beginning to poll for completion (HERMON_SW_RESET_DELAY), the in-between
1239517SBill.Taylor@Sun.COM  * polling delay (HERMON_SW_RESET_POLL_DELAY), and the value that indicates
1249517SBill.Taylor@Sun.COM  * that the reset has not completed (HERMON_SW_RESET_NOTDONE).
1259517SBill.Taylor@Sun.COM  */
1269517SBill.Taylor@Sun.COM #define	HERMON_SW_RESET_START		0x00000001
1279517SBill.Taylor@Sun.COM #define	HERMON_SW_RESET_DELAY		1000000	 /* 1000 ms, per 0.36 PRM */
1289517SBill.Taylor@Sun.COM #define	HERMON_SW_RESET_POLL_DELAY	100	 /* 100 us */
1299517SBill.Taylor@Sun.COM #define	HERMON_SW_RESET_NOTDONE		0xFFFFFFFF
1309517SBill.Taylor@Sun.COM 
1319517SBill.Taylor@Sun.COM /*
1329517SBill.Taylor@Sun.COM  * These defines are used in the Hermon software reset operation.  They define
1339517SBill.Taylor@Sun.COM  * the total number PCI registers to read/restore during the reset.  And they
1349517SBill.Taylor@Sun.COM  * also specify two config registers which should not be read or restored.
1359517SBill.Taylor@Sun.COM  */
1369517SBill.Taylor@Sun.COM #define	HERMON_SW_RESET_NUMREGS		0x40
1379517SBill.Taylor@Sun.COM #define	HERMON_SW_RESET_REG22_RSVD	0x16	/* 22 dec */
1389517SBill.Taylor@Sun.COM #define	HERMON_SW_RESET_REG23_RSVD	0x17  	/* 23 dec */
1399517SBill.Taylor@Sun.COM 
1409517SBill.Taylor@Sun.COM /*
1419517SBill.Taylor@Sun.COM  * Macro used to output HCA warning messages.  Note: HCA warning messages
1429517SBill.Taylor@Sun.COM  * are only generated when an unexpected condition has been detected.  This
143*12965SWilliam.Taylor@Oracle.COM  * can be the result of a software bug or some other problem.  Previously
144*12965SWilliam.Taylor@Oracle.COM  * this was used for hardware errors, but those now use HERMON_FMANOTE
145*12965SWilliam.Taylor@Oracle.COM  * instead, indicating that the driver state is more likely in an
146*12965SWilliam.Taylor@Oracle.COM  * unpredictable state, and that shutdown/restart is suggested.
147*12965SWilliam.Taylor@Oracle.COM  *
148*12965SWilliam.Taylor@Oracle.COM  * HERMON_WARNING messages are not considered important enough to print
149*12965SWilliam.Taylor@Oracle.COM  * to the console, just to the message log.
1509517SBill.Taylor@Sun.COM  */
1519517SBill.Taylor@Sun.COM #define	HERMON_WARNING(state, string)					\
152*12965SWilliam.Taylor@Oracle.COM 	cmn_err(CE_CONT, "!hermon%d: %s\n", (state)->hs_instance, string)
1539517SBill.Taylor@Sun.COM 
1549517SBill.Taylor@Sun.COM /*
1559517SBill.Taylor@Sun.COM  * Macro used to set attach failure messages.  Also, the attach message buf
1569517SBill.Taylor@Sun.COM  * size is set here.
1579517SBill.Taylor@Sun.COM  */
1589517SBill.Taylor@Sun.COM #define	HERMON_ATTACH_MSGSIZE	80
1599517SBill.Taylor@Sun.COM #define	HERMON_ATTACH_MSG(attach_buf, attach_msg)		\
1609517SBill.Taylor@Sun.COM 	(void) snprintf((attach_buf), HERMON_ATTACH_MSGSIZE, (attach_msg));
1619517SBill.Taylor@Sun.COM #define	HERMON_ATTACH_MSG_INIT(attach_buf)			\
1629517SBill.Taylor@Sun.COM 	(attach_buf)[0] = '\0';
1639517SBill.Taylor@Sun.COM 
1649517SBill.Taylor@Sun.COM /*
1659517SBill.Taylor@Sun.COM  * Macros used for controlling whether or not event callbacks will be forwarded
1669517SBill.Taylor@Sun.COM  * to the IBTF.  This is necessary because there are certain race conditions
1679517SBill.Taylor@Sun.COM  * that can occur (e.g. calling IBTF with an asynch event before the IBTF
1689517SBill.Taylor@Sun.COM  * registration has successfully completed or handling an event after we've
1699517SBill.Taylor@Sun.COM  * detached from the IBTF.)
1709517SBill.Taylor@Sun.COM  *
1719517SBill.Taylor@Sun.COM  * HERMON_ENABLE_IBTF_CALLB() initializes the "hs_ibtfpriv" field in the Hermon
1729517SBill.Taylor@Sun.COM  *    softstate.  When "hs_ibtfpriv" is non-NULL, it is OK to forward asynch
1739517SBill.Taylor@Sun.COM  *    and CQ events to the IBTF.
1749517SBill.Taylor@Sun.COM  *
1759517SBill.Taylor@Sun.COM  * HERMON_DO_IBTF_ASYNC_CALLB() and HERMON_DO_IBTF_CQ_CALLB() both set and clear
1769517SBill.Taylor@Sun.COM  *    the "hs_in_evcallb" flag, as necessary, to indicate that an IBTF
1779517SBill.Taylor@Sun.COM  *    callback is currently in progress.  This is necessary so that we can
1789517SBill.Taylor@Sun.COM  *    block on this condition in hermon_detach().
1799517SBill.Taylor@Sun.COM  *
1809517SBill.Taylor@Sun.COM  * HERMON_QUIESCE_IBTF_CALLB() is used in hermon_detach() to set the
1819517SBill.Taylor@Sun.COM  *    "hs_ibtfpriv" to NULL (thereby disabling any further IBTF callbacks)
1829517SBill.Taylor@Sun.COM  *    and to poll on the "hs_in_evcallb" flag.  When this flag is zero, all
1839517SBill.Taylor@Sun.COM  *    IBTF callbacks have quiesced and it is safe to continue with detach
1849517SBill.Taylor@Sun.COM  *    (i.e. continue detaching from IBTF).
1859517SBill.Taylor@Sun.COM  */
1869517SBill.Taylor@Sun.COM #define	HERMON_ENABLE_IBTF_CALLB(state, tmp_ibtfpriv)		\
1879517SBill.Taylor@Sun.COM 	(state)->hs_ibtfpriv = (tmp_ibtfpriv);
1889517SBill.Taylor@Sun.COM 
1899517SBill.Taylor@Sun.COM #define	HERMON_DO_IBTF_ASYNC_CALLB(state, type, event)	\
1909517SBill.Taylor@Sun.COM 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS((state)->hs_in_evcallb))	\
1919517SBill.Taylor@Sun.COM 	(state)->hs_in_evcallb = 1;					\
1929517SBill.Taylor@Sun.COM 	ibc_async_handler((state)->hs_ibtfpriv, (type), (event));	\
1939517SBill.Taylor@Sun.COM 	(state)->hs_in_evcallb = 0;
1949517SBill.Taylor@Sun.COM 
1959517SBill.Taylor@Sun.COM #define	HERMON_DO_IBTF_CQ_CALLB(state, cq)			\
1969517SBill.Taylor@Sun.COM 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS((state)->hs_in_evcallb))	\
1979517SBill.Taylor@Sun.COM 	(state)->hs_in_evcallb = 1;					\
1989517SBill.Taylor@Sun.COM 	ibc_cq_handler((state)->hs_ibtfpriv, (cq)->cq_hdlrarg);		\
1999517SBill.Taylor@Sun.COM 	(state)->hs_in_evcallb = 0;
2009517SBill.Taylor@Sun.COM 
2019517SBill.Taylor@Sun.COM #define	HERMON_QUIESCE_IBTF_CALLB(state)			\
2029517SBill.Taylor@Sun.COM {									\
2039517SBill.Taylor@Sun.COM 	uint_t		count = 0;					\
2049517SBill.Taylor@Sun.COM 									\
2059517SBill.Taylor@Sun.COM 	state->hs_ibtfpriv = NULL;					\
2069517SBill.Taylor@Sun.COM 	while (((state)->hs_in_evcallb != 0) &&				\
2079517SBill.Taylor@Sun.COM 	    (count++ < HERMON_QUIESCE_IBTF_CALLB_POLL_MAX)) {		\
2089517SBill.Taylor@Sun.COM 		drv_usecwait(HERMON_QUIESCE_IBTF_CALLB_POLL_DELAY);	\
2099517SBill.Taylor@Sun.COM 	}								\
2109517SBill.Taylor@Sun.COM }
2119517SBill.Taylor@Sun.COM 
2129517SBill.Taylor@Sun.COM /*
2139517SBill.Taylor@Sun.COM  * Defines used by the HERMON_QUIESCE_IBTF_CALLB() macro to determine the
2149517SBill.Taylor@Sun.COM  * duration and number of times (at maximum) to poll while waiting for IBTF
2159517SBill.Taylor@Sun.COM  * callbacks to quiesce.
2169517SBill.Taylor@Sun.COM  */
2179517SBill.Taylor@Sun.COM #define	HERMON_QUIESCE_IBTF_CALLB_POLL_DELAY	1
2189517SBill.Taylor@Sun.COM #define	HERMON_QUIESCE_IBTF_CALLB_POLL_MAX	1000000
2199517SBill.Taylor@Sun.COM 
2209517SBill.Taylor@Sun.COM /*
2219517SBill.Taylor@Sun.COM  * Macros to retrieve PCI id's of the device
2229517SBill.Taylor@Sun.COM  */
2239517SBill.Taylor@Sun.COM #define	HERMON_DDI_PROP_GET(dip, property) \
2249517SBill.Taylor@Sun.COM 	(ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, \
2259517SBill.Taylor@Sun.COM 	    property, -1))
2269517SBill.Taylor@Sun.COM 
2279517SBill.Taylor@Sun.COM #define	HERMON_GET_VENDOR_ID(dip)	HERMON_DDI_PROP_GET(dip, "vendor-id")
2289517SBill.Taylor@Sun.COM #define	HERMON_GET_DEVICE_ID(dip)	HERMON_DDI_PROP_GET(dip, "device-id")
2299517SBill.Taylor@Sun.COM #define	HERMON_GET_REVISION_ID(dip)	HERMON_DDI_PROP_GET(dip, "revision-id")
2309517SBill.Taylor@Sun.COM 
2319517SBill.Taylor@Sun.COM /*
23212688SWilliam.Taylor@Oracle.COM  * Defines used to record the device mode to which Hermon driver has been
23312688SWilliam.Taylor@Oracle.COM  * attached.  HERMON_MAINTENANCE_MODE is used when the device has
2349517SBill.Taylor@Sun.COM  * come up in the "maintenance mode".  In this mode, no InfiniBand interfaces
2359517SBill.Taylor@Sun.COM  * are enabled, but the device's firmware can be updated/flashed (and
2369517SBill.Taylor@Sun.COM  * test/debug interfaces should be useable).
23712688SWilliam.Taylor@Oracle.COM  * HERMON_HCA_MODE isused when the device has come up in the
2389517SBill.Taylor@Sun.COM  * normal HCA mode.  In this mode, all necessary InfiniBand interfaces are
2399517SBill.Taylor@Sun.COM  * enabled (and, if necessary, HERMON firmware can be updated/flashed).
2409517SBill.Taylor@Sun.COM  */
24112688SWilliam.Taylor@Oracle.COM #define	HERMON_MAINTENANCE_MODE	1
2429517SBill.Taylor@Sun.COM #define	HERMON_HCA_MODE		2
2439517SBill.Taylor@Sun.COM 
2449517SBill.Taylor@Sun.COM /*
2459517SBill.Taylor@Sun.COM  * Used to determine if the device is operational, or not in maintenance mode.
2469517SBill.Taylor@Sun.COM  * This means either the driver has attached successfully against an hermon
2479517SBill.Taylor@Sun.COM  * device in hermon compatibility mode, or against a hermon device in full HCA
2489517SBill.Taylor@Sun.COM  * mode.
2499517SBill.Taylor@Sun.COM  */
2509517SBill.Taylor@Sun.COM #define	HERMON_IS_OPERATIONAL(mode)				\
2519517SBill.Taylor@Sun.COM 	(mode == HERMON_HCA_MODE)
2529517SBill.Taylor@Sun.COM 
2539517SBill.Taylor@Sun.COM /*
2549517SBill.Taylor@Sun.COM  * The following define is used (in hermon_umap_db_set_onclose_cb()) to
2559517SBill.Taylor@Sun.COM  * indicate that a cleanup callback is needed to undo initialization done
2569517SBill.Taylor@Sun.COM  * by the firmware flash burn code.
2579517SBill.Taylor@Sun.COM  */
2589517SBill.Taylor@Sun.COM #define	HERMON_ONCLOSE_FLASH_INPROGRESS		(1 << 0)
2599517SBill.Taylor@Sun.COM 
2609517SBill.Taylor@Sun.COM /*
2619517SBill.Taylor@Sun.COM  * The following enumerated type and structures are used during driver
2629517SBill.Taylor@Sun.COM  * initialization.  Note: The HERMON_DRV_CLEANUP_ALL type is used as a marker
2639517SBill.Taylor@Sun.COM  * for end of the cleanup steps.  No cleanup steps should be added after
2649517SBill.Taylor@Sun.COM  * HERMON_DRV_CLEANUP_ALL.  Any addition steps should be added before it.
2659517SBill.Taylor@Sun.COM  */
2669517SBill.Taylor@Sun.COM typedef enum {
2679517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL0,
2689517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL1,
2699517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL2,
2709517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL3,
2719517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL4,
2729517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL5,
2739517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL6,
2749517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL7,
2759517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL8,
2769517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL9,
2779517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL10,
2789517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL11,
2799517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL12,
2809517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL13,
2819517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL14,
2829517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL15,
2839517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL16,
2849517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL17,
2859517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL18,
2869517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_LEVEL19,
2879517SBill.Taylor@Sun.COM 	/* No more driver cleanup steps below this point! */
2889517SBill.Taylor@Sun.COM 	HERMON_DRV_CLEANUP_ALL
2899517SBill.Taylor@Sun.COM } hermon_drv_cleanup_level_t;
2909517SBill.Taylor@Sun.COM 
2919517SBill.Taylor@Sun.COM /*
2929517SBill.Taylor@Sun.COM  * The hermon_dma_info_t structure is used to store information related to
2939517SBill.Taylor@Sun.COM  * the various ICM resources' DMA allocations.  The related ICM table and
2949517SBill.Taylor@Sun.COM  * virtual address are stored here.  The DMA and Access handles are stored
2959517SBill.Taylor@Sun.COM  * here.  Also, the allocation length and virtual (host) address.
2969517SBill.Taylor@Sun.COM  */
2979517SBill.Taylor@Sun.COM struct hermon_dma_info_s {
2989517SBill.Taylor@Sun.COM 	ddi_dma_handle_t	dma_hdl;
2999517SBill.Taylor@Sun.COM 	ddi_acc_handle_t	acc_hdl;
3009517SBill.Taylor@Sun.COM 	uint64_t		icmaddr;	/* ICM virtual address */
3019517SBill.Taylor@Sun.COM 	uint64_t		vaddr;  	/* host virtual address */
3029517SBill.Taylor@Sun.COM 	uint_t			length;		/* length requested */
3039517SBill.Taylor@Sun.COM 	uint_t			icm_refcnt;	/* refcnt */
3049517SBill.Taylor@Sun.COM };
3059517SBill.Taylor@Sun.COM _NOTE(SCHEME_PROTECTS_DATA("safe sharing",
3069517SBill.Taylor@Sun.COM     hermon_dma_info_s::icm_refcnt))
3079517SBill.Taylor@Sun.COM 
3089517SBill.Taylor@Sun.COM 
3099517SBill.Taylor@Sun.COM /*
3109517SBill.Taylor@Sun.COM  * The hermon_cmd_reg_t structure is used to hold the address of the each of
3119517SBill.Taylor@Sun.COM  * the most frequently accessed hardware registers.  Specifically, it holds
3129517SBill.Taylor@Sun.COM  * the HCA Command Registers (HCR, used to pass command and mailbox
3139517SBill.Taylor@Sun.COM  * information back and forth to Hermon firmware) and the lock used to guarantee
3149517SBill.Taylor@Sun.COM  * mutually exclusive access to the registers.
3159517SBill.Taylor@Sun.COM  * Related to this, is the "clr_int" register which is used to clear the
3169517SBill.Taylor@Sun.COM  * interrupt once all EQs have been serviced.
3179517SBill.Taylor@Sun.COM  * Finally, there is the software reset register which is used to reinitialize
3189517SBill.Taylor@Sun.COM  * the Hermon device and to put it into a known state at driver startup time.
3199517SBill.Taylor@Sun.COM  * Below we also have the offsets (into the CMD register space) for each of
3209517SBill.Taylor@Sun.COM  * the various registers.
3219517SBill.Taylor@Sun.COM  */
3229517SBill.Taylor@Sun.COM typedef struct hermon_cmd_reg_s {
3239517SBill.Taylor@Sun.COM 	hermon_hw_hcr_t	*hcr;
3249517SBill.Taylor@Sun.COM 	kmutex_t	hcr_lock;
3259517SBill.Taylor@Sun.COM 	uint64_t	*clr_intr;
3269517SBill.Taylor@Sun.COM 	uint64_t	*eq_arm;
3279517SBill.Taylor@Sun.COM 	uint64_t	*eq_set_ci;
3289517SBill.Taylor@Sun.COM 	uint32_t	*sw_reset;
3299517SBill.Taylor@Sun.COM 	uint32_t	*sw_semaphore;
3309517SBill.Taylor@Sun.COM 	uint32_t	*fw_err_buf;
3319517SBill.Taylor@Sun.COM } hermon_cmd_reg_t;
3329517SBill.Taylor@Sun.COM _NOTE(MUTEX_PROTECTS_DATA(hermon_cmd_reg_t::hcr_lock,
3339517SBill.Taylor@Sun.COM     hermon_cmd_reg_t::hcr))
3349517SBill.Taylor@Sun.COM 
3359517SBill.Taylor@Sun.COM /* SOME TEMPORARY PRINTING THINGS */
3369517SBill.Taylor@Sun.COM #define	HERMON_PRINT_CI		(0x01 << 0)
3379517SBill.Taylor@Sun.COM #define	HERMON_PRINT_MEM	(0x01 << 1)
3389517SBill.Taylor@Sun.COM #define	HERMON_PRINT_CQ		(0x01 << 2)
3399517SBill.Taylor@Sun.COM 
3409517SBill.Taylor@Sun.COM 
3419517SBill.Taylor@Sun.COM #define	HD_PRINT(state, mask)	\
3429517SBill.Taylor@Sun.COM 	if (state->hs_debug_lev & mask)
3439517SBill.Taylor@Sun.COM 
3449517SBill.Taylor@Sun.COM /* END PRINTING THINGS */
3459517SBill.Taylor@Sun.COM 
3469517SBill.Taylor@Sun.COM /*
3479517SBill.Taylor@Sun.COM  * The hermon_state_t structure is the HCA software state structure.  It
3489517SBill.Taylor@Sun.COM  * contains all the pointers and placeholder for everything that the HCA
3499517SBill.Taylor@Sun.COM  * driver needs to properly operate.  One of these structures exists for
3509517SBill.Taylor@Sun.COM  * every instance of the HCA driver.
3519517SBill.Taylor@Sun.COM  */
3529517SBill.Taylor@Sun.COM struct hermon_state_s {
3539517SBill.Taylor@Sun.COM 	dev_info_t		*hs_dip;
3549517SBill.Taylor@Sun.COM 	int			hs_instance;
355*12965SWilliam.Taylor@Oracle.COM 
3569517SBill.Taylor@Sun.COM 	/* PCI device, vendor, and revision IDs */
3579517SBill.Taylor@Sun.COM 	uint16_t		hs_vendor_id;
3589517SBill.Taylor@Sun.COM 	uint16_t		hs_device_id;
3599517SBill.Taylor@Sun.COM 	uint8_t			hs_revision_id;
3609517SBill.Taylor@Sun.COM 
3619517SBill.Taylor@Sun.COM 	/*
3629517SBill.Taylor@Sun.COM 	 * DMA information for the InfiniHost Context Memory (ICM),
3639517SBill.Taylor@Sun.COM 	 * ICM Auxiliary allocation and the firmware. Also, record
3649517SBill.Taylor@Sun.COM 	 * of ICM and ICMA sizes, in bytes.
3659517SBill.Taylor@Sun.COM 	 */
3669517SBill.Taylor@Sun.COM 
3679517SBill.Taylor@Sun.COM 	uint64_t		hs_icm_sz;
3689517SBill.Taylor@Sun.COM 	hermon_icm_table_t	*hs_icm;
3699517SBill.Taylor@Sun.COM 	uint64_t		hs_icma_sz;
3709517SBill.Taylor@Sun.COM 	hermon_dma_info_t	hs_icma_dma;
3719517SBill.Taylor@Sun.COM 	hermon_dma_info_t	hs_fw_dma;
3729517SBill.Taylor@Sun.COM 
3739517SBill.Taylor@Sun.COM 	/* Hermon interrupt/MSI information */
3749517SBill.Taylor@Sun.COM 	int			hs_intr_types_avail;
3759517SBill.Taylor@Sun.COM 	uint_t			hs_intr_type_chosen;
3769517SBill.Taylor@Sun.COM 	int			hs_intrmsi_count;
3779517SBill.Taylor@Sun.COM 	int			hs_intrmsi_avail;
3789517SBill.Taylor@Sun.COM 	int			hs_intrmsi_allocd;
3799517SBill.Taylor@Sun.COM 	ddi_intr_handle_t	hs_intrmsi_hdl[HERMON_MSIX_MAX];
3809517SBill.Taylor@Sun.COM 	uint_t			hs_intrmsi_pri;
3819517SBill.Taylor@Sun.COM 	int			hs_intrmsi_cap;
382*12965SWilliam.Taylor@Oracle.COM 	ddi_cb_handle_t		hs_intr_cb_hdl;
3839517SBill.Taylor@Sun.COM 
384*12965SWilliam.Taylor@Oracle.COM 	/* Do not use reserved EQs */
385*12965SWilliam.Taylor@Oracle.COM 	uint_t			hs_rsvd_eqs;
386*12965SWilliam.Taylor@Oracle.COM 	uint_t			hs_cq_erreqnum;
387*12965SWilliam.Taylor@Oracle.COM 
388*12965SWilliam.Taylor@Oracle.COM 	/* cq_sched data */
389*12965SWilliam.Taylor@Oracle.COM 	kmutex_t		hs_cq_sched_lock;
390*12965SWilliam.Taylor@Oracle.COM 	hermon_cq_sched_t	*hs_cq_sched_array;
391*12965SWilliam.Taylor@Oracle.COM 	hermon_cq_sched_t	hs_cq_sched_default;
392*12965SWilliam.Taylor@Oracle.COM 	uint_t			hs_cq_sched_array_size;
3939517SBill.Taylor@Sun.COM 
3949517SBill.Taylor@Sun.COM 	/* hermon HCA name and HCA part number */
3959517SBill.Taylor@Sun.COM 	char			hs_hca_name[64];
3969517SBill.Taylor@Sun.COM 	char			hs_hca_pn[64];
3979517SBill.Taylor@Sun.COM 	int			hs_hca_pn_len;
3989517SBill.Taylor@Sun.COM 
3999517SBill.Taylor@Sun.COM 	/* Hermon device operational mode */
4009517SBill.Taylor@Sun.COM 	int			hs_operational_mode;
4019517SBill.Taylor@Sun.COM 
4029517SBill.Taylor@Sun.COM 	/* Attach buffer saved per state to store detailed attach errors */
4039517SBill.Taylor@Sun.COM 	char			hs_attach_buf[HERMON_ATTACH_MSGSIZE];
4049517SBill.Taylor@Sun.COM 
4059517SBill.Taylor@Sun.COM 	/* Hermon NodeGUID, SystemImageGUID, and NodeDescription */
4069517SBill.Taylor@Sun.COM 	uint64_t		hs_nodeguid;
4079517SBill.Taylor@Sun.COM 	uint64_t		hs_sysimgguid;
4089517SBill.Taylor@Sun.COM 	char			hs_nodedesc[64];
4099517SBill.Taylor@Sun.COM 
4109517SBill.Taylor@Sun.COM 	/* Info passed to IBTF during registration */
4119517SBill.Taylor@Sun.COM 	ibc_hca_info_t		hs_ibtfinfo;
4129517SBill.Taylor@Sun.COM 	ibc_clnt_hdl_t		hs_ibtfpriv;
4139517SBill.Taylor@Sun.COM 
4149517SBill.Taylor@Sun.COM 	/*
4159517SBill.Taylor@Sun.COM 	 * Hermon register mapping.  Holds the device access attributes,
4169517SBill.Taylor@Sun.COM 	 * kernel mapped addresses, and DDI access handles for both
4179517SBill.Taylor@Sun.COM 	 * Hermon's CMD and UAR BARs.
4189517SBill.Taylor@Sun.COM 	 */
4199517SBill.Taylor@Sun.COM 	ddi_device_acc_attr_t	hs_reg_accattr;
4209517SBill.Taylor@Sun.COM 	caddr_t			hs_reg_cmd_baseaddr;	/* Hermon CMD BAR */
4219517SBill.Taylor@Sun.COM 	ddi_acc_handle_t	hs_reg_cmdhdl;
4229517SBill.Taylor@Sun.COM 	caddr_t			hs_reg_uar_baseaddr;	/* Hermon UAR BAR */
4239517SBill.Taylor@Sun.COM 	ddi_acc_handle_t	hs_reg_uarhdl;
4249517SBill.Taylor@Sun.COM 	caddr_t			hs_reg_msi_baseaddr;	/* Hermon MSIx BAR */
4259517SBill.Taylor@Sun.COM 	ddi_acc_handle_t	hs_reg_msihdl;
4269517SBill.Taylor@Sun.COM 
4279517SBill.Taylor@Sun.COM 	/*
4289517SBill.Taylor@Sun.COM 	 * Some additional things for UAR Pages
4299517SBill.Taylor@Sun.COM 	 */
4309517SBill.Taylor@Sun.COM 	uint64_t		hs_kernel_uar_index;	/* kernel UAR index */
4319517SBill.Taylor@Sun.COM 	uint64_t		hs_bf_offset;		/* offset from UAR */
4329517SBill.Taylor@Sun.COM 							/* Bar to Blueflame */
4339517SBill.Taylor@Sun.COM 	caddr_t			hs_reg_bf_baseaddr;	/* blueflame base */
4349517SBill.Taylor@Sun.COM 	ddi_acc_handle_t	hs_reg_bfhdl;  		/* blueflame handle */
4359517SBill.Taylor@Sun.COM 
4369517SBill.Taylor@Sun.COM 
4379517SBill.Taylor@Sun.COM 	/*
4389517SBill.Taylor@Sun.COM 	 * Hermon PCI config space registers.  This array is used to
4399517SBill.Taylor@Sun.COM 	 * save and restore the PCI config registers before and after a
4409517SBill.Taylor@Sun.COM 	 * software reset.
4419517SBill.Taylor@Sun.COM 	 */
4429517SBill.Taylor@Sun.COM 	uint32_t		hs_cfg_data[HERMON_SW_RESET_NUMREGS];
4439517SBill.Taylor@Sun.COM 	/* for reset per Linux driver */
4449517SBill.Taylor@Sun.COM 	uint32_t		hs_pci_cap_offset;
4459517SBill.Taylor@Sun.COM 	uint32_t		hs_pci_cap_devctl;
4469517SBill.Taylor@Sun.COM 	uint32_t		hs_pci_cap_lnkctl;
4479517SBill.Taylor@Sun.COM 
4489517SBill.Taylor@Sun.COM 	/*
4499517SBill.Taylor@Sun.COM 	 * Hermon UAR page resources.  Holds the resource pointers for
4509517SBill.Taylor@Sun.COM 	 * UAR page #0 (reserved) and for UAR page #1 (used for kernel
4519517SBill.Taylor@Sun.COM 	 * driver doorbells).  In addition, we save a pointer to the
4529517SBill.Taylor@Sun.COM 	 * UAR page #1 doorbells which will be used throughout the driver
4539517SBill.Taylor@Sun.COM 	 * whenever it is necessary to ring one of them.  And, in case we
4549517SBill.Taylor@Sun.COM 	 * are unable to do 64-bit writes to the page (because of system
4559517SBill.Taylor@Sun.COM 	 * architecture), we include a lock (to ensure atomic 64-bit access).
4569517SBill.Taylor@Sun.COM 	 */
4579517SBill.Taylor@Sun.COM 	hermon_rsrc_t		*hs_uarpg0_rsrc_rsrvd;
4589517SBill.Taylor@Sun.COM 	hermon_rsrc_t		*hs_uarkpg_rsrc;
4599517SBill.Taylor@Sun.COM 	hermon_hw_uar_t		*hs_uar;
4609517SBill.Taylor@Sun.COM 	kmutex_t		hs_uar_lock;
4619517SBill.Taylor@Sun.COM 
4629517SBill.Taylor@Sun.COM 	/*
4639517SBill.Taylor@Sun.COM 	 * Used during a call to open() if we are in maintenance mode, this
4649517SBill.Taylor@Sun.COM 	 * field serves as a semi-unique rolling count index value, used only
4659517SBill.Taylor@Sun.COM 	 * in the setup of umap_db entries.  This is primarily needed to
4669517SBill.Taylor@Sun.COM 	 * firmware device access ioctl operations can still be guaranteed to
4679517SBill.Taylor@Sun.COM 	 * close in the event of an unplanned process exit, even in maintenance
4689517SBill.Taylor@Sun.COM 	 * mode.
4699517SBill.Taylor@Sun.COM 	 */
4709517SBill.Taylor@Sun.COM 	uint_t			hs_open_ar_indx;
4719517SBill.Taylor@Sun.COM 
4729517SBill.Taylor@Sun.COM 	/*
4739517SBill.Taylor@Sun.COM 	 * Hermon command registers.  This structure contains the addresses
4749517SBill.Taylor@Sun.COM 	 * for each of the most frequently accessed CMD registers.  Since
4759517SBill.Taylor@Sun.COM 	 * almost all accesses to the Hermon hardware are through the Hermon
4769517SBill.Taylor@Sun.COM 	 * command interface (i.e. the HCR), we save away the pointer to
4779517SBill.Taylor@Sun.COM 	 * the HCR, as well as pointers to the ECR and INT registers (as
4789517SBill.Taylor@Sun.COM 	 * well as their corresponding "clear" registers) for interrupt
4799517SBill.Taylor@Sun.COM 	 * processing.  And we also save away a pointer to the software
4809517SBill.Taylor@Sun.COM 	 * reset register (see above).
4819517SBill.Taylor@Sun.COM 	 */
4829517SBill.Taylor@Sun.COM 	hermon_cmd_reg_t	hs_cmd_regs;
4839517SBill.Taylor@Sun.COM 	uint32_t		hs_cmd_toggle;
4849517SBill.Taylor@Sun.COM 
4859517SBill.Taylor@Sun.COM 	/*
4869517SBill.Taylor@Sun.COM 	 * Hermon resource pointers.  The following are pointers to the
4879517SBill.Taylor@Sun.COM 	 * kmem cache (from which the Hermon resource handles are allocated),
4889517SBill.Taylor@Sun.COM 	 * and the array of "resource pools" (which store all the pertinent
4899517SBill.Taylor@Sun.COM 	 * information necessary to manage each of the various types of
4909517SBill.Taylor@Sun.COM 	 * resources that are used by the driver.  See hermon_rsrc.h for
4919517SBill.Taylor@Sun.COM 	 * more detail.
4929517SBill.Taylor@Sun.COM 	 */
4939517SBill.Taylor@Sun.COM 	kmem_cache_t		*hs_rsrc_cache;
4949517SBill.Taylor@Sun.COM 	hermon_rsrc_pool_info_t	*hs_rsrc_hdl;
4959517SBill.Taylor@Sun.COM 
4969517SBill.Taylor@Sun.COM 	/*
4979517SBill.Taylor@Sun.COM 	 * Hermon mailbox lists.  These hold the information necessary to
4989517SBill.Taylor@Sun.COM 	 * manage the pools of pre-allocated Hermon mailboxes (both "In" and
4999517SBill.Taylor@Sun.COM 	 * "Out" type).  See hermon_cmd.h for more detail.
5009517SBill.Taylor@Sun.COM 	 */
5019517SBill.Taylor@Sun.COM 	hermon_mboxlist_t	hs_in_mblist;
5029517SBill.Taylor@Sun.COM 	hermon_mboxlist_t	hs_out_mblist;
5039517SBill.Taylor@Sun.COM 
5049517SBill.Taylor@Sun.COM 	/*
5059517SBill.Taylor@Sun.COM 	 * Hermon interrupt mailbox lists.  We allocate both an "In" mailbox
5069517SBill.Taylor@Sun.COM 	 * and an "Out" type mailbox for the interrupt context.  This is in
5079517SBill.Taylor@Sun.COM 	 * order to guarantee that a mailbox entry will always be available in
5089517SBill.Taylor@Sun.COM 	 * the interrupt context, and we can NOSLEEP without having to worry
5099517SBill.Taylor@Sun.COM 	 * about possible failure allocating the mbox.  We create this as an
5109517SBill.Taylor@Sun.COM 	 * mboxlist so that we have the potential for having multiple mboxes
5119517SBill.Taylor@Sun.COM 	 * available based on the number of interrupts we can receive at once.
5129517SBill.Taylor@Sun.COM 	 */
5139517SBill.Taylor@Sun.COM 	hermon_mboxlist_t	hs_in_intr_mblist;
5149517SBill.Taylor@Sun.COM 	hermon_mboxlist_t	hs_out_intr_mblist;
5159517SBill.Taylor@Sun.COM 
5169517SBill.Taylor@Sun.COM 	/*
5179517SBill.Taylor@Sun.COM 	 * Hermon outstanding command list.  Used to hold all the information
5189517SBill.Taylor@Sun.COM 	 * necessary to manage the Hermon "outstanding command list".  See
5199517SBill.Taylor@Sun.COM 	 * hermon_cmd.h for more detail.
5209517SBill.Taylor@Sun.COM 	 */
5219517SBill.Taylor@Sun.COM 	hermon_cmdlist_t	hs_cmd_list;
5229517SBill.Taylor@Sun.COM 
5239517SBill.Taylor@Sun.COM 	/*
5249517SBill.Taylor@Sun.COM 	 * This structure contains the Hermon driver's "configuration profile".
5259517SBill.Taylor@Sun.COM 	 * This is the collected set of configuration information, such as
5269517SBill.Taylor@Sun.COM 	 * number of QPs, CQs, mailboxes and other resources, sizes of
5279517SBill.Taylor@Sun.COM 	 * individual resources, other system level configuration information,
5289517SBill.Taylor@Sun.COM 	 * etc.  See hermon_cfg.h for more detail.
5299517SBill.Taylor@Sun.COM 	 */
5309517SBill.Taylor@Sun.COM 	hermon_cfg_profile_t	*hs_cfg_profile;
5319517SBill.Taylor@Sun.COM 
5329517SBill.Taylor@Sun.COM 	/*
5339517SBill.Taylor@Sun.COM 	 * This flag contains the profile setting, selecting which profile the
5349517SBill.Taylor@Sun.COM 	 * driver would use.  This is needed in the case where we have to
5359517SBill.Taylor@Sun.COM 	 * fallback to a smaller profile based on some DDR conditions.  If we
5369517SBill.Taylor@Sun.COM 	 * don't fallback, then it is set to the size of DDR in the system.
5379517SBill.Taylor@Sun.COM 	 */
5389517SBill.Taylor@Sun.COM 	uint32_t		hs_cfg_profile_setting;
5399517SBill.Taylor@Sun.COM 
5409517SBill.Taylor@Sun.COM 	/*
5419517SBill.Taylor@Sun.COM 	 * The following are a collection of resource handles used by the
5429517SBill.Taylor@Sun.COM 	 * Hermon driver (internally).  First is the protection domain (PD)
5439517SBill.Taylor@Sun.COM 	 * handle that is used when mapping all kernel memory (work queues,
5449517SBill.Taylor@Sun.COM 	 * completion queues, etc).  Next is an array of EQ handles.  This
5459517SBill.Taylor@Sun.COM 	 * array is indexed by EQ number and allows the Hermon driver to quickly
5469517SBill.Taylor@Sun.COM 	 * convert an EQ number into the software structure associated with the
5479517SBill.Taylor@Sun.COM 	 * given EQ.  Likewise, we have three arrays for CQ, QP and SRQ
5489517SBill.Taylor@Sun.COM 	 * handles.  These arrays are also indexed by CQ, QP or SRQ number and
5499517SBill.Taylor@Sun.COM 	 * allow the driver to quickly find the corresponding CQ, QP or SRQ
5509517SBill.Taylor@Sun.COM 	 * software structure.  Note: while the EQ table is of fixed size
5519517SBill.Taylor@Sun.COM 	 * (because there are a maximum of 64 EQs), each of the CQ, QP and SRQ
5529517SBill.Taylor@Sun.COM 	 * handle lists must be allocated at driver startup.
5539517SBill.Taylor@Sun.COM 	 */
5549517SBill.Taylor@Sun.COM 	hermon_pdhdl_t		hs_pdhdl_internal;
5559517SBill.Taylor@Sun.COM 	hermon_eqhdl_t		hs_eqhdl[HERMON_NUM_EQ];
5569517SBill.Taylor@Sun.COM 	kmutex_t		hs_dbr_lock;	/* lock for dbr mgmt */
5579517SBill.Taylor@Sun.COM 
55810027SGiri.Adari@Sun.COM 	/* linked list of kernel dbr resources */
55910027SGiri.Adari@Sun.COM 	hermon_dbr_info_t	*hs_kern_dbr;
56010027SGiri.Adari@Sun.COM 
56110027SGiri.Adari@Sun.COM 	/* linked list of non-kernel dbr resources */
5629517SBill.Taylor@Sun.COM 	hermon_user_dbr_t	*hs_user_dbr;
5639517SBill.Taylor@Sun.COM 
5649517SBill.Taylor@Sun.COM 	/*
5659517SBill.Taylor@Sun.COM 	 * The AVL tree is used to store information regarding QP number
5669517SBill.Taylor@Sun.COM 	 * allocations.  The lock protects access to the AVL tree.
5679517SBill.Taylor@Sun.COM 	 */
5689517SBill.Taylor@Sun.COM 	avl_tree_t		hs_qpn_avl;
5699517SBill.Taylor@Sun.COM 	kmutex_t		hs_qpn_avl_lock;
5709517SBill.Taylor@Sun.COM 
5719517SBill.Taylor@Sun.COM 	/*
5729517SBill.Taylor@Sun.COM 	 * This field is used to indicate whether or not the Hermon driver is
5739517SBill.Taylor@Sun.COM 	 * currently in an IBTF event callback elsewhere in the system.  Note:
5749517SBill.Taylor@Sun.COM 	 * It is "volatile" because we intend to poll on this value - in
5759517SBill.Taylor@Sun.COM 	 * hermon_detach() - until we are assured that no further IBTF callbacks
5769517SBill.Taylor@Sun.COM 	 * are currently being processed.
5779517SBill.Taylor@Sun.COM 	 */
5789517SBill.Taylor@Sun.COM 	volatile uint32_t	hs_in_evcallb;
5799517SBill.Taylor@Sun.COM 
5809517SBill.Taylor@Sun.COM 	/*
5819517SBill.Taylor@Sun.COM 	 * The following structures are used to store the results of several
5829517SBill.Taylor@Sun.COM 	 * device query commands passed to the Hermon hardware at startup.
5839517SBill.Taylor@Sun.COM 	 * Specifically, we have hung onto the results of QUERY_DDR (which
5849517SBill.Taylor@Sun.COM 	 * gives information about how much DDR memory is present and where
5859517SBill.Taylor@Sun.COM 	 * it is located), QUERY_FW (which gives information about firmware
5869517SBill.Taylor@Sun.COM 	 * version numbers and the location and extent of firmware's footprint
5879517SBill.Taylor@Sun.COM 	 * in DDR, QUERY_DEVLIM (which gives the device limitations/resource
5889517SBill.Taylor@Sun.COM 	 * maximums) and QUERY_PORT (where some of the specs from DEVLIM moved),
5899517SBill.Taylor@Sun.COM 	 * QUERY_ADAPTER (which gives additional miscellaneous
5909517SBill.Taylor@Sun.COM 	 * information), and INIT/QUERY_HCA (which serves the purpose of
5919517SBill.Taylor@Sun.COM 	 * recording what configuration information was passed to the firmware
5929517SBill.Taylor@Sun.COM 	 * when the HCA was initialized).
5939517SBill.Taylor@Sun.COM 	 */
5949517SBill.Taylor@Sun.COM 	struct hermon_hw_queryfw_s	hs_fw;
5959517SBill.Taylor@Sun.COM 	struct hermon_hw_querydevlim_s	hs_devlim;
5969517SBill.Taylor@Sun.COM 	struct hermon_hw_query_port_s	hs_queryport;
5979517SBill.Taylor@Sun.COM 	struct hermon_hw_set_port_s 	*hs_initport;
5989517SBill.Taylor@Sun.COM 	struct hermon_hw_queryadapter_s	hs_adapter;
5999517SBill.Taylor@Sun.COM 	struct hermon_hw_initqueryhca_s	hs_hcaparams;
6009517SBill.Taylor@Sun.COM 
6019517SBill.Taylor@Sun.COM 	/*
6029517SBill.Taylor@Sun.COM 	 * The following are used for managing special QP resources.
6039517SBill.Taylor@Sun.COM 	 * Specifically, we have a lock, a set of flags (in "hs_spec_qpflags")
6049517SBill.Taylor@Sun.COM 	 * used to track the special QP resources, and two Hermon resource
6059517SBill.Taylor@Sun.COM 	 * handle pointers.  Each resource handle actually corresponds to two
6069517SBill.Taylor@Sun.COM 	 * consecutive QP contexts (one per port) for each special QP type.
6079517SBill.Taylor@Sun.COM 	 */
6089517SBill.Taylor@Sun.COM 	kmutex_t		hs_spec_qplock;
6099517SBill.Taylor@Sun.COM 	uint_t			hs_spec_qpflags;
6109517SBill.Taylor@Sun.COM 	hermon_rsrc_t		*hs_spec_qp0;
6119517SBill.Taylor@Sun.COM 	hermon_rsrc_t		*hs_spec_qp1;
6129517SBill.Taylor@Sun.COM 	/*
6139517SBill.Taylor@Sun.COM 	 * For Hermon, you have to alloc 8 qp's total, but the last 4 are
6149517SBill.Taylor@Sun.COM 	 * unused/reserved.  The following represents the handle for those
6159517SBill.Taylor@Sun.COM 	 * last 4 qp's
6169517SBill.Taylor@Sun.COM 	 */
6179517SBill.Taylor@Sun.COM 	hermon_rsrc_t		*hs_spec_qp_unused;
6189517SBill.Taylor@Sun.COM 
6199517SBill.Taylor@Sun.COM 	/*
6209517SBill.Taylor@Sun.COM 	 * Related in some ways to the special QP handling above are these
6219517SBill.Taylor@Sun.COM 	 * resources which are used specifically for implementing the Hermon
6229517SBill.Taylor@Sun.COM 	 * agents (SMA, PMA, and BMA).  Although, each of these agents does
6239517SBill.Taylor@Sun.COM 	 * little more that intercept the appropriate incoming MAD and forward
6249517SBill.Taylor@Sun.COM 	 * it along to the firmware (see hermon_agents.c for more details), we
6259517SBill.Taylor@Sun.COM 	 * do still use a task queue to queue them up.  We can also configure
6269517SBill.Taylor@Sun.COM 	 * the driver to force firmware handling for certain classes of MAD,
6279517SBill.Taylor@Sun.COM 	 * and, therefore, we require the agent list and number of agents
6289517SBill.Taylor@Sun.COM 	 * in order to know what needs to be torn down at detach() time.
6299517SBill.Taylor@Sun.COM 	 */
6309517SBill.Taylor@Sun.COM 	hermon_agent_list_t	*hs_agents;
6319517SBill.Taylor@Sun.COM 	ddi_taskq_t		*hs_taskq_agents;
6329517SBill.Taylor@Sun.COM 	uint_t			hs_num_agents;
6339517SBill.Taylor@Sun.COM 
6349517SBill.Taylor@Sun.COM 	/*
6359517SBill.Taylor@Sun.COM 	 * Multicast group lists.  These are used to track the "shadow" MCG
6369517SBill.Taylor@Sun.COM 	 * lists that speed up the processing of attach and detach multicast
6379517SBill.Taylor@Sun.COM 	 * group operations.  See hermon_misc.h for more details.  Note: we
6389517SBill.Taylor@Sun.COM 	 * need the pointer to the "temporary" MCG entry here primarily
6399517SBill.Taylor@Sun.COM 	 * because the size of a given MCG entry is configurable.  Therefore,
6409517SBill.Taylor@Sun.COM 	 * it is impossible to put this variable on the stack.  And rather
6419517SBill.Taylor@Sun.COM 	 * than allocate and deallocate the entry multiple times, we choose
6429517SBill.Taylor@Sun.COM 	 * instead to preallocate it once and reuse it over and over again.
6439517SBill.Taylor@Sun.COM 	 */
6449517SBill.Taylor@Sun.COM 	kmutex_t		hs_mcglock;
6459517SBill.Taylor@Sun.COM 	hermon_mcghdl_t		hs_mcghdl;
6469517SBill.Taylor@Sun.COM 	hermon_hw_mcg_t		*hs_mcgtmp;
6479517SBill.Taylor@Sun.COM 
6489517SBill.Taylor@Sun.COM 	/*
6499517SBill.Taylor@Sun.COM 	 * Cache of the pkey table, sgid (guid-only) tables, and
6509517SBill.Taylor@Sun.COM 	 * sgid (subnet) prefix.  These arrays are set
6519517SBill.Taylor@Sun.COM 	 * during port_query, and mainly used for generating MLX GSI wqes.
6529517SBill.Taylor@Sun.COM 	 */
6539517SBill.Taylor@Sun.COM 	ib_pkey_t		*hs_pkey[HERMON_MAX_PORTS];
6549517SBill.Taylor@Sun.COM 	ib_sn_prefix_t		hs_sn_prefix[HERMON_MAX_PORTS];
6559517SBill.Taylor@Sun.COM 	ib_guid_t		*hs_guid[HERMON_MAX_PORTS];
6569517SBill.Taylor@Sun.COM 
6579517SBill.Taylor@Sun.COM 	/*
6589517SBill.Taylor@Sun.COM 	 * Used for tracking Hermon kstat information
6599517SBill.Taylor@Sun.COM 	 */
6609517SBill.Taylor@Sun.COM 	hermon_ks_info_t	*hs_ks_info;
6619517SBill.Taylor@Sun.COM 
6629517SBill.Taylor@Sun.COM 	/*
6639517SBill.Taylor@Sun.COM 	 * Used for Hermon info ioctl used by VTS
6649517SBill.Taylor@Sun.COM 	 */
6659517SBill.Taylor@Sun.COM 	kmutex_t		hs_info_lock;
6669517SBill.Taylor@Sun.COM 
6679517SBill.Taylor@Sun.COM 	/*
6689517SBill.Taylor@Sun.COM 	 * Used for Hermon FW flash burning.  They are used exclusively
6699517SBill.Taylor@Sun.COM 	 * within the ioctl calls for use when accessing the hermon
6709517SBill.Taylor@Sun.COM 	 * flash device.
6719517SBill.Taylor@Sun.COM 	 */
6729517SBill.Taylor@Sun.COM 	kmutex_t		hs_fw_flashlock;
6739517SBill.Taylor@Sun.COM 	int			hs_fw_flashstarted;
6749517SBill.Taylor@Sun.COM 	dev_t			hs_fw_flashdev;
6759517SBill.Taylor@Sun.COM 	uint32_t		hs_fw_log_sector_sz;
6769517SBill.Taylor@Sun.COM 	uint32_t		hs_fw_device_sz;
6779517SBill.Taylor@Sun.COM 	uint32_t		hs_fw_flashbank;
6789517SBill.Taylor@Sun.COM 	uint32_t		*hs_fw_sector;
6799517SBill.Taylor@Sun.COM 	uint32_t		hs_fw_gpio[4];
6809517SBill.Taylor@Sun.COM 	int			hs_fw_cmdset;
6819517SBill.Taylor@Sun.COM 
6829517SBill.Taylor@Sun.COM 	/*
6839517SBill.Taylor@Sun.COM 	 * Used for Hermon FM. They are basically used to manage
6849517SBill.Taylor@Sun.COM 	 * the toggle switch to enable/disable Hermon FM.
6859517SBill.Taylor@Sun.COM 	 * Please see the comment in hermon_fm.c.
6869517SBill.Taylor@Sun.COM 	 */
6879517SBill.Taylor@Sun.COM 	int			hs_fm_capabilities; /* FM capabilities */
6889517SBill.Taylor@Sun.COM 	int			hs_fm_disable;	/* Hermon FM disable flag */
6899517SBill.Taylor@Sun.COM 	int			hs_fm_state;	/* Hermon FM state */
6909517SBill.Taylor@Sun.COM 	boolean_t		hs_fm_async_fatal; /* async internal error */
6919517SBill.Taylor@Sun.COM 	uint32_t		hs_fm_async_errcnt; /* async error count */
6929517SBill.Taylor@Sun.COM 	boolean_t		hs_fm_poll_suspend; /* poll thread suspend */
6939517SBill.Taylor@Sun.COM 	kmutex_t		hs_fm_lock;	/* mutex for state */
6949517SBill.Taylor@Sun.COM 	hermon_hca_fm_t		*hs_fm_hca_fm;	/* HCA FM pointer */
6959517SBill.Taylor@Sun.COM 	ddi_acc_handle_t	hs_fm_cmdhdl;	/* fm-protected CMD hdl */
6969517SBill.Taylor@Sun.COM 	ddi_acc_handle_t	hs_fm_uarhdl;	/* fm-protected UAR hdl */
6979517SBill.Taylor@Sun.COM 	ddi_device_acc_attr_t	hs_fm_accattr;	/* fm-protected acc attr */
6989517SBill.Taylor@Sun.COM 	ddi_periodic_t		hs_fm_poll_thread; /* fma poll thread */
69910125SEiji.Ota@Sun.COM 	int32_t			hs_fm_degraded_reason;	/* degradation cause */
7009517SBill.Taylor@Sun.COM #ifdef FMA_TEST
7019517SBill.Taylor@Sun.COM 	mod_hash_t		*hs_fm_test_hash; /* testset */
7029517SBill.Taylor@Sun.COM 	mod_hash_t		*hs_fm_id_hash;	/* testid */
7039517SBill.Taylor@Sun.COM #endif
704*12965SWilliam.Taylor@Oracle.COM 	/* FCoIB data */
705*12965SWilliam.Taylor@Oracle.COM 	hermon_fcoib_t		hs_fcoib;
706*12965SWilliam.Taylor@Oracle.COM 	boolean_t		hs_fcoib_may_be_running; /* cq_poll test */
707*12965SWilliam.Taylor@Oracle.COM 
7089517SBill.Taylor@Sun.COM 	/*
7099517SBill.Taylor@Sun.COM 	 * Hermon fastreboot support. To sw-reset Hermon HCA, the driver
7109517SBill.Taylor@Sun.COM 	 * needs to save/restore MSI-X tables and PBA. Those members are
7119517SBill.Taylor@Sun.COM 	 * used for the purpose.
7129517SBill.Taylor@Sun.COM 	 */
7139517SBill.Taylor@Sun.COM 	/* Access handle for PCI config space */
7149517SBill.Taylor@Sun.COM 	ddi_acc_handle_t	hs_reg_pcihdl;		/* PCI cfg handle */
7159517SBill.Taylor@Sun.COM 	ddi_acc_handle_t	hs_fm_pcihdl;		/* 	fm handle */
7169517SBill.Taylor@Sun.COM 	ushort_t		hs_caps_ptr;		/* MSI-X caps */
7179517SBill.Taylor@Sun.COM 	ushort_t		hs_msix_ctrl;		/* MSI-X ctrl */
7189517SBill.Taylor@Sun.COM 
7199517SBill.Taylor@Sun.COM 	/* members to handle MSI-X tables */
7209517SBill.Taylor@Sun.COM 	ddi_acc_handle_t	hs_reg_msix_tblhdl;	/* MSI-X table handle */
7219517SBill.Taylor@Sun.COM 	ddi_acc_handle_t	hs_fm_msix_tblhdl;	/* 	fm handle */
7229517SBill.Taylor@Sun.COM 	char 			*hs_msix_tbl_addr;	/* MSI-X table addr */
7239517SBill.Taylor@Sun.COM 	char 			*hs_msix_tbl_entries;	/* MSI-X table entry */
7249517SBill.Taylor@Sun.COM 	size_t			hs_msix_tbl_size;	/* MSI-X table size */
7259517SBill.Taylor@Sun.COM 	uint32_t		hs_msix_tbl_offset;	/* MSI-X table offset */
7269517SBill.Taylor@Sun.COM 	uint32_t		hs_msix_tbl_rnumber;	/* MSI-X table reg# */
7279517SBill.Taylor@Sun.COM 
7289517SBill.Taylor@Sun.COM 	/* members to handle MSI-X PBA */
7299517SBill.Taylor@Sun.COM 	ddi_acc_handle_t	hs_reg_msix_pbahdl;	/* MSI-X PBA handle */
7309517SBill.Taylor@Sun.COM 	ddi_acc_handle_t	hs_fm_msix_pbahdl;	/* 	fm handle */
7319517SBill.Taylor@Sun.COM 	char 			*hs_msix_pba_addr;	/* MSI-X PBA addr */
7329517SBill.Taylor@Sun.COM 	char 			*hs_msix_pba_entries;	/* MSI-X PBA entry */
7339517SBill.Taylor@Sun.COM 	size_t			hs_msix_pba_size;	/* MSI-X PBA size */
7349517SBill.Taylor@Sun.COM 	uint32_t		hs_msix_pba_offset;	/* MSI-X PBA offset */
7359517SBill.Taylor@Sun.COM 	uint32_t		hs_msix_pba_rnumber;	/* MSI-X PBA reg# */
7369517SBill.Taylor@Sun.COM 
7379517SBill.Taylor@Sun.COM 	boolean_t		hs_quiescing;		/* in fastreboot */
7389517SBill.Taylor@Sun.COM };
7399517SBill.Taylor@Sun.COM _NOTE(MUTEX_PROTECTS_DATA(hermon_state_s::hs_fw_flashlock,
7409517SBill.Taylor@Sun.COM     hermon_state_s::hs_fw_flashstarted
7419517SBill.Taylor@Sun.COM     hermon_state_s::hs_fw_flashdev
7429517SBill.Taylor@Sun.COM     hermon_state_s::hs_fw_log_sector_sz
7439517SBill.Taylor@Sun.COM     hermon_state_s::hs_fw_device_sz))
7449517SBill.Taylor@Sun.COM _NOTE(MUTEX_PROTECTS_DATA(hermon_state_s::hs_spec_qplock,
7459517SBill.Taylor@Sun.COM     hermon_state_s::hs_spec_qpflags
7469517SBill.Taylor@Sun.COM     hermon_state_s::hs_spec_qp0
7479517SBill.Taylor@Sun.COM     hermon_state_s::hs_spec_qp1))
7489517SBill.Taylor@Sun.COM _NOTE(MUTEX_PROTECTS_DATA(hermon_state_s::hs_mcglock,
7499517SBill.Taylor@Sun.COM     hermon_state_s::hs_mcghdl
7509517SBill.Taylor@Sun.COM     hermon_state_s::hs_mcgtmp))
7519517SBill.Taylor@Sun.COM _NOTE(DATA_READABLE_WITHOUT_LOCK(hermon_state_s::hs_in_evcallb
7529517SBill.Taylor@Sun.COM     hermon_state_s::hs_fw_log_sector_sz
7539517SBill.Taylor@Sun.COM     hermon_state_s::hs_fw_device_sz
7549517SBill.Taylor@Sun.COM     hermon_state_s::hs_spec_qpflags
7559517SBill.Taylor@Sun.COM     hermon_state_s::hs_spec_qp0
7569517SBill.Taylor@Sun.COM     hermon_state_s::hs_spec_qp1))
7579517SBill.Taylor@Sun.COM _NOTE(MUTEX_PROTECTS_DATA(hermon_state_s::hs_qpn_avl_lock,
7589517SBill.Taylor@Sun.COM     hermon_state_s::hs_qpn_avl))
7599517SBill.Taylor@Sun.COM _NOTE(SCHEME_PROTECTS_DATA("safe sharing",
7609517SBill.Taylor@Sun.COM     hermon_state_s::hs_fm_async_fatal
7619517SBill.Taylor@Sun.COM     hermon_state_s::hs_fw_sector))
7629517SBill.Taylor@Sun.COM 
7639517SBill.Taylor@Sun.COM /*
7649517SBill.Taylor@Sun.COM  * HERMON_IN_FASTREBOOT() shows if Hermon driver is at fastreboot.
7659517SBill.Taylor@Sun.COM  * This macro should be used to check if the mutex lock can be used
7669517SBill.Taylor@Sun.COM  * since the lock cannot be used if the driver is in the quiesce mode.
7679517SBill.Taylor@Sun.COM  */
7689517SBill.Taylor@Sun.COM #define	HERMON_IN_FASTREBOOT(state)	(state->hs_quiescing == B_TRUE)
7699517SBill.Taylor@Sun.COM 
7709517SBill.Taylor@Sun.COM /*
7719517SBill.Taylor@Sun.COM  * Bit positions in the "hs_spec_qpflags" field above.  The flags are (from
7729517SBill.Taylor@Sun.COM  * least significant to most): (QP0,Port1), (QP0,Port2), (QP1,Port1), and
7739517SBill.Taylor@Sun.COM  * (QP1,Port2).  The masks are there to help with some specific allocation
7749517SBill.Taylor@Sun.COM  * and freeing operations
7759517SBill.Taylor@Sun.COM  */
7769517SBill.Taylor@Sun.COM #define	HERMON_SPECIAL_QP0_RSRC		0
7779517SBill.Taylor@Sun.COM #define	HERMON_SPECIAL_QP0_RSRC_MASK	0x3
7789517SBill.Taylor@Sun.COM #define	HERMON_SPECIAL_QP1_RSRC		2
7799517SBill.Taylor@Sun.COM #define	HERMON_SPECIAL_QP1_RSRC_MASK	0xC
7809517SBill.Taylor@Sun.COM 
7819517SBill.Taylor@Sun.COM 
7829517SBill.Taylor@Sun.COM /*
7839517SBill.Taylor@Sun.COM  * These flags specifies additional behaviors on database access.
7849517SBill.Taylor@Sun.COM  * HERMON_UMAP_DB_REMOVE, for example, specifies that (if found) the database
7859517SBill.Taylor@Sun.COM  * entry should be removed from the database.  HERMON_UMAP_DB_IGNORE_INSTANCE
7869517SBill.Taylor@Sun.COM  * specifies that a particular database query should ignore value in the
7879517SBill.Taylor@Sun.COM  * "tdb_instance" field as a criterion for the search.
7889517SBill.Taylor@Sun.COM  */
7899517SBill.Taylor@Sun.COM #define	HERMON_UMAP_DB_REMOVE		(1 << 0)
7909517SBill.Taylor@Sun.COM #define	HERMON_UMAP_DB_IGNORE_INSTANCE	(1 << 1)
7919517SBill.Taylor@Sun.COM 
7929517SBill.Taylor@Sun.COM /*
7939517SBill.Taylor@Sun.COM  * The hermon_umap_db_t structure contains what is referred to throughout the
7949517SBill.Taylor@Sun.COM  * driver code as the "userland resources database".  This structure contains
7959517SBill.Taylor@Sun.COM  * all the necessary information to track resources that have been prepared
7969517SBill.Taylor@Sun.COM  * for direct-from-userland access.  There is an AVL tree ("hdl_umapdb_avl")
7979517SBill.Taylor@Sun.COM  * which consists of the "hermon_umap_db_entry_t" (below) and a lock to ensure
7989517SBill.Taylor@Sun.COM  * atomic access when adding or removing entries from the database.
7999517SBill.Taylor@Sun.COM  */
8009517SBill.Taylor@Sun.COM typedef struct hermon_umap_db_s {
8019517SBill.Taylor@Sun.COM 	kmutex_t		hdl_umapdb_lock;
8029517SBill.Taylor@Sun.COM 	avl_tree_t		hdl_umapdb_avl;
8039517SBill.Taylor@Sun.COM } hermon_umap_db_t;
8049517SBill.Taylor@Sun.COM 
8059517SBill.Taylor@Sun.COM /*
8069517SBill.Taylor@Sun.COM  * The hermon_umap_db_priv_t structure currently contains information necessary
8079517SBill.Taylor@Sun.COM  * to provide the "on close" callback to the firmware flash interfaces.  It
8089517SBill.Taylor@Sun.COM  * is intended that this structure could be extended to enable other "on
8099517SBill.Taylor@Sun.COM  * close" callbacks as well.
8109517SBill.Taylor@Sun.COM  */
8119517SBill.Taylor@Sun.COM typedef struct hermon_umap_db_priv_s {
8129517SBill.Taylor@Sun.COM 	int		(*hdp_cb)(void *);
8139517SBill.Taylor@Sun.COM 	void		*hdp_arg;
8149517SBill.Taylor@Sun.COM } hermon_umap_db_priv_t;
8159517SBill.Taylor@Sun.COM 
8169517SBill.Taylor@Sun.COM /*
8179517SBill.Taylor@Sun.COM  * The hermon_umap_db_common_t structure contains fields which are common
8189517SBill.Taylor@Sun.COM  * between the database entries ("hermon_umap_db_entry_t") and the structure
8199517SBill.Taylor@Sun.COM  * used to contain the search criteria ("hermon_umap_db_query_t").  This
8209517SBill.Taylor@Sun.COM  * structure contains a key, a resource type (described above), an instance
8219517SBill.Taylor@Sun.COM  * (corresponding to the driver instance which inserted the database entry),
8229517SBill.Taylor@Sun.COM  * and a "value" field.  Typically, "hdb_value" is a pointer to a Hermon
8239517SBill.Taylor@Sun.COM  * resource object.  Although for memory regions, the value field corresponds
8249517SBill.Taylor@Sun.COM  * to the ddi_umem_cookie_t for the pinned userland memory.
8259517SBill.Taylor@Sun.COM  * The structure also includes a placeholder for private data ("hdb_priv").
8269517SBill.Taylor@Sun.COM  * Currently this data is being used for holding "on close" callback
8279517SBill.Taylor@Sun.COM  * information to allow certain kinds of cleanup even if a userland process
8289517SBill.Taylor@Sun.COM  * prematurely exits.
8299517SBill.Taylor@Sun.COM  */
8309517SBill.Taylor@Sun.COM typedef struct hermon_umap_db_common_s {
8319517SBill.Taylor@Sun.COM 	uint64_t		hdb_key;
8329517SBill.Taylor@Sun.COM 	uint64_t		hdb_value;
8339517SBill.Taylor@Sun.COM 	uint_t			hdb_type;
8349517SBill.Taylor@Sun.COM 	uint_t			hdb_instance;
8359517SBill.Taylor@Sun.COM 	void			*hdb_priv;
8369517SBill.Taylor@Sun.COM } hermon_umap_db_common_t;
8379517SBill.Taylor@Sun.COM 
8389517SBill.Taylor@Sun.COM /*
8399517SBill.Taylor@Sun.COM  * The hermon_umap_db_entry_t structure is the entry in "userland resources
8409517SBill.Taylor@Sun.COM  * database".  As required by the AVL framework, each entry contains an
8419517SBill.Taylor@Sun.COM  * "avl_node_t".  Then, as required to implement the database, each entry
8429517SBill.Taylor@Sun.COM  * contains a "hermon_umap_db_common_t" structure used to contain all of the
8439517SBill.Taylor@Sun.COM  * relevant entries.
8449517SBill.Taylor@Sun.COM  */
8459517SBill.Taylor@Sun.COM typedef struct hermon_umap_db_entry_s {
8469517SBill.Taylor@Sun.COM 	avl_node_t		hdbe_avlnode;
8479517SBill.Taylor@Sun.COM 	hermon_umap_db_common_t	hdbe_common;
8489517SBill.Taylor@Sun.COM } hermon_umap_db_entry_t;
8499517SBill.Taylor@Sun.COM 
8509517SBill.Taylor@Sun.COM /*
8519517SBill.Taylor@Sun.COM  * The hermon_umap_db_query_t structure is used in queries to the "userland
8529517SBill.Taylor@Sun.COM  * resources database".  In addition to the "hermon_umap_db_common_t" structure
8539517SBill.Taylor@Sun.COM  * used to contain the various search criteria, this structure also contains
8549517SBill.Taylor@Sun.COM  * a flags field "hqdb_flags" which can be used to specify additional behaviors
8559517SBill.Taylor@Sun.COM  * (as described above).  Specifically, the flags field can be used to specify
8569517SBill.Taylor@Sun.COM  * that an entry should be removed from the database, if found, and to
8579517SBill.Taylor@Sun.COM  * specify whether the database lookup should consider "tdb_instance" in the
8589517SBill.Taylor@Sun.COM  * search.
8599517SBill.Taylor@Sun.COM  */
8609517SBill.Taylor@Sun.COM typedef struct hermon_umap_db_query_s {
8619517SBill.Taylor@Sun.COM 	uint_t			hqdb_flags;
8629517SBill.Taylor@Sun.COM 	hermon_umap_db_common_t	hqdb_common;
8639517SBill.Taylor@Sun.COM } hermon_umap_db_query_t;
8649517SBill.Taylor@Sun.COM _NOTE(MUTEX_PROTECTS_DATA(hermon_umap_db_s::hdl_umapdb_lock,
8659517SBill.Taylor@Sun.COM     hermon_umap_db_entry_s::hdbe_avlnode
8669517SBill.Taylor@Sun.COM     hermon_umap_db_entry_s::hdbe_common.hdb_key
8679517SBill.Taylor@Sun.COM     hermon_umap_db_entry_s::hdbe_common.hdb_value
8689517SBill.Taylor@Sun.COM     hermon_umap_db_entry_s::hdbe_common.hdb_type
8699517SBill.Taylor@Sun.COM     hermon_umap_db_entry_s::hdbe_common.hdb_instance))
8709517SBill.Taylor@Sun.COM 
8719517SBill.Taylor@Sun.COM /*
8729517SBill.Taylor@Sun.COM  * The hermon_devmap_track_t structure contains all the necessary information
8739517SBill.Taylor@Sun.COM  * to track resources that have been mapped through devmap.  There is a
8749517SBill.Taylor@Sun.COM  * back-pointer to the Hermon softstate, the logical offset corresponding with
8759517SBill.Taylor@Sun.COM  * the mapped resource, the size of the mapped resource (zero indicates an
8769517SBill.Taylor@Sun.COM  * "invalid mapping"), and a reference count and lock used to determine when
8779517SBill.Taylor@Sun.COM  * to free the structure (specifically, this is necessary to handle partial
8789517SBill.Taylor@Sun.COM  * unmappings).
8799517SBill.Taylor@Sun.COM  */
8809517SBill.Taylor@Sun.COM typedef struct hermon_devmap_track_s {
8819517SBill.Taylor@Sun.COM 	hermon_state_t	*hdt_state;
8829517SBill.Taylor@Sun.COM 	uint64_t	hdt_offset;
8839517SBill.Taylor@Sun.COM 	uint_t		hdt_size;
8849517SBill.Taylor@Sun.COM 	int		hdt_refcnt;
8859517SBill.Taylor@Sun.COM 	kmutex_t	hdt_lock;
8869517SBill.Taylor@Sun.COM } hermon_devmap_track_t;
8879517SBill.Taylor@Sun.COM 
8889517SBill.Taylor@Sun.COM #define	HERMON_ICM_SPLIT	64
8899517SBill.Taylor@Sun.COM #define	HERMON_ICM_SPAN		4096
8909517SBill.Taylor@Sun.COM 
891*12965SWilliam.Taylor@Oracle.COM #define	hermon_bitmap(bitmap, dma_info, icm_table, split_index, num_to_hdl) \
8929517SBill.Taylor@Sun.COM 	bitmap = (icm_table)->icm_bitmap[split_index];		\
8939517SBill.Taylor@Sun.COM 	if (bitmap == NULL) {					\
8949517SBill.Taylor@Sun.COM 		_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*(icm_table))) \
8959517SBill.Taylor@Sun.COM 		int num_spans = (icm_table)->num_spans;		\
8969517SBill.Taylor@Sun.COM 		bitmap =					\
8979517SBill.Taylor@Sun.COM 		(icm_table)->icm_bitmap[split_index] =		\
8989517SBill.Taylor@Sun.COM 		    kmem_zalloc((num_spans + 7) / 8, KM_SLEEP);	\
8999517SBill.Taylor@Sun.COM 		ASSERT((icm_table)->icm_dma[split_index] == NULL); \
9009517SBill.Taylor@Sun.COM 		(icm_table)->icm_dma[split_index] =		\
9019517SBill.Taylor@Sun.COM 		    kmem_zalloc(num_spans * sizeof (hermon_dma_info_t), \
9029517SBill.Taylor@Sun.COM 		    KM_SLEEP);					\
903*12965SWilliam.Taylor@Oracle.COM 		if (num_to_hdl) {				\
904*12965SWilliam.Taylor@Oracle.COM 			ASSERT((icm_table)->num_to_hdl[split_index] == NULL); \
905*12965SWilliam.Taylor@Oracle.COM 			(icm_table)->num_to_hdl[split_index] =	\
906*12965SWilliam.Taylor@Oracle.COM 			    kmem_zalloc(num_spans *		\
907*12965SWilliam.Taylor@Oracle.COM 			    sizeof (void **), KM_SLEEP);	\
908*12965SWilliam.Taylor@Oracle.COM 		}						\
9099517SBill.Taylor@Sun.COM 	}							\
9109517SBill.Taylor@Sun.COM 	dma_info = (icm_table)->icm_dma[split_index]
9119517SBill.Taylor@Sun.COM 
9129517SBill.Taylor@Sun.COM /*
9139517SBill.Taylor@Sun.COM  * The hermon_icm_table_t encodes data pertaining to a given ICM table, and
9149517SBill.Taylor@Sun.COM  * holds an array of hermon_dma_info_t's related to its backing memory. Each
9159517SBill.Taylor@Sun.COM  * ICM table is sized during initialization, but real memory is allocated
9169517SBill.Taylor@Sun.COM  * and mapped into and out of ICM in the device throughout the life of the
9179517SBill.Taylor@Sun.COM  * instance. We use a bitmap to determine whether or not a given ICM object
9189517SBill.Taylor@Sun.COM  * has memory backing it or not, and an array of hermon_dma_info_t's to house
9199517SBill.Taylor@Sun.COM  * the actual allocations. Memory is allocated in chunks of span_size, stored
9209517SBill.Taylor@Sun.COM  * in the icm_dma array, and can later be looked up by using the bitmap index.
9219517SBill.Taylor@Sun.COM  * The total number of ICM spans is equal to table_size / span_size. We also
9229517SBill.Taylor@Sun.COM  * keep track of the ICM characteristics, such as ICM object size and the
9239517SBill.Taylor@Sun.COM  * number of entries in the ICM area.
9249517SBill.Taylor@Sun.COM  */
9259517SBill.Taylor@Sun.COM struct hermon_icm_table_s {
9269517SBill.Taylor@Sun.COM 	kmutex_t		icm_table_lock;
9279517SBill.Taylor@Sun.COM 	kcondvar_t		icm_table_cv;
9289517SBill.Taylor@Sun.COM 	uint8_t			icm_busy;
9299517SBill.Taylor@Sun.COM 	hermon_rsrc_type_t	icm_type;
9309517SBill.Taylor@Sun.COM 	uint64_t		icm_baseaddr;
9319517SBill.Taylor@Sun.COM 	uint64_t		table_size;
9329517SBill.Taylor@Sun.COM 	uint64_t		num_entries;	/* maximum #entries */
9339517SBill.Taylor@Sun.COM 	uint32_t		object_size;
9349517SBill.Taylor@Sun.COM 	uint32_t		span;		/* #rsrc's per span */
9359517SBill.Taylor@Sun.COM 	uint32_t		num_spans;	/* #dmainfos in icm_dma */
9369517SBill.Taylor@Sun.COM 	uint32_t		split_shift;
9379517SBill.Taylor@Sun.COM 	uint32_t		span_mask;
9389517SBill.Taylor@Sun.COM 	uint32_t		span_shift;
9399517SBill.Taylor@Sun.COM 	uint32_t		rsrc_mask;
9409517SBill.Taylor@Sun.COM 	uint16_t		log_num_entries;
9419517SBill.Taylor@Sun.COM 	uint16_t		log_object_size;
942*12965SWilliam.Taylor@Oracle.COM 	/* three arrays of pointers, each pointer points to arrays */
9439517SBill.Taylor@Sun.COM 	uint8_t			*icm_bitmap[HERMON_ICM_SPLIT];
9449517SBill.Taylor@Sun.COM 	hermon_dma_info_t	*icm_dma[HERMON_ICM_SPLIT];
945*12965SWilliam.Taylor@Oracle.COM 	void			***num_to_hdl[HERMON_ICM_SPLIT]; /* qp/cq/srq */
9469517SBill.Taylor@Sun.COM };
9479517SBill.Taylor@Sun.COM /*
9489517SBill.Taylor@Sun.COM  * Split the rsrc index into three pieces:
9499517SBill.Taylor@Sun.COM  *
9509517SBill.Taylor@Sun.COM  *      index1 - icm_bitmap[HERMON_ICM_SPLIT], icm_dma[HERMON_ICM_SPLIT]
9519517SBill.Taylor@Sun.COM  *      index2 - bitmap[], dma[]
9529517SBill.Taylor@Sun.COM  *      offset - rsrc within the icm mapping
9539517SBill.Taylor@Sun.COM  */
9549517SBill.Taylor@Sun.COM #define	hermon_index(index1, index2, rindx, table, offset)		\
9559517SBill.Taylor@Sun.COM 	index1 = (rindx) >> table->split_shift;				\
9569517SBill.Taylor@Sun.COM 	index2 = ((rindx) & table->span_mask) >> table->span_shift;	\
9579517SBill.Taylor@Sun.COM 	offset = (rindx) & table->rsrc_mask
9589517SBill.Taylor@Sun.COM 
9599517SBill.Taylor@Sun.COM /* Defined in hermon.c */
9609517SBill.Taylor@Sun.COM int hermon_dma_alloc(hermon_state_t *state, hermon_dma_info_t *dma_info,
9619517SBill.Taylor@Sun.COM     uint16_t opcode);
9629517SBill.Taylor@Sun.COM void hermon_dma_attr_init(hermon_state_t *state, ddi_dma_attr_t *dma_attr);
9639517SBill.Taylor@Sun.COM void hermon_dma_free(hermon_dma_info_t *info);
9649517SBill.Taylor@Sun.COM int hermon_icm_alloc(hermon_state_t *state, hermon_rsrc_type_t type,
9659517SBill.Taylor@Sun.COM     uint32_t icm_index1, uint32_t icm_index2);
9669517SBill.Taylor@Sun.COM void hermon_icm_free(hermon_state_t *state, hermon_rsrc_type_t type,
9679517SBill.Taylor@Sun.COM     uint32_t icm_index1, uint32_t icm_index2);
968*12965SWilliam.Taylor@Oracle.COM void *hermon_icm_num_to_hdl(hermon_state_t *state, hermon_rsrc_type_t type,
969*12965SWilliam.Taylor@Oracle.COM     uint32_t idx);
970*12965SWilliam.Taylor@Oracle.COM void hermon_icm_set_num_to_hdl(hermon_state_t *state, hermon_rsrc_type_t type,
971*12965SWilliam.Taylor@Oracle.COM     uint32_t idx, void *hdl);
97212688SWilliam.Taylor@Oracle.COM int hermon_device_mode(hermon_state_t *state);
9739517SBill.Taylor@Sun.COM 
9749517SBill.Taylor@Sun.COM /* Defined in hermon_umap.c */
9759517SBill.Taylor@Sun.COM int hermon_devmap(dev_t dev, devmap_cookie_t dhp, offset_t off, size_t len,
9769517SBill.Taylor@Sun.COM     size_t *maplen, uint_t model);
9779517SBill.Taylor@Sun.COM ibt_status_t hermon_umap_ci_data_in(hermon_state_t *state,
9789517SBill.Taylor@Sun.COM     ibt_ci_data_flags_t flags, ibt_object_type_t object, void *hdl,
9799517SBill.Taylor@Sun.COM     void *data_p, size_t data_sz);
9809517SBill.Taylor@Sun.COM ibt_status_t hermon_umap_ci_data_out(hermon_state_t *state,
9819517SBill.Taylor@Sun.COM     ibt_ci_data_flags_t flags, ibt_object_type_t object, void *hdl,
9829517SBill.Taylor@Sun.COM     void *data_p, size_t data_sz);
9839517SBill.Taylor@Sun.COM void hermon_umap_db_init(void);
9849517SBill.Taylor@Sun.COM void hermon_umap_db_fini(void);
9859517SBill.Taylor@Sun.COM hermon_umap_db_entry_t *hermon_umap_db_alloc(uint_t instance, uint64_t key,
9869517SBill.Taylor@Sun.COM     uint_t type, uint64_t value);
9879517SBill.Taylor@Sun.COM void hermon_umap_db_free(hermon_umap_db_entry_t *umapdb);
9889517SBill.Taylor@Sun.COM void hermon_umap_db_add(hermon_umap_db_entry_t *umapdb);
9899517SBill.Taylor@Sun.COM void hermon_umap_db_add_nolock(hermon_umap_db_entry_t *umapdb);
9909517SBill.Taylor@Sun.COM int hermon_umap_db_find(uint_t instance, uint64_t key, uint_t type,
9919517SBill.Taylor@Sun.COM     uint64_t *value, uint_t flags, hermon_umap_db_entry_t **umapdb);
9929517SBill.Taylor@Sun.COM int hermon_umap_db_find_nolock(uint_t instance, uint64_t key, uint_t type,
9939517SBill.Taylor@Sun.COM     uint64_t *value, uint_t flags, hermon_umap_db_entry_t **umapdb);
9949517SBill.Taylor@Sun.COM void hermon_umap_umemlock_cb(ddi_umem_cookie_t *umem_cookie);
9959517SBill.Taylor@Sun.COM int hermon_umap_db_set_onclose_cb(dev_t dev, uint64_t flag,
9969517SBill.Taylor@Sun.COM     int (*callback)(void *), void *arg);
9979517SBill.Taylor@Sun.COM int hermon_umap_db_clear_onclose_cb(dev_t dev, uint64_t flag);
9989517SBill.Taylor@Sun.COM int hermon_umap_db_handle_onclose_cb(hermon_umap_db_priv_t *priv);
9999517SBill.Taylor@Sun.COM int hermon_rsrc_hw_entries_init(hermon_state_t *state,
10009517SBill.Taylor@Sun.COM     hermon_rsrc_hw_entry_info_t *info);
10019517SBill.Taylor@Sun.COM void hermon_rsrc_hw_entries_fini(hermon_state_t *state,
10029517SBill.Taylor@Sun.COM     hermon_rsrc_hw_entry_info_t *info);
10039517SBill.Taylor@Sun.COM 
10049517SBill.Taylor@Sun.COM #ifdef __cplusplus
10059517SBill.Taylor@Sun.COM }
10069517SBill.Taylor@Sun.COM #endif
10079517SBill.Taylor@Sun.COM 
10089517SBill.Taylor@Sun.COM #endif	/* _SYS_IB_ADAPTERS_HERMON_H */
1009