4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #ifndef _SYS_IB_ADAPTERS_TAVOR_H
28 #define _SYS_IB_ADAPTERS_TAVOR_H
33 * Contains the #defines and typedefs necessary for the Tavor softstate
34 * structure and for proper attach() and detach() processing. Also
35 * includes all the other Tavor header files (and so is the only header
36 * file that is directly included by the Tavor source files).
37 * Additionally, this file contains some defines and macros used by
38 * Tavor TNF tracing mechanism.
39 * Lastly, this file includes everything necessary for implementing the
40 * devmap interface and for maintaining the "mapped resource database".
43 #include <sys/types.h>
46 #include <sys/sunddi.h>
47 #include <sys/tnf_probe.h>
48 #include <sys/taskq.h>
50 #include <sys/ib/ibtl/ibci.h>
51 #include <sys/ib/adapters/mlnx_umap.h>
54 * First include all the Tavor typedefs, then include all the other Tavor
55 * specific headers (many of which depend on the typedefs having already
58 #include <sys/ib/adapters/tavor/tavor_typedef.h>
60 #include <sys/ib/adapters/tavor/tavor_agents.h>
61 #include <sys/ib/adapters/tavor/tavor_cfg.h>
62 #include <sys/ib/adapters/tavor/tavor_cmd.h>
63 #include <sys/ib/adapters/tavor/tavor_cq.h>
64 #include <sys/ib/adapters/tavor/tavor_event.h>
65 #include <sys/ib/adapters/tavor/tavor_hw.h>
66 #include <sys/ib/adapters/tavor/tavor_ioctl.h>
67 #include <sys/ib/adapters/tavor/tavor_misc.h>
68 #include <sys/ib/adapters/tavor/tavor_mr.h>
69 #include <sys/ib/adapters/tavor/tavor_qp.h>
70 #include <sys/ib/adapters/tavor/tavor_srq.h>
71 #include <sys/ib/adapters/tavor/tavor_rsrc.h>
72 #include <sys/ib/adapters/tavor/tavor_wr.h>
78 #define TAVOR_VPD_HDR_DWSIZE 0x10 /* 16 Dwords */
79 #define TAVOR_VPD_HDR_BSIZE 0x40 /* 64 Bytes */
82 * Number of initial states to setup. Used in call to ddi_soft_state_init()
84 #define TAVOR_INITIAL_STATES 3
87 * Macro and defines used to calculate device instance number from minor
88 * number (and vice versa).
90 #define TAVOR_MINORNUM_SHIFT 3
91 #define TAVOR_DEV_INSTANCE(dev) (getminor((dev)) & \
92 ((1 << TAVOR_MINORNUM_SHIFT) - 1))
95 * Locations for the various Tavor hardware PCI BARs (CMD, UAR, DDR)
97 #define TAVOR_CMD_BAR 1
98 #define TAVOR_UAR_BAR 2
99 #define TAVOR_DDR_BAR 3
102 * Some defines for the software reset. These define the value that should
103 * be written to begin the reset (TAVOR_SW_RESET_START), the delay before
104 * beginning to poll for completion (TAVOR_SW_RESET_DELAY), the in-between
105 * polling delay (TAVOR_SW_RESET_POLL_DELAY), and the value that indicates
106 * that the reset has not completed (TAVOR_SW_RESET_NOTDONE).
108 #define TAVOR_SW_RESET_START 0x00000001
109 #define TAVOR_SW_RESET_DELAY 100000 /* 100 ms */
110 #define TAVOR_SW_RESET_POLL_DELAY 100 /* 100 us */
111 #define TAVOR_SW_RESET_NOTDONE 0xFFFFFFFF
114 * These defines are used in the Tavor software reset operation. They define
115 * the total number PCI registers to read/restore during the reset. And they
116 * also specify two config registers which should not be read or restored.
118 #define TAVOR_SW_RESET_NUMREGS 0x40
119 #define TAVOR_SW_RESET_REG22_RSVD 0x16
120 #define TAVOR_SW_RESET_REG23_RSVD 0x17
123 * Macro used to output Tavor warning messages. Note: Tavor warning messages
124 * are only generated when an unexpected condition has been detected. This
125 * can be the result of a software bug or some other problem, but it is more
126 * often an indication that the Tavor firmware (and/or hardware) has done
127 * something unexpected. This warning message means that the driver state
128 * in unpredictable and that shutdown/restart is suggested.
130 #define TAVOR_WARNING(state, string) \
131 cmn_err(CE_WARN, "tavor%d: "string, (state)->ts_instance)
134 * Macro used to set attach failure messages. Also, the attach message buf
137 #define TAVOR_ATTACH_MSGSIZE 80
138 #define TAVOR_ATTACH_MSG(attach_buf, attach_msg) \
139 (void) snprintf((attach_buf), TAVOR_ATTACH_MSGSIZE, (attach_msg));
140 #define TAVOR_ATTACH_MSG_INIT(attach_buf) \
141 (attach_buf)[0] = '\0';
144 * Macros used for controlling whether or not event callbacks will be forwarded
145 * to the IBTF. This is necessary because there are certain race conditions
146 * that can occur (e.g. calling IBTF with an asynch event before the IBTF
147 * registration has successfully completed or handling an event after we've
148 * detached from the IBTF.)
150 * TAVOR_ENABLE_IBTF_CALLB() initializes the "ts_ibtfpriv" field in the Tavor
151 * softstate. When "ts_ibtfpriv" is non-NULL, it is OK to forward asynch
152 * and CQ events to the IBTF.
154 * TAVOR_DO_IBTF_ASYNC_CALLB() and TAVOR_DO_IBTF_CQ_CALLB() both set and clear
155 * the "ts_in_evcallb" flag, as necessary, to indicate that an IBTF
156 * callback is currently in progress. This is necessary so that we can
157 * block on this condition in tavor_detach().
159 * TAVOR_QUIESCE_IBTF_CALLB() is used in tavor_detach() to set the
160 * "ts_ibtfpriv" to NULL (thereby disabling any further IBTF callbacks)
161 * and to poll on the "ts_in_evcallb" flag. When this flag is zero, all
162 * IBTF callbacks have quiesced and it is safe to continue with detach
163 * (i.e. continue detaching from IBTF).
165 #define TAVOR_ENABLE_IBTF_CALLB(state, tmp_ibtfpriv) \
166 (state)->ts_ibtfpriv = (tmp_ibtfpriv);
168 #define TAVOR_DO_IBTF_ASYNC_CALLB(state, type, event) \
169 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS((state)->ts_in_evcallb)) \
170 (state)->ts_in_evcallb = 1; \
171 ibc_async_handler((state)->ts_ibtfpriv, (type), (event)); \
172 (state)->ts_in_evcallb = 0;
174 #define TAVOR_DO_IBTF_CQ_CALLB(state, cq) \
175 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS((state)->ts_in_evcallb)) \
176 (state)->ts_in_evcallb = 1; \
177 ibc_cq_handler((state)->ts_ibtfpriv, (cq)->cq_hdlrarg); \
178 (state)->ts_in_evcallb = 0;
180 #define TAVOR_QUIESCE_IBTF_CALLB(state) \
184 state->ts_ibtfpriv = NULL; \
185 while (((state)->ts_in_evcallb != 0) && \
186 (count++ < TAVOR_QUIESCE_IBTF_CALLB_POLL_MAX)) { \
187 drv_usecwait(TAVOR_QUIESCE_IBTF_CALLB_POLL_DELAY); \
192 * Defines used by the TAVOR_QUIESCE_IBTF_CALLB() macro to determine the
193 * duration and number of times (at maximum) to poll while waiting for IBTF
194 * callbacks to quiesce.
196 #define TAVOR_QUIESCE_IBTF_CALLB_POLL_DELAY 1
197 #define TAVOR_QUIESCE_IBTF_CALLB_POLL_MAX 1000000
200 * Define used to determine the device mode to which Tavor driver has been
201 * attached. TAVOR_IS_MAINTENANCE_MODE() returns true when the device has
202 * come up in the "maintenance mode". In this mode, no InfiniBand interfaces
203 * are enabled, but the device's firmware can be updated/flashed (and
204 * test/debug interfaces should be useable).
205 * TAVOR_IS_HCA_MODE() returns true when the device has come up in the normal
206 * HCA mode. In this mode, all necessary InfiniBand interfaces are enabled
207 * (and, if necessary, Tavor firmware can be updated/flashed).
209 #define TAVOR_IS_MAINTENANCE_MODE(dip) \
210 (((ddi_prop_get_int(DDI_DEV_T_ANY, (dip), DDI_PROP_DONTPASS, \
211 "device-id", -1) == 0x5a45) || \
212 (ddi_prop_get_int(DDI_DEV_T_ANY, (dip), DDI_PROP_DONTPASS, \
213 "device-id", -1) == 0x6279)) && \
214 (ddi_prop_get_int(DDI_DEV_T_ANY, (dip), DDI_PROP_DONTPASS, \
215 "vendor-id", -1) == 0x15b3))
216 #define TAVOR_IS_COMPAT_MODE(dip) \
217 ((ddi_prop_get_int(DDI_DEV_T_ANY, (dip), DDI_PROP_DONTPASS, \
218 "device-id", -1) == 0x6278) && \
219 (ddi_prop_get_int(DDI_DEV_T_ANY, (dip), DDI_PROP_DONTPASS, \
220 "vendor-id", -1) == 0x15b3))
221 #define TAVOR_IS_HCA_MODE(dip) \
222 ((ddi_prop_get_int(DDI_DEV_T_ANY, (dip), DDI_PROP_DONTPASS, \
223 "device-id", -1) == 0x5a44) && \
224 (ddi_prop_get_int(DDI_DEV_T_ANY, (dip), DDI_PROP_DONTPASS, \
225 "vendor-id", -1) == 0x15b3))
227 #define TAVOR_MAINTENANCE_MODE 1
228 #define TAVOR_COMPAT_MODE 2
229 #define TAVOR_HCA_MODE 3
232 * Used to determine if the device is operational, or not in maintenance mode.
233 * This means either the driver has attached successfully against an arbel
234 * device in tavor compatibility mode, or against a tavor device in full HCA
237 #define TAVOR_IS_OPERATIONAL(mode) \
238 (mode == TAVOR_COMPAT_MODE || mode == TAVOR_HCA_MODE)
241 * Used to determine if parent bridge is a PCI bridge; used in software reset
243 #define TAVOR_PARENT_IS_BRIDGE(dip) \
244 ((ddi_prop_get_int(DDI_DEV_T_ANY, (dip), DDI_PROP_DONTPASS, \
245 "device-id", -1) == 0x5a46))
248 * The following define is used (in tavor_umap_db_set_onclose_cb()) to
249 * indicate that a cleanup callback is needed to undo initialization done
250 * by the firmware flash burn code.
252 #define TAVOR_ONCLOSE_FLASH_INPROGRESS (1 << 0)
255 * The following enumerated type and structures are used during driver
256 * initialization. Note: The TAVOR_DRV_CLEANUP_ALL type is used as a marker
257 * for end of the cleanup steps. No cleanup steps should be added after
258 * TAVOR_DRV_CLEANUP_ALL. Any addition steps should be added before it.
261 TAVOR_DRV_CLEANUP_LEVEL0
,
262 TAVOR_DRV_CLEANUP_LEVEL1
,
263 TAVOR_DRV_CLEANUP_LEVEL2
,
264 TAVOR_DRV_CLEANUP_LEVEL3
,
265 TAVOR_DRV_CLEANUP_LEVEL4
,
266 TAVOR_DRV_CLEANUP_LEVEL5
,
267 TAVOR_DRV_CLEANUP_LEVEL6
,
268 TAVOR_DRV_CLEANUP_LEVEL7
,
269 TAVOR_DRV_CLEANUP_LEVEL8
,
270 TAVOR_DRV_CLEANUP_LEVEL9
,
271 TAVOR_DRV_CLEANUP_LEVEL10
,
272 TAVOR_DRV_CLEANUP_LEVEL11
,
273 TAVOR_DRV_CLEANUP_LEVEL12
,
274 TAVOR_DRV_CLEANUP_LEVEL13
,
275 TAVOR_DRV_CLEANUP_LEVEL14
,
276 /* No more driver cleanup steps below this point! */
277 TAVOR_DRV_CLEANUP_ALL
278 } tavor_drv_cleanup_level_t
;
281 * tavor_mem_alloc_hdl_t structure store DMA handles for the new
282 * ibc_alloc_io_mem calls
284 typedef struct tavor_mem_alloc_hdl_s
{
285 ddi_dma_handle_t tavor_dma_hdl
;
286 ddi_acc_handle_t tavor_acc_hdl
;
287 } *tavor_mem_alloc_hdl_t
;
291 * The tavor_cmd_reg_t structure is used to hold the address of the each of
292 * the most frequently accessed hardware registers. Specifically, it holds
293 * the HCA Command Registers (HCR, used to pass command and mailbox
294 * information back and forth to Tavor firmware) and the lock used to guarantee
295 * mutually exclusive access to the registers. It also holds the Event Cause
296 * Register (ECR) and its related clear register. These are used to indicate
297 * during interrupt processing which EQs have fired and require servicing.
298 * Related to this, is the "clr_int" register which is used to clear the
299 * interrupt once all EQs have been services.
300 * Finally, there is the software reset register which is used to reinitialize
301 * the Tavor device and to put it into a known state at driver startup time.
302 * Below we also have the offsets (into the CMD register space) for each of
303 * the various registers.
305 typedef struct tavor_cmd_reg_s
{
313 _NOTE(MUTEX_PROTECTS_DATA(tavor_cmd_reg_t::hcr_lock
,
314 tavor_cmd_reg_t::hcr
))
318 * The tavor_state_t structure is the Tavor software state structure. It
319 * contains all the pointers and placeholder for everything that the Tavor
320 * driver needs to properly operate. One of these structures exists for
321 * every instance of the Tavor driver.
323 struct tavor_state_s
{
327 /* Tavor interrupt/MSI information */
328 int ts_intr_types_avail
;
329 uint_t ts_intr_type_chosen
;
330 int ts_intrmsi_count
;
331 int ts_intrmsi_avail
;
332 int ts_intrmsi_allocd
;
333 ddi_intr_handle_t ts_intrmsi_hdl
;
334 uint_t ts_intrmsi_pri
;
337 /* Tavor device operational mode */
338 int ts_operational_mode
;
340 /* Attach buffer saved per state to store detailed attach errors */
341 char ts_attach_buf
[TAVOR_ATTACH_MSGSIZE
];
344 * Tavor NodeGUID, SystemImageGUID, NodeDescription, HCA name,
345 * and HCA part number.
347 uint64_t ts_nodeguid
;
348 uint64_t ts_sysimgguid
;
349 char ts_nodedesc
[64];
350 char ts_hca_name
[64];
354 /* Info passed to IBTF during registration */
355 ibc_hca_info_t ts_ibtfinfo
;
356 ibc_clnt_hdl_t ts_ibtfpriv
;
359 * Tavor register mapping. Holds the device access attributes,
360 * kernel mapped addresses, and DDI access handles for each of
361 * Tavor's three types of address register (CMD, UAR, and DDR).
363 ddi_device_acc_attr_t ts_reg_accattr
;
364 caddr_t ts_reg_cmd_baseaddr
; /* Tavor CMD BAR */
365 ddi_acc_handle_t ts_reg_cmdhdl
;
366 caddr_t ts_reg_uar_baseaddr
; /* Tavor UAR BAR */
367 ddi_acc_handle_t ts_reg_uarhdl
;
368 caddr_t ts_reg_ddr_baseaddr
; /* Tavor DDR BAR */
369 ddi_acc_handle_t ts_reg_ddrhdl
;
372 * Tavor PCI config space registers. These two arrays are used to
373 * save and restore the PCI config registers before and after a
374 * software reset. Note: We must save away both our own registers
375 * and our parent's (the "virtual" PCI bridge in the device) because
376 * the software reset will reset both sets.
378 uint32_t ts_cfg_data
[TAVOR_SW_RESET_NUMREGS
];
379 uint32_t ts_cfg_pdata
[TAVOR_SW_RESET_NUMREGS
];
382 * Tavor UAR page resources. Holds the resource pointers for
383 * UAR page #0 (reserved) and for UAR page #1 (used for kernel
384 * driver doorbells). In addition, we save a pointer to the
385 * UAR page #1 doorbells which will be used throughout the driver
386 * whenever it is necessary to ring one of them. And, in case we
387 * are unable to do 64-bit writes to the page (because of system
388 * architecture), we include a lock (to ensure atomic 64-bit access).
390 tavor_rsrc_t
*ts_uarpg0_rsrc_rsrvd
;
391 tavor_rsrc_t
*ts_uarpg1_rsrc
;
392 tavor_hw_uar_t
*ts_uar
;
393 kmutex_t ts_uar_lock
;
396 * Used during a call to open() if we are in maintenance mode, this
397 * field serves as a semi-unique rolling count index value, used only
398 * in the setup of umap_db entries. This is primarily needed to
399 * firmware device access ioctl operations can still be guaranteed to
400 * close in the event of an unplanned process exit, even in maintenance
403 uint_t ts_open_tr_indx
;
406 * Tavor command registers. This structure contains the addresses
407 * for each of the most frequently accessed CMD registers. Since
408 * almost all accesses to the Tavor hardware are through the Tavor
409 * command interface (i.e. the HCR), we save away the pointer to
410 * the HCR, as well as pointers to the ECR and INT registers (as
411 * well as their corresponding "clear" registers) for interrupt
412 * processing. And we also save away a pointer to the software
413 * reset register (see above).
415 tavor_cmd_reg_t ts_cmd_regs
;
418 * Tavor resource pointers. The following are pointers to the vmem
419 * arena (created to manage the DDR memory), the kmem cache (from
420 * which the Tavor resource handles are allocated), and the array
421 * of "resource pools" (which store all the pertinent information
422 * necessary to manage each of the various types of resources that
423 * are used by the Tavor driver. See tavor_rsrc.h for more detail.
426 kmem_cache_t
*ts_rsrc_cache
;
427 tavor_rsrc_pool_info_t
*ts_rsrc_hdl
;
430 * Tavor mailbox lists. These hold the information necessary to
431 * manage the pools of pre-allocated Tavor mailboxes (both "In" and
432 * "Out" type). See tavor_cmd.h for more detail.
434 tavor_mboxlist_t ts_in_mblist
;
435 tavor_mboxlist_t ts_out_mblist
;
438 * Tavor interrupt mailbox lists. We allocate both an "In" mailbox
439 * and an "Out" type mailbox for the interrupt context. This is in
440 * order to guarantee that a mailbox entry will always be available in
441 * the interrupt context, and we can NOSLEEP without having to worry
442 * about possible failure allocating the mbox. We create this as an
443 * mboxlist so that we have the potential for having multiple mboxes
444 * available based on the number of interrupts we can receive at once.
446 tavor_mboxlist_t ts_in_intr_mblist
;
447 tavor_mboxlist_t ts_out_intr_mblist
;
450 * Tavor outstanding command list. Used to hold all the information
451 * necessary to manage the Tavor "outstanding command list". See
452 * tavor_cmd.h for more detail.
454 tavor_cmdlist_t ts_cmd_list
;
457 * This structure contains the Tavor driver's "configuration profile".
458 * This is the collected set of configuration information, such as
459 * number of QPs, CQs, mailboxes and other resources, sizes of
460 * individual resources, other system level configuration information,
461 * etc. See tavor_cfg.h for more detail.
463 tavor_cfg_profile_t
*ts_cfg_profile
;
466 * This flag contains the profile setting, selecting which profile the
467 * driver would use. This is needed in the case where we have to
468 * fallback to a smaller profile based on some DDR conditions. If we
469 * don't fallback, then it is set to the size of DDR in the system.
471 uint32_t ts_cfg_profile_setting
;
474 * The following are a collection of resource handles used by the
475 * Tavor driver (internally). First is the protection domain (PD)
476 * handle that is used when mapping all kernel memory (work queues,
477 * completion queues, etc). Next is an array of EQ handles. This
478 * array is indexed by EQ number and allows the Tavor driver to quickly
479 * convert an EQ number into the software structure associated with the
480 * given EQ. Likewise, we have three arrays for CQ, QP and SRQ
481 * handles. These arrays are also indexed by CQ, QP or SRQ number and
482 * allow the driver to quickly find the corresponding CQ, QP or SRQ
483 * software structure. Note: while the EQ table is of fixed size
484 * (because there are a maximum of 64 EQs), each of the CQ, QP and SRQ
485 * handle lists must be allocated at driver startup.
487 tavor_pdhdl_t ts_pdhdl_internal
;
488 tavor_eqhdl_t ts_eqhdl
[TAVOR_NUM_EQ
];
489 tavor_cqhdl_t
*ts_cqhdl
;
490 tavor_qphdl_t
*ts_qphdl
;
491 tavor_srqhdl_t
*ts_srqhdl
;
494 * The AVL tree is used to store information regarding QP number
495 * allocations. The lock protects access to the AVL tree.
497 avl_tree_t ts_qpn_avl
;
498 kmutex_t ts_qpn_avl_lock
;
501 * This field is used to indicate whether or not the Tavor driver is
502 * currently in an IBTF event callback elsewhere in the system. Note:
503 * It is "volatile" because we intend to poll on this value - in
504 * tavor_detach() - until we are assured that no further IBTF callbacks
505 * are currently being processed.
507 volatile uint32_t ts_in_evcallb
;
510 * The following structures are used to store the results of several
511 * device query commands passed to the Tavor hardware at startup.
512 * Specifically, we have hung onto the results of QUERY_DDR (which
513 * gives information about how much DDR memory is present and where
514 * it is located), QUERY_FW (which gives information about firmware
515 * version numbers and the location and extent of firmware's footprint
516 * in DDR, QUERY_DEVLIM (which gives the device limitations/resource
517 * maximums), QUERY_ADAPTER (which gives additional miscellaneous
518 * information), and INIT/QUERY_HCA (which serves the purpose of
519 * recording what configuration information was passed to the firmware
520 * when the HCA was initialized).
522 struct tavor_hw_queryddr_s ts_ddr
;
523 struct tavor_hw_queryfw_s ts_fw
;
524 struct tavor_hw_querydevlim_s ts_devlim
;
525 struct tavor_hw_queryadapter_s ts_adapter
;
526 struct tavor_hw_initqueryhca_s ts_hcaparams
;
529 * The following are used for managing special QP resources.
530 * Specifically, we have a lock, a set of flags (in "ts_spec_qpflags")
531 * used to track the special QP resources, and two Tavor resource
532 * handle pointers. Each resource handle actually corresponds to two
533 * consecutive QP contexts (one per port) for each special QP type.
535 kmutex_t ts_spec_qplock
;
536 uint_t ts_spec_qpflags
;
537 tavor_rsrc_t
*ts_spec_qp0
;
538 tavor_rsrc_t
*ts_spec_qp1
;
541 * Related in some ways to the special QP handling above are these
542 * resources which are used specifically for implementing the Tavor
543 * agents (SMA, PMA, and BMA). Although, each of these agents does
544 * little more that intercept the appropriate incoming MAD and forward
545 * it along to the firmware (see tavor_agents.c for more details), we
546 * do still use a task queue to queue them up. We can also configure
547 * the driver to force firmware handling for certain classes of MAD,
548 * and, therefore, we require the agent list and number of agents
549 * in order to know what needs to be torn down at detach() time.
551 tavor_agent_list_t
*ts_agents
;
552 ddi_taskq_t
*ts_taskq_agents
;
553 uint_t ts_num_agents
;
556 * Multicast group lists. These are used to track the "shadow" MCG
557 * lists that speed up the processing of attach and detach multicast
558 * group operations. See tavor_misc.h for more details. Note: we
559 * need the pointer to the "temporary" MCG entry here primarily
560 * because the size of a given MCG entry is configurable. Therefore,
561 * it is impossible to put this variable on the stack. And rather
562 * than allocate and deallocate the entry multiple times, we choose
563 * instead to preallocate it once and reuse it over and over again.
566 tavor_mcghdl_t ts_mcghdl
;
567 tavor_hw_mcg_t
*ts_mcgtmp
;
570 * Used for tracking Tavor kstat information
572 tavor_ks_info_t
*ts_ks_info
;
575 * Used for Tavor info ioctl used by VTS
577 kmutex_t ts_info_lock
;
580 * Used for Tavor FW flash burning. They are used exclusively
581 * within the ioctl calls for use when accessing the tavor
584 kmutex_t ts_fw_flashlock
;
585 int ts_fw_flashstarted
;
586 dev_t ts_fw_flashdev
;
587 uint32_t ts_fw_log_sector_sz
;
588 uint32_t ts_fw_device_sz
;
589 uint32_t ts_fw_flashbank
;
590 uint32_t *ts_fw_sector
;
591 uint32_t ts_fw_gpio
[4];
592 ddi_acc_handle_t ts_pci_cfghdl
; /* PCI cfg handle */
595 /* Tavor fastreboot support */
596 boolean_t ts_quiescing
; /* in fastreboot */
598 _NOTE(MUTEX_PROTECTS_DATA(tavor_state_s::ts_fw_flashlock
,
599 tavor_state_s::ts_fw_flashstarted
600 tavor_state_s::ts_fw_flashdev
601 tavor_state_s::ts_fw_log_sector_sz
602 tavor_state_s::ts_fw_device_sz
))
603 _NOTE(MUTEX_PROTECTS_DATA(tavor_state_s::ts_spec_qplock
,
604 tavor_state_s::ts_spec_qpflags
605 tavor_state_s::ts_spec_qp0
606 tavor_state_s::ts_spec_qp1
))
607 _NOTE(MUTEX_PROTECTS_DATA(tavor_state_s::ts_mcglock
,
608 tavor_state_s::ts_mcghdl
609 tavor_state_s::ts_mcgtmp
))
610 _NOTE(DATA_READABLE_WITHOUT_LOCK(tavor_state_s::ts_in_evcallb
611 tavor_state_s::ts_fw_log_sector_sz
612 tavor_state_s::ts_fw_device_sz
613 tavor_state_s::ts_fw_sector
614 tavor_state_s::ts_spec_qpflags
615 tavor_state_s::ts_spec_qp0
616 tavor_state_s::ts_spec_qp1
))
617 _NOTE(MUTEX_PROTECTS_DATA(tavor_state_s::ts_qpn_avl_lock
,
618 tavor_state_s::ts_qpn_avl
))
621 * TAVOR_IN_FASTREBOOT() shows if Hermon driver is at fastreboot.
622 * This macro should be used to check if the mutex lock can be used
623 * since the lock cannot be used if the driver is in the quiesce mode.
625 #define TAVOR_IN_FASTREBOOT(state) (state->ts_quiescing == B_TRUE)
628 * Bit positions in the "ts_spec_qpflags" field above. The flags are (from
629 * least significant to most): (QP0,Port1), (QP0,Port2), (QP1,Port1), and
630 * (QP1,Port2). The masks are there to help with some specific allocation
631 * and freeing operations
633 #define TAVOR_SPECIAL_QP0_RSRC 0
634 #define TAVOR_SPECIAL_QP0_RSRC_MASK 0x3
635 #define TAVOR_SPECIAL_QP1_RSRC 2
636 #define TAVOR_SPECIAL_QP1_RSRC_MASK 0xC
640 * These flags specifies additional behaviors on database access.
641 * TAVOR_UMAP_DB_REMOVE, for example, specifies that (if found) the database
642 * entry should be removed from the database. TAVOR_UMAP_DB_IGNORE_INSTANCE
643 * specifies that a particular database query should ignore value in the
644 * "tdb_instance" field as a criterion for the search.
646 #define TAVOR_UMAP_DB_REMOVE (1 << 0)
647 #define TAVOR_UMAP_DB_IGNORE_INSTANCE (1 << 1)
651 * The tavor_umap_db_t structure contains what is referred to throughout the
652 * driver code as the "userland resources database". This structure contains
653 * all the necessary information to track resources that have been prepared
654 * for direct-from-userland access. There is an AVL tree ("tdl_umapdb_avl")
655 * which consists of the "tavor_umap_db_entry_t" (below) and a lock to ensure
656 * atomic access when adding or removing entries from the database.
658 typedef struct tavor_umap_db_s
{
659 kmutex_t tdl_umapdb_lock
;
660 avl_tree_t tdl_umapdb_avl
;
664 * The tavor_umap_db_priv_t structure currently contains information necessary
665 * to provide the "on close" callback to the firmware flash interfaces. It
666 * is intended that this structure could be extended to enable other "on
667 * close" callbacks as well.
669 typedef struct tavor_umap_db_priv_s
{
670 void (*tdp_cb
)(void *);
672 } tavor_umap_db_priv_t
;
675 * The tavor_umap_db_common_t structure contains fields which are common
676 * between the database entries ("tavor_umap_db_entry_t") and the structure
677 * used to contain the search criteria ("tavor_umap_db_query_t"). This
678 * structure contains a key, a resource type (described above), an instance
679 * (corresponding to the driver instance which inserted the database entry),
680 * and a "value" field. Typically, "tdb_value" is a pointer to a Tavor
681 * resource object. Although for memory regions, the value field corresponds
682 * to the ddi_umem_cookie_t for the pinned userland memory.
683 * The structure also includes a placeholder for private data ("tdb_priv").
684 * Currently this data is being used for holding "on close" callback
685 * information to allow certain kinds of cleanup even if a userland process
688 typedef struct tavor_umap_db_common_s
{
694 } tavor_umap_db_common_t
;
697 * The tavor_umap_db_entry_t structure is the entry in "userland resources
698 * database". As required by the AVL framework, each entry contains an
699 * "avl_node_t". Then, as required to implement the database, each entry
700 * contains a "tavor_umap_db_common_t" structure used to contain all of the
703 typedef struct tavor_umap_db_entry_s
{
704 avl_node_t tdbe_avlnode
;
705 tavor_umap_db_common_t tdbe_common
;
706 } tavor_umap_db_entry_t
;
709 * The tavor_umap_db_query_t structure is used in queries to the "userland
710 * resources database". In addition to the "tavor_umap_db_common_t" structure
711 * used to contain the various search criteria, this structure also contains
712 * a flags field "tqdb_flags" which can be used to specify additional behaviors
713 * (as described above). Specifically, the flags field can be used to specify
714 * that an entry should be removed from the database, if found, and to
715 * specify whether the database lookup should consider "tdb_instance" in the
718 typedef struct tavor_umap_db_query_s
{
720 tavor_umap_db_common_t tqdb_common
;
721 } tavor_umap_db_query_t
;
722 _NOTE(MUTEX_PROTECTS_DATA(tavor_umap_db_s::tdl_umapdb_lock
,
723 tavor_umap_db_entry_s::tdbe_avlnode
724 tavor_umap_db_entry_s::tdbe_common
.tdb_key
725 tavor_umap_db_entry_s::tdbe_common
.tdb_value
726 tavor_umap_db_entry_s::tdbe_common
.tdb_type
727 tavor_umap_db_entry_s::tdbe_common
.tdb_instance
))
730 * The tavor_devmap_track_t structure contains all the necessary information
731 * to track resources that have been mapped through devmap. There is a
732 * back-pointer to the Tavor softstate, the logical offset corresponding with
733 * the mapped resource, the size of the mapped resource (zero indicates an
734 * "invalid mapping"), and a reference count and lock used to determine when
735 * to free the structure (specifically, this is necessary to handle partial
738 typedef struct tavor_devmap_track_s
{
739 tavor_state_t
*tdt_state
;
744 } tavor_devmap_track_t
;
747 /* Defined in tavor_umap.c */
748 int tavor_devmap(dev_t dev
, devmap_cookie_t dhp
, offset_t off
, size_t len
,
749 size_t *maplen
, uint_t model
);
750 ibt_status_t
tavor_umap_ci_data_in(tavor_state_t
*state
,
751 ibt_ci_data_flags_t flags
, ibt_object_type_t object
, void *hdl
,
752 void *data_p
, size_t data_sz
);
753 ibt_status_t
tavor_umap_ci_data_out(tavor_state_t
*state
,
754 ibt_ci_data_flags_t flags
, ibt_object_type_t object
, void *hdl
,
755 void *data_p
, size_t data_sz
);
756 void tavor_umap_db_init(void);
757 void tavor_umap_db_fini(void);
758 tavor_umap_db_entry_t
*tavor_umap_db_alloc(uint_t instance
, uint64_t key
,
759 uint_t type
, uint64_t value
);
760 void tavor_umap_db_free(tavor_umap_db_entry_t
*umapdb
);
761 void tavor_umap_db_add(tavor_umap_db_entry_t
*umapdb
);
762 void tavor_umap_db_add_nolock(tavor_umap_db_entry_t
*umapdb
);
763 int tavor_umap_db_find(uint_t instance
, uint64_t key
, uint_t type
,
764 uint64_t *value
, uint_t flags
, tavor_umap_db_entry_t
**umapdb
);
765 int tavor_umap_db_find_nolock(uint_t instance
, uint64_t key
, uint_t type
,
766 uint64_t *value
, uint_t flags
, tavor_umap_db_entry_t
**umapdb
);
767 void tavor_umap_umemlock_cb(ddi_umem_cookie_t
*umem_cookie
);
768 int tavor_umap_db_set_onclose_cb(dev_t dev
, uint64_t flag
,
769 void (*callback
)(void *), void *arg
);
770 int tavor_umap_db_clear_onclose_cb(dev_t dev
, uint64_t flag
);
771 void tavor_umap_db_handle_onclose_cb(tavor_umap_db_priv_t
*priv
);
777 #endif /* _SYS_IB_ADAPTERS_TAVOR_H */