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 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #ifndef _SYS_IB_ADAPTERS_TAVOR_MISC_H
28 #define _SYS_IB_ADAPTERS_TAVOR_MISC_H
32 * Contains all of the prototypes, #defines, and structures necessary
33 * for the Tavor Miscellaneous routines - Address Handle, Multicast,
34 * Protection Domain, port-related, statistics (kstat) routines, and
35 * extra VTS related routines.
36 * Many of these functions are called by other parts of the Tavor driver
37 * (and several routines are directly exposed through the IBTF CI
38 * interface and/or kstat interface).
41 #include <sys/types.h>
44 #include <sys/sunddi.h>
46 #include <sys/ib/adapters/tavor/tavor_ioctl.h>
53 * The following defines specify the default number of Address Handles (AH)
54 * and their size (in the hardware). By default the maximum number of address
55 * handles is set to 32K. This value is controllable through the
56 * "tavor_log_num_ah" configuration variable. Note: Tavor Address Handles
57 * are also referred to as UD Address Vectors (UDAV).
59 #define TAVOR_NUM_AH_SHIFT 0xF
60 #define TAVOR_NUM_AH (1 << TAVOR_NUM_AH_SHIFT)
61 #define TAVOR_UDAV_SIZE_SHIFT 0x5
62 #define TAVOR_UDAV_SIZE (1 << TAVOR_UDAV_SIZE_SHIFT)
65 * Minimal configuration value.
67 #define TAVOR_NUM_AH_SHIFT_MIN 0xA
70 * The following macro determines whether the contents of a UDAV need to be
71 * sync'd (with ddi_dma_sync()). This decision is based on whether the
72 * UDAV is in DDR memory (no sync) or system memory (sync required).
74 #define TAVOR_UDAV_IS_SYNC_REQ(state) \
75 (((&((state)->ts_rsrc_hdl[TAVOR_UDAV]))->rsrc_loc == \
76 TAVOR_IN_DDR) ? 0 : 1)
79 * These defines are used by tavor_get_addr_path() and tavor_set_addr_path()
80 * below. They indicate the type of hardware context being passed in the
81 * "path" argument. Because the Tavor hardware formats for the QP address
82 * path and UDAV address path structures is so similar, but not exactly the
83 * same, we use these flags to indicate which type of structure is being
84 * read from or written to.
86 #define TAVOR_ADDRPATH_QP 0x0
87 #define TAVOR_ADDRPATH_UDAV 0x1
91 * The following defines specify the default number of Multicast Groups (MCG)
92 * and the maximum number of QP which can be associated with each. By default
93 * the maximum number of multicast groups is set to 256, and the maximum number
94 * of QP per multicast group is set to 8. These values are controllable
95 * through the "tavor_log_num_mcg" and "tavor_num_qp_per_mcg" configuration
97 * We also define a macro below that is used to determine the size of each
98 * individual MCG entry (in hardware) based on the number of QP to be
99 * supported per multicast group.
101 #define TAVOR_NUM_MCG_SHIFT 0x8
102 #define TAVOR_NUM_MCG (1 << TAVOR_NUM_MCG_SHIFT)
103 #define TAVOR_NUM_QP_PER_MCG 8
106 * Minimal configuration values.
108 #define TAVOR_NUM_MCG_SHIFT_MIN 0x4
109 #define TAVOR_NUM_QP_PER_MCG_MIN 0x1
112 * Macro to compute the offset of the QP list in a given MCG entry.
114 #define TAVOR_MCGMEM_SZ(state) \
115 ((((state)->ts_cfg_profile->cp_num_qp_per_mcg) + 8) << 2)
116 #define TAVOR_MCG_GET_QPLIST_PTR(mcg) \
117 ((tavor_hw_mcg_qp_list_t *)((uintptr_t)(mcg) + \
118 sizeof (tavor_hw_mcg_t)))
121 * The following defines specify the characteristics of the Tavor multicast
122 * group hash table. The TAVOR_NUM_MCG_HASH_SHIFT defines the size of the
123 * hash table (as a power-of-2), which is set to 16 by default. This value
124 * is controllable through the "tavor_log_num_mcg_hash" configuration variable,
125 * but serious consideration should be taken before changing this value. Note:
126 * its appropriate size should be a function of the entire table size (as
127 * defined by "tavor_log_num_mcg" and TAVOR_NUM_MCG_SHIFT above).
129 #define TAVOR_NUM_MCG_HASH_SHIFT 0x4
132 * Minimal configuration value.
134 #define TAVOR_NUM_MCG_HASH_SHIFT_MIN 0x2
137 * The following defines are used by the multicast routines to determine
138 * if a given "multicast GID" is valid or not (see tavor_mcg_is_mgid_valid
139 * for more details. These values are pulled from the IBA specification,
142 #define TAVOR_MCG_TOPBITS_SHIFT 56
143 #define TAVOR_MCG_TOPBITS_MASK 0xFF
144 #define TAVOR_MCG_TOPBITS 0xFF
146 #define TAVOR_MCG_FLAGS_SHIFT 52
147 #define TAVOR_MCG_FLAGS_MASK 0xF
148 #define TAVOR_MCG_FLAGS_PERM 0x0
149 #define TAVOR_MCG_FLAGS_NONPERM 0x1
151 #define TAVOR_MCG_SCOPE_SHIFT 48
152 #define TAVOR_MCG_SCOPE_MASK 0xF
153 #define TAVOR_MCG_SCOPE_LINKLOC 0x2
154 #define TAVOR_MCG_SCOPE_SITELOC 0x5
155 #define TAVOR_MCG_SCOPE_ORGLOC 0x8
156 #define TAVOR_MCG_SCOPE_GLOBAL 0xE
160 * The following defines specify the default number of Protection Domains (PD).
161 * By default the maximum number of protection domains is set to 64K. This
162 * value is controllable through the "tavor_log_num_pd" configuration variable.
164 #define TAVOR_NUM_PD_SHIFT 0x10
165 #define TAVOR_NUM_PD (1 << TAVOR_NUM_PD_SHIFT)
168 * The following defines specify the default number of Partition Keys (PKey)
169 * per port. By default the maximum number of PKeys is set to 32 per port, for
170 * a total of 64 (assuming two ports) . This value is controllable through the
171 * "tavor_log_max_pkeytbl" configuration variable.
173 #define TAVOR_NUM_PKEYTBL_SHIFT 0x5
174 #define TAVOR_NUM_PKEYTBL (1 << TAVOR_NUM_PKEYTBL_SHIFT)
177 * The following defines specify the default number of SGIDs per port. By
178 * default the maximum number of GIDS per port is set to 16. This value
179 * is controllable through the "tavor_log_max_gidtbl" configuration variable.
181 #define TAVOR_NUM_GIDTBL_SHIFT 0x4
182 #define TAVOR_NUM_GIDTBL (1 << TAVOR_NUM_GIDTBL_SHIFT)
185 * The following defines specify the default number of UAR pages. By
186 * default the maximum number of UAR pages is set to 1024. This value
187 * is controllable through the "tavor_log_num_uar" configuration variable.
188 * NOTE: This value should not be set larger than 15 (0xF) because the
189 * UAR index number is used as part of the minor number calculation (see
190 * tavor_open() for details) and the minor numbers should not be larger
191 * than eighteen bits (i.e. 15 bits of UAR index, 3 bits of driver instance
192 * number). This is especially true for 32-bit kernels.
194 #define TAVOR_NUM_UAR_SHIFT 0xA
195 #define TAVOR_NUM_UAR (1 << TAVOR_NUM_UAR_SHIFT)
198 * Minimal configuration value.
200 #define TAVOR_NUM_UAR_SHIFT_MIN 0x4
203 * These defines specify some miscellaneous port-related configuration
204 * information. Specifically, TAVOR_MAX_MTU is used to define the maximum
205 * MTU supported for each Tavor port, TAVOR_MAX_PORT_WIDTH is used to define
206 * the maximum supported port width, and the TAVOR_MAX_VLCAP define is used
207 * to specify the maximum number of VLs supported, excluding VL15. Both
208 * of these values are controllable and get be set using the "tavor_max_mtu"
209 * and "tavor_max_vlcap" configuration variables. Note: as with many of the
210 * configurable variables, caution should be exercised when changing these
211 * values. These values, specifically, should not be set any larger than
212 * they are defined here as these are set to the current Tavor device
215 #define TAVOR_MAX_MTU 0x4
216 #define TAVOR_MAX_PORT_WIDTH 0x3
217 #define TAVOR_MAX_VLCAP 0x8
220 * These last defines are used by the statistics counting routines (kstats)
221 * for initialization of the structures associated with the IB statistics
222 * access routines. The TAVOR_CNTR_MASK and TAVOR_CNTR_SIZE defines are
223 * used to divide the "pcr" register into two 32-bit counters (one for "pic0"
224 * and the other for "pic1")
226 #define TAVOR_CNTR_MASK 0xFFFFFFFF
227 #define TAVOR_CNTR_SIZE 32
228 #define TAVOR_CNTR_NUMENTRIES 17
231 * The following defines are used by tavor_queue_alloc() to specify whether
232 * a given QP/CQ/EQ queue memory should be allocated from kernel system memory
233 * (TAVOR_QUEUE_LOCATION_NORMAL), from user-mappable system memory
234 * (TAVOR_QUEUE_LOCATION_USERLAND), or from local-attached DDR memory
235 * (TAVOR_QUEUE_LOCATION_INDDR).
237 #define TAVOR_QUEUE_LOCATION_NORMAL 0x1
238 #define TAVOR_QUEUE_LOCATION_USERLAND 0x2
239 #define TAVOR_QUEUE_LOCATION_INDDR 0x3
242 * Minimum number of ticks to delay between successive polls of the CQ in
243 * VTS ioctl loopback test
245 #define TAVOR_VTS_LOOPBACK_MIN_WAIT_DUR 50
249 * The tavor_sw_ah_s structure is also referred to using the "tavor_ahhdl_t"
250 * typedef (see tavor_typedef.h). It encodes all the information necessary
251 * to track the various resources (e.g. the UDAV hardware resource) needed to
252 * allocate, query, modify, and (later) free an address handle.
254 * In specific, it has a lock to ensure single-threaded access, it stores a
255 * pointer to the associated MR handle (for the mapped UDAV memory) and a
256 * pointer to the associated PD handle. And it also contains a copy of the
257 * GUID stored into the address handle. The reason for this extra copy of
258 * the GUID info has to do with Tavor PRM compliance and is fully explained
261 * It also has the always necessary backpointer to the resource for the AH
262 * handle structure itself.
264 struct tavor_sw_ah_s
{
266 tavor_pdhdl_t ah_pdhdl
;
267 tavor_mrhdl_t ah_mrhdl
;
268 tavor_rsrc_t
*ah_udavrsrcp
;
269 tavor_rsrc_t
*ah_rsrcp
;
270 uint64_t ah_save_guid
;
271 ibt_srate_t ah_save_srate
;
274 _NOTE(MUTEX_PROTECTS_DATA(tavor_sw_ah_s::ah_lock
,
275 tavor_sw_ah_s::ah_pdhdl
276 tavor_sw_ah_s::ah_mrhdl
277 tavor_sw_ah_s::ah_udavrsrcp
278 tavor_sw_ah_s::ah_rsrcp
279 tavor_sw_ah_s::ah_save_guid
280 tavor_sw_ah_s::ah_sync
))
283 * The tavor_sw_mcg_list_s structure is also referred to using the
284 * "tavor_mcghdl_t" typedef (see tavor_typedef.h). It encodes all the
285 * information necessary to track the various resources needed to for attaching
286 * and detaching QP from multicast groups.
288 * The Tavor driver keeps an array of these and uses them as a shadow for
289 * the real HW-based MCG table. They hold all the necessary information
290 * to track the resources and to allow fast access to the MCG table. First,
291 * it had a 128-bit multicast GID (stored in "mcg_mgid_h" and "mcg_mgid_l".
292 * next if has a field to indicate the index of the next tavor_mcghdl_t in
293 * the current hash chain (zero is the end of the chain). Note: this very
294 * closely mimics what the hardware MCG entry has. Then it has a field to
295 * indicate how many QP are currently attached to the given MCG. And, lastly,
296 * it has the obligatory backpointer to the resource for the MCH handle
299 struct tavor_sw_mcg_list_s
{
302 uint_t mcg_next_indx
;
304 tavor_rsrc_t
*mcg_rsrcp
;
308 * The tavor_sw_pd_s structure is also referred to using the "tavor_pdhdl_t"
309 * typedef (see tavor_typedef.h). It encodes all the information necessary
310 * to track the various resources needed to allocate and free protection
313 * Specifically, it has reference count and a lock to ensure single threaded
314 * access to it. It has a field for the protection domain number ("pd_pdnum").
315 * And it also has the obligatory backpointer to the resource for the PD
316 * handle structure itself.
318 struct tavor_sw_pd_s
{
322 tavor_rsrc_t
*pd_rsrcp
;
324 _NOTE(READ_ONLY_DATA(tavor_sw_pd_s::pd_pdnum
325 tavor_sw_pd_s::pd_rsrcp
))
326 _NOTE(MUTEX_PROTECTS_DATA(tavor_sw_pd_s::pd_lock
,
327 tavor_sw_pd_s::pd_refcnt
))
330 * The tavor_qalloc_info_s structure is also referred to using the
331 * "tavor_qalloc_info_t" typedef (see tavor_typedef.h). It holds all the
332 * information necessary to track the resources for each of the various Tavor
333 * queue types (i.e. Event Queue, Completion Queue, Work Queue).
335 * Specifically, it has the size, alignment restrictions, and location (in DDR
336 * or in system memory). And depending on the location, it also has the
337 * ddi_dma_handle_t, ddi_acc_handle_t, and pointers used for reading/writing to
338 * the queue's memory.
340 struct tavor_qalloc_info_s
{
342 uint64_t qa_alloc_align
;
343 uint64_t qa_bind_align
;
344 uint32_t *qa_buf_real
;
345 uint32_t *qa_buf_aligned
;
346 uint64_t qa_buf_realsz
;
348 ddi_dma_handle_t qa_dmahdl
;
349 ddi_acc_handle_t qa_acchdl
;
350 ddi_umem_cookie_t qa_umemcookie
;
354 * The tavor_ks_mask_t structure encodes all the information necessary for
355 * the individual kstat entries. The "ks_reg_offset" field contains the
356 * hardware offset for the corresponding counter, and "ks_reg_shift" and
357 * "ks_reg_mask" contain shift and mask registers used by the access routines.
358 * Also the "ks_old_pic0" and "ks_old_pic1" fields contain the most recently
359 * read value for the corresponding port ("pic"). Note: An array of these
360 * structures is part of the "tavor_ks_info_t" structure below.
362 typedef struct tavor_ks_mask_s
{
364 uint64_t ks_reg_offset
;
365 uint32_t ks_reg_shift
;
366 uint32_t ks_reg_mask
;
367 uint32_t ks_old_pic0
;
368 uint32_t ks_old_pic1
;
372 * Index into the named data components of 64 bit "perf_counters" kstat.
375 TAVOR_PERFCNTR64_ENABLE_IDX
= 0,
376 TAVOR_PERFCNTR64_XMIT_DATA_IDX
,
377 TAVOR_PERFCNTR64_RECV_DATA_IDX
,
378 TAVOR_PERFCNTR64_XMIT_PKTS_IDX
,
379 TAVOR_PERFCNTR64_RECV_PKTS_IDX
,
380 TAVOR_PERFCNTR64_NUM_COUNTERS
384 * Data associated with the 64 bit "perf_counters" kstat. One for each port.
386 typedef struct tavor_perfcntr64_ks_info_s
{
387 struct kstat
*tki64_ksp
;
389 uint64_t tki64_counters
[TAVOR_PERFCNTR64_NUM_COUNTERS
];
390 uint32_t tki64_last_read
[TAVOR_PERFCNTR64_NUM_COUNTERS
];
391 uint_t tki64_port_num
;
392 tavor_state_t
*tki64_state
;
393 } tavor_perfcntr64_ks_info_t
;
397 * The tavor_ks_info_t structure stores all the information necessary for
398 * tracking the resources associated with each of the various kstats. In
399 * addition to containing pointers to each of the counter and pic kstats,
400 * this structure also contains "tki_pcr" which is the control register that
401 * determines which of the countable entries (from the "tki_ib_perfcnt[]"
402 * array) is being currently accessed.
404 typedef struct tavor_ks_info_s
{
405 struct kstat
*tki_cntr_ksp
;
406 struct kstat
*tki_picN_ksp
[TAVOR_NUM_PORTS
];
410 tavor_ks_mask_t tki_ib_perfcnt
[TAVOR_CNTR_NUMENTRIES
];
411 kt_did_t tki_perfcntr64_thread_id
;
412 kmutex_t tki_perfcntr64_lock
;
413 kcondvar_t tki_perfcntr64_cv
;
414 uint_t tki_perfcntr64_flags
; /* see below */
415 tavor_perfcntr64_ks_info_t tki_perfcntr64
[TAVOR_NUM_PORTS
];
418 /* tki_perfcntr64_flags */
419 #define TAVOR_PERFCNTR64_THREAD_CREATED 0x0001
420 #define TAVOR_PERFCNTR64_THREAD_EXIT 0x0002
423 * The tavor_ports_ioctl32_t, tavor_loopback_ioctl32_t, and
424 * tavor_flash_ioctl32_s structures are used internally by the Tavor
425 * driver to accomodate 32-bit applications which need to access the
426 * Tavor ioctls. They are 32-bit versions of externally available
427 * structures defined in tavor_ioctl.h
429 typedef struct tavor_ports_ioctl32_s
{
432 uint8_t tp_num_ports
;
433 } tavor_ports_ioctl32_t
;
435 typedef struct tavor_loopback_ioctl32_s
{
437 caddr32_t tlb_send_buf
;
438 caddr32_t tlb_fail_buf
;
441 uint_t tlb_pass_done
;
443 tavor_loopback_error_t tlb_error_type
;
444 uint8_t tlb_port_num
;
445 uint8_t tlb_num_retry
;
446 } tavor_loopback_ioctl32_t
;
448 typedef struct tavor_flash_ioctl32_s
{
451 uint32_t tf_sector_num
;
455 } tavor_flash_ioctl32_t
;
458 * The tavor_loopback_comm_t and tavor_loopback_state_t structures below
459 * are used to store all of the relevant state information needed to keep
460 * track of a single VTS ioctl loopback test run.
462 typedef struct tavor_loopback_comm_s
{
465 ibt_mr_desc_t tlc_mrdesc
;
467 tavor_mrhdl_t tlc_mrhdl
;
468 tavor_cqhdl_t tlc_cqhdl
[2];
469 tavor_qphdl_t tlc_qp_hdl
;
471 ibt_mr_attr_t tlc_memattr
;
473 ibt_cq_attr_t tlc_cq_attr
;
474 ibt_qp_alloc_attr_t tlc_qp_attr
;
475 ibt_chan_sizes_t tlc_chan_sizes
;
476 ibt_qp_info_t tlc_qp_info
;
477 ibt_queue_sizes_t tlc_queue_sizes
;
478 ibt_send_wr_t tlc_wr
;
481 uint_t tlc_num_polled
;
482 ibt_status_t tlc_status
;
485 } tavor_loopback_comm_t
;
487 typedef struct tavor_loopback_state_s
{
491 tavor_state_t
*tls_state
;
492 ibc_hca_hdl_t tls_hca_hdl
;
493 tavor_pdhdl_t tls_pd_hdl
;
494 tavor_loopback_comm_t tls_tx
;
495 tavor_loopback_comm_t tls_rx
;
496 ibt_status_t tls_status
;
500 } tavor_loopback_state_t
;
502 /* Tavor Address Handle routines */
503 int tavor_ah_alloc(tavor_state_t
*state
, tavor_pdhdl_t pd
,
504 ibt_adds_vect_t
*attr_p
, tavor_ahhdl_t
*ahhdl
, uint_t sleepflag
);
505 int tavor_ah_free(tavor_state_t
*state
, tavor_ahhdl_t
*ahhdl
,
507 int tavor_ah_query(tavor_state_t
*state
, tavor_ahhdl_t ahhdl
,
508 tavor_pdhdl_t
*pdhdl
, ibt_adds_vect_t
*attr_p
);
509 int tavor_ah_modify(tavor_state_t
*state
, tavor_ahhdl_t ahhdl
,
510 ibt_adds_vect_t
*attr_p
);
512 /* Tavor Multicast Group routines */
513 int tavor_mcg_attach(tavor_state_t
*state
, tavor_qphdl_t qphdl
, ib_gid_t gid
,
515 int tavor_mcg_detach(tavor_state_t
*state
, tavor_qphdl_t qphdl
, ib_gid_t gid
,
518 /* Tavor Protection Domain routines */
519 int tavor_pd_alloc(tavor_state_t
*state
, tavor_pdhdl_t
*pdhdl
,
521 int tavor_pd_free(tavor_state_t
*state
, tavor_pdhdl_t
*pdhdl
);
522 void tavor_pd_refcnt_inc(tavor_pdhdl_t pd
);
523 void tavor_pd_refcnt_dec(tavor_pdhdl_t pd
);
525 /* Tavor port-related routines */
526 int tavor_port_query(tavor_state_t
*state
, uint_t port
,
527 ibt_hca_portinfo_t
*pi
);
528 int tavor_port_modify(tavor_state_t
*state
, uint8_t port
,
529 ibt_port_modify_flags_t flags
, uint8_t init_type
);
531 /* Tavor statistics (kstat) routines */
532 int tavor_kstat_init(tavor_state_t
*state
);
533 void tavor_kstat_fini(tavor_state_t
*state
);
535 /* Miscellaneous routines */
536 int tavor_set_addr_path(tavor_state_t
*state
, ibt_adds_vect_t
*av
,
537 tavor_hw_addr_path_t
*path
, uint_t type
, tavor_qphdl_t qp
);
538 void tavor_get_addr_path(tavor_state_t
*state
, tavor_hw_addr_path_t
*path
,
539 ibt_adds_vect_t
*av
, uint_t type
, tavor_qphdl_t qp
);
540 int tavor_portnum_is_valid(tavor_state_t
*state
, uint_t portnum
);
541 int tavor_pkeyindex_is_valid(tavor_state_t
*state
, uint_t pkeyindx
);
542 int tavor_queue_alloc(tavor_state_t
*state
, tavor_qalloc_info_t
*qa_info
,
544 void tavor_queue_free(tavor_state_t
*state
, tavor_qalloc_info_t
*qa_info
);
545 void tavor_dma_attr_init(ddi_dma_attr_t
*dma_attr
);
551 #endif /* _SYS_IB_ADAPTERS_TAVOR_MISC_H */