docs/how-to-build.md: use proper markup for directory names
[unleashed/tickless.git] / include / sys / ib / adapters / hermon / hermon_cmd.h
blob50a041d3d34c8ef2b012ccc5027dbb484036e638
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
26 #ifndef _SYS_IB_ADAPTERS_HERMON_CMD_H
27 #define _SYS_IB_ADAPTERS_HERMON_CMD_H
30 * hermon_cmd.h
31 * Contains all of the prototypes, #defines, and structures necessary
32 * for the Hermon Firmware Command routines.
33 * Specifically it contains the command types, command statuses and flags,
34 * structures used for managing Hermon mailboxes and outstanding commands,
35 * and prototypes for most of the functions consumed by other parts of
36 * the Hermon driver.
39 #include <sys/types.h>
40 #include <sys/conf.h>
41 #include <sys/ddi.h>
42 #include <sys/sunddi.h>
44 #include <sys/ib/mgt/sm_attr.h>
46 #ifdef __cplusplus
47 extern "C" {
48 #endif
52 * Defines used hermon_write_hcr() to determine the duration and number of
53 * times (at maximum) to poll while waiting for a Hermon firmware command to
54 * release the HCR resource (i.e. waiting for the command to complete)
56 #define HERMON_CMD_POLL_DELAY 1
57 #define HERMON_CMD_POLL_MAX 3000000
60 * The following defines specify the default number of mailboxes (log 2) of
61 * each type and their size and alignment restrictions. By default the number
62 * of both "In" and "Out" mailboxes is set to 1024 (with each mailbox being
63 * 4KB in size), but both the number and sizes of each are controllable
64 * through the "hermon_log_num_inmbox", "hermon_log_num_outmbox",
65 * "hermon_log_inmbox_size" and "hermon_log_outmbox_size" configuration
66 * variables. Also, we have a define that is used to allocate interrupt
67 * mailboxes (1 in, 1 out).
69 #define HERMON_NUM_MAILBOXES_SHIFT 0xA
70 #define HERMON_NUM_INTR_MAILBOXES_SHIFT 0
71 #define HERMON_MBOX_SIZE_SHIFT 0xC
72 #define HERMON_MBOX_SIZE (1 << HERMON_MBOX_SIZE_SHIFT)
73 #define HERMON_MBOX_ALIGN HERMON_MBOX_SIZE
76 * These are the defines for the Hermon command type (opcodes). They are
77 * specified by the Hermon PRM
80 /* Init Commands */
81 #define QUERY_DEV_LIM 0x3
82 #define QUERY_DEV_CAP 0x3
83 #define QUERY_FW 0x4
84 #define QUERY_ADAPTER 0x6
85 #define INIT_HCA 0x7
86 #define CLOSE_HCA 0x8
87 #define INIT_IB 0x9
88 #define INIT_PORT 0x9
89 #define CLOSE_IB 0xA
90 #define CLOSE_PORT 0xA
91 #define QUERY_HCA 0xB
92 #define SET_IB 0xC
93 #define SET_PORT 0xC
94 /* added late in tavor for SRQ support */
95 #define MOD_STAT_CFG 0x34
96 /* added late in Hermon (PRM 0.35) */
97 #define QUERY_PORT 0x43
100 /* TPT Commands */
101 #define SW2HW_MPT 0xD
102 #define QUERY_MPT 0xE
103 #define HW2SW_MPT 0xF
104 #define READ_MTT 0x10
105 #define WRITE_MTT 0x11
106 #define SYNC_TPT 0x2F
107 #define MODIFY_MPT 0x39
109 /* EQ Commands */
110 #define MAP_EQ 0x12
111 #define SW2HW_EQ 0x13
112 #define HW2SW_EQ 0x14
113 #define QUERY_EQ 0x15
115 /* CQ Commands */
116 #define SW2HW_CQ 0x16
117 #define HW2SW_CQ 0x17
118 #define QUERY_CQ 0x18
119 #define MODIFY_CQ 0x2C
121 /* Modify CQ Command - opcode modifiers */
122 #define RESIZE_CQ 0x0
123 #define MODIFY_MODERATION_CQ 0x1
124 #define MODIFY_EQN 0x2
126 /* QP Commands */
127 #define RST2INIT_QP 0x19
128 #define INIT2INIT_QP 0x2D
129 #define INIT2RTR_QP 0x1A
130 #define RTR2RTS_QP 0x1B
131 #define RTS2RTS_QP 0x1C
132 #define SQERR2RTS_QP 0x1D
133 #define TOERR_QP 0x1E
134 #define RTS2SQD_QP 0x1F
135 #define SQD2SQD_QP 0x38
136 #define SQD2RTS_QP 0x20
137 #define TORST_QP 0x21
138 #define QUERY_QP 0x22
139 #define SUSPEND_QP 0x32 /* new w/ hermon driver */
140 #define UNSUSPEND_QP 0x33 /* new w/ hermon driver */
142 /* SPECIAL QPs Commands */
143 #define CONF_SPECIAL_QP 0x23
144 #define MAD_IFC 0x24
146 /* added late in tavor for SRQ support */
147 /* SRQ Commands */
148 #define SW2HW_SRQ 0x35
149 #define HW2SW_SRQ 0x36
150 #define QUERY_SRQ 0x37
151 /* new in hermon, replaces part of modify MPT */
152 #define RESIZE_SRQ 0X44
153 /* new in hermon, set limit water mark */
154 #define ARM_RQ 0X40
155 /* new in hermon (PRM 0.36) configure interrupt moderation */
156 #define CONFIG_INT_MOD 0X45
157 #define HW_HEALTH_CHECK 0X50
159 /* Multicast Group Commands */
160 #define READ_MGM 0x25
161 #define READ_MCG 0x25
162 #define WRITE_MGM 0x26
163 #define WRITE_MCG 0x26
164 #define MGID_HASH 0x27
166 /* Debug/Diagnostic Commands */
167 #define QUERY_DEBUG_MSG 0x2A
168 #define SET_DEBUG_MSG 0x2B
169 #define DIAG_RPRT 0x30
170 #define CMD_NOP 0x31
172 #define SET_VLAN_FLTR 0x47
173 #define SET_MCAST_FLTR 0x48
175 #define CONFIG_FC 0x4A
176 #define QUERY_FC 0x4B
177 #define HEART_BEAT_RQ 0x4C
179 #define SENSE_PORT 0x4D
181 /* ICM and related commands - w/out LAM commands from Arbel */
182 #define RUN_FW 0xFF6
183 #define UNMAP_ICM 0xFF9
184 #define MAP_ICM 0xFFA
185 #define UNMAP_ICM_AUX 0xFFB
186 #define MAP_ICM_AUX 0xFFC
187 #define SET_ICM_SIZE 0xFFD
188 #define UNMAP_FA 0xFFE
189 #define MAP_FA 0xFFF
192 * Commands mentioned but not defined in PRM v35
193 * REL_ICM_AUX
194 * INIT_VM
198 * These are the defines for the Hermon command completion statuses. They are
199 * also specified (in part) by the Hermon PRM. However,
200 * the HERMON_CMD_INSUFF_RSRC, HERMON_CMD_TIMEOUT and HERMON_CMD_INVALID_STATUS
201 * codes were added for this driver specifically to indicate the conditions
202 * when insufficient resources are available for a command, when a command has
203 * timed out (failure in the Hermon firmware) or when some other invalid result
204 * was received.
206 #define HERMON_CMD_TIMEOUT_TOGGLE 0xFFFC /* -4 */
207 #define HERMON_CMD_INSUFF_RSRC 0xFFFD /* -3 */
208 #define HERMON_CMD_TIMEOUT_GOBIT 0xFFFE /* -2 */
209 #define HERMON_CMD_INVALID_STATUS 0xFFFF /* -1 */
210 #define HERMON_CMD_SUCCESS 0x00
211 #define HERMON_CMD_INTERNAL_ERR 0x01
212 #define HERMON_CMD_BAD_OP 0x02
213 #define HERMON_CMD_BAD_PARAM 0x03
214 #define HERMON_CMD_BAD_SYS_STATE 0x04
215 #define HERMON_CMD_BAD_RESOURCE 0x05
216 #define HERMON_CMD_RESOURCE_BUSY 0x06
217 #define HERMON_CMD_EXCEED_LIM 0x08
218 #define HERMON_CMD_BAD_RES_STATE 0x09
219 #define HERMON_CMD_BAD_INDEX 0x0A
220 #define HERMON_CMD_BAD_NVMEM 0x0B
221 #define HERMON_CMD_ICM_ERROR 0x0C
222 #define HERMON_CMD_BAD_QP_STATE 0x10
223 #define HERMON_CMD_BAD_SEG_PARAM 0x20
224 #define HERMON_CMD_REG_BOUND 0x21
225 #define HERMON_CMD_BAD_PKT 0x30
226 #define HERMON_CMD_BAD_SIZE 0x40
229 * These defines are used in the "special QP" allocation to indicate the type
230 * of special QP (SMI, GSI, or one of the raw types). These values are
231 * specified by the Hermon PRM
233 #define HERMON_CMD_QP_SMI 0
234 #define HERMON_CMD_QP_GSI 1
235 #define HERMON_CMD_QP_RAW_IPV6 2
236 #define HERMON_CMD_QP_RAW_ETH 3
238 #define HERMON_CMD_SPEC_QP_OPMOD(smi, gsi) \
239 ((smi & 0x01) | ((gsi & 0x01) << 1))
242 * For certain Hermon QP state transition commands some optional flags are
243 * allowed. These "opmask" flags are defined by the Hermon PRM
244 * as a bitmask.
247 #define HERMON_CMD_OP_ALT_PATH (1 << 0)
248 #define HERMON_CMD_OP_RRE (1 << 1)
249 #define HERMON_CMD_OP_RAE (1 << 2)
250 #define HERMON_CMD_OP_RWE (1 << 3)
251 #define HERMON_CMD_OP_PKEYINDX (1 << 4) /* primary path */
252 #define HERMON_CMD_OP_QKEY (1 << 5)
253 #define HERMON_CMD_OP_MINRNRNAK (1 << 6)
254 #define HERMON_CMD_OP_PRIM_PATH (1 << 7)
255 #define HERMON_CMD_OP_SRA_SET (1 << 8)
256 #define HERMON_CMD_OP_RRA_SET (1 << 9)
257 #define HERMON_CMD_OP_PM_STATE (1 << 10) /* migration */
258 /* HERMON_CMD_OP_PRIM_PORT is obsolete, instead use HERMON_CMD_OP_SCHEDQUEUE */
259 #define HERMON_CMD_OP_PRIM_PORT (1 << 11)
260 #define HERMON_CMD_OP_RETRYCNT (1 << 12) /* Global */
261 #define HERMON_CMD_OP_ALT_RNRRETRY (1 << 13)
262 #define HERMON_CMD_OP_ACKTIMEOUT (1 << 14) /* primary path */
263 #define HERMON_CMD_OP_PRIM_RNRRETRY (1 << 15) /* reserved in HERMON */
264 #define HERMON_CMD_OP_SCHEDQUEUE (1 << 16)
265 #define HERMON_CMD_OP_RSSCONTEXT (1 << 17)
266 #define HERMON_CMD_OP_SRQN (1 << 18) /* for rss balancing */
267 #define HERMON_CMD_OP_CQN_RCV (1 << 19) /* for rss balancing */
268 /* Bits 20 - 31 RESERVED - per PRM 0.35c */
273 * The Hermon RTS2SQD command can take the following flag as part of its
274 * input modifier to request the Send Queue Drained event
276 #define HERMON_CMD_REQ_SQD_EVENT 0x80000000
279 * The Hermon TORST command can take the following flag (as part of a bitmask)
280 * in its opcode modifier to request that the transition to reset should
281 * not go through the Error state (and, hence, should not generate "flushed-
282 * in-error" completions
284 #define HERMON_CMD_DIRECT_TO_RESET (1 << 1)
287 * Some Hermon commands write an OUT mailbox entry, depending on the value of
288 * the 'opmod' parameter. These defines provide the correct opmod value to
289 * write depending on whether to write an entry or not.
291 #define HERMON_CMD_DO_OUTMBOX (0)
292 #define HERMON_CMD_NO_OUTMBOX (1 << 0)
296 * The Hermon MAP_EQ command can take the following flags (and use the
297 * HERMON_CMD_UNMAP_EQ_MASK input modifier) to indicate whether the given
298 * event queue should mapped to or unmapped from the given event type.
302 #define HERMON_CMD_MAP_EQ_EVT_MAP 0
303 #define HERMON_CMD_MAP_EQ_EVT_UNMAP 1
304 #define HERMON_CMD_UNMAP_EQ_MASK 0x80000000
307 * The following defines are used by the MAD_IFC command and the helper
308 * routines that get PortInfo, NodeInfo, GUIDInfo, and PKeyTable entries.
310 * The first indicates whether of not MKey checking should be enforced.
311 * This is passed in the opcode modifier field for MAD_IFC commands.
313 * The next set are used to define certain hardcoded management datagram (MAD)
314 * sizes, offsets, and header formats for each of the helper operations.
316 #define HERMON_CMD_MKEY_CHECK 0
317 #define HERMON_CMD_MKEY_DONTCHECK 1
318 #define HERMON_CMD_BKEY_DONTCHECK 2
320 #define HERMON_CMD_MAD_IFC_SIZE 0x100
321 #define HERMON_CMD_MADDATA_OFFSET 0x40
322 #define HERMON_CMD_MADHDR0 0x01010101
323 #define HERMON_CMD_MADHDR1 0x00000000
324 #define HERMON_CMD_MADHDR2 0x00000000
325 #define HERMON_CMD_MADHDR3 0x00000000
327 #define HERMON_CMD_PORTINFO 0x00150000
328 #define HERMON_CMD_NODEINFO 0x00110000
329 #define HERMON_CMD_NODEDESC 0x00100000
330 #define HERMON_CMD_GUIDINFO 0x00140000
331 #define HERMON_CMD_PKEYTBLE 0x00160000
333 #define HERMON_CMD_PERF_GET 0x01040101
334 #define HERMON_CMD_PERF_SET 0x01040102
335 #define HERMON_CMD_CLASSPORTINFO 0x00010000
336 #define HERMON_CMD_PERFCNTRS 0x00120000
337 #define HERMON_CMD_EXTPERFCNTRS 0x001D0000
338 #define HERMON_CMD_PERFATTR 0x00000000
340 #define HERMON_IS_EXT_WIDTH_SUPPORTED 0x0000020000000000
341 #define HERMON_IS_EXT_WIDTH_SUPPORTED_NOIETF 0x0000040000000000
345 * The next few defines are used to indicate the size of the "reserved" area
346 * in the WRITE_MTT command, and the respective sizes of the SET_PORT and
347 * MGID_HASH commands
349 #define HERMON_CMD_WRITEMTT_RSVD_SZ 0x10
350 #define HERMON_CMD_SETPORT_SZ 0x8
351 #define HERMON_CMD_MGIDHASH_SZ 0x10
354 * This last define is used by hermon_cmn_ownership_cmd_post() to keep track
355 * of the direction (from hardware ownership to software, or vice versa) of
356 * the requested operation
358 #define HERMON_CMD_RSRC_HW2SW 0
359 #define HERMON_CMD_RSRC_SW2HW 1
362 * The following macros are used for handling any endianness related issues
363 * that might arise from the Hermon driver's internal use of MADs.
365 * HERMON_GETPORTINFO_SWAP - All the necessary swapping to handle the
366 * response to a GetPortInfo MAD
367 * HERMON_GETNODEINFO_SWAP - All the necessary swapping to handle the
368 * response to a GetNodeInfo MAD
369 * HERMON_GETGUIDINFO_SWAP - All the necessary swapping to handle the
370 * response to a GetGUIDInfo MAD
371 * HERMON_GETPKEYTABLE_SWAP - All the necessary swapping to handle the
372 * response to a GetPKeyTable MAD
376 #ifdef _LITTLE_ENDIAN
377 #define HERMON_GETPORTINFO_SWAP(portinfo) \
379 (portinfo)->M_Key = ddi_swap64((portinfo)->M_Key); \
380 (portinfo)->GidPrefix = ddi_swap64((portinfo)->GidPrefix); \
381 (portinfo)->LID = ddi_swap16((portinfo)->LID); \
382 (portinfo)->MasterSMLID = ddi_swap16((portinfo)->MasterSMLID); \
383 (portinfo)->CapabilityMask = \
384 ddi_swap32((portinfo)->CapabilityMask); \
385 (portinfo)->DiagCode = ddi_swap16((portinfo)->DiagCode); \
386 (portinfo)->M_KeyLeasePeriod = \
387 ddi_swap16((portinfo)->M_KeyLeasePeriod); \
388 (portinfo)->M_KeyViolations = \
389 ddi_swap16((portinfo)->M_KeyViolations); \
390 (portinfo)->P_KeyViolations = \
391 ddi_swap16((portinfo)->P_KeyViolations); \
392 (portinfo)->Q_KeyViolations = \
393 ddi_swap16((portinfo)->Q_KeyViolations); \
395 #else
396 #define HERMON_GETPORTINFO_SWAP(portinfo)
397 #endif
399 #ifdef _LITTLE_ENDIAN
400 #define HERMON_GETNODEINFO_SWAP(nodeinfo) \
402 uint32_t tmp; \
404 tmp = ddi_swap32(((uint32_t *)nodeinfo)[9]); \
405 (nodeinfo)->VendorID = tmp & 0xFFFFFF; \
406 (nodeinfo)->LocalPortNum = tmp >> 24; \
407 (nodeinfo)->Revision = \
408 ddi_swap32(((uint32_t *)nodeinfo)[8]); \
409 tmp = ddi_swap32(((uint32_t *)nodeinfo)[7]); \
410 (nodeinfo)->PartitionCap = tmp >> 16; \
411 (nodeinfo)->DeviceID = tmp & 0xFFFF; \
412 (nodeinfo)->PortGUID = ddi_swap64((((uint64_t) \
413 (((uint32_t *)nodeinfo)[6]) << 32) | \
414 ((uint32_t *)nodeinfo)[5])); \
415 (nodeinfo)->NodeGUID = ddi_swap64((((uint64_t) \
416 (((uint32_t *)nodeinfo)[4]) << 32) | \
417 ((uint32_t *)nodeinfo)[3])); \
418 (nodeinfo)->SystemImageGUID = ddi_swap64((((uint64_t) \
419 (((uint32_t *)nodeinfo)[2]) << 32) | \
420 ((uint32_t *)nodeinfo)[1])); \
422 #else
423 #define HERMON_GETNODEINFO_SWAP(nodeinfo) \
425 uint32_t tmp; \
427 tmp = ((uint32_t *)nodeinfo)[9]; \
428 (nodeinfo)->VendorID = tmp & 0xFFFFFF; \
429 (nodeinfo)->LocalPortNum = tmp >> 24; \
430 (nodeinfo)->Revision = ((uint32_t *)nodeinfo)[8]; \
431 tmp = ((uint32_t *)nodeinfo)[7]; \
432 (nodeinfo)->PartitionCap = tmp >> 16; \
433 (nodeinfo)->DeviceID = tmp & 0xFFFF; \
434 (nodeinfo)->PortGUID = (((uint64_t) \
435 (((uint32_t *)nodeinfo)[5]) << 32) | \
436 ((uint32_t *)nodeinfo)[6]); \
437 (nodeinfo)->NodeGUID = (((uint64_t) \
438 (((uint32_t *)nodeinfo)[3]) << 32) | \
439 ((uint32_t *)nodeinfo)[4]); \
440 (nodeinfo)->SystemImageGUID = (((uint64_t) \
441 (((uint32_t *)nodeinfo)[1]) << 32) | \
442 ((uint32_t *)nodeinfo)[2]); \
444 #endif
446 #ifdef _LITTLE_ENDIAN
447 #define HERMON_GETGUIDINFO_SWAP(guidinfo) \
449 int i; \
451 for (i = 0; i < 8; i++) { \
452 (guidinfo)->GUIDBlocks[i] = \
453 ddi_swap64((guidinfo)->GUIDBlocks[i]); \
456 #else
457 #define HERMON_GETGUIDINFO_SWAP(guidinfo)
458 #endif
460 #ifdef _LITTLE_ENDIAN
461 #define HERMON_GETPKEYTABLE_SWAP(pkeytable) \
463 int i; \
465 for (i = 0; i < 32; i++) { \
466 (pkeytable)->P_KeyTableBlocks[i] = \
467 ddi_swap16((pkeytable)->P_KeyTableBlocks[i]); \
470 #else
471 #define HERMON_GETPKEYTABLE_SWAP(pkeytable)
472 #endif
475 * The Hermon MODIFY_MPT command can take the following opcode modifier
476 * options to specify whether to modify for ResizeSRQ() or to swap the
477 * full MPT entry.
479 #define HERMON_CMD_MODIFY_MPT_RESIZESRQ 3
480 #define HERMON_CMD_MODIFY_MPT_SWAPFULL 5
483 * Hermon MOD_STAT_CFG Opcode Modifier
485 #define HERMON_MOD_STAT_CFG_PTR 0x0
486 #define HERMON_MOD_STAT_CFG_INLINE 0x1
487 #define HERMON_MOD_STAT_CFG_DEFAULTS 0xF
491 * The hermon_mbox_t structure is used internally by the Hermon driver to track
492 * all the information necessary to manage mailboxes for the Hermon command
493 * interface. Specifically, by containing a pointer to the buffer, the
494 * PCI mapped address, the access handle, and a back pointer to the
495 * hermon_rsrc_t structure used to track this resource, it provides enough
496 * information allocate, use, and free any type of mailbox.
498 * The mb_indx, mb_next, and mb_prev fields are used only by the mailbox
499 * alloc/free routines (see hermon_impl_mbox_alloc/free() for more details)
500 * and are not read or modified by any mailbox consumers. They are used
501 * to implement a fast allocation mechanism.
503 typedef struct hermon_mbox_s {
504 void *mb_addr;
505 uint64_t mb_mapaddr;
506 ddi_acc_handle_t mb_acchdl;
507 hermon_rsrc_t *mb_rsrcptr;
508 uint_t mb_indx;
509 uint_t mb_next;
510 uint_t mb_prev;
511 } hermon_mbox_t;
514 * The hermon_mboxlist_t structure is used to track all the information
515 * relevant to the pools of Hermon mailboxes. Specifically, it has a pointer
516 * to an array of hermon_mbox_t structures, a lock and cv used for blocking
517 * on alloc when mailboxes are not available, and a head, tail, and entries
518 * free counter to keep track of which (if any) mailboxes are currently free.
519 * This is used (along with the mb_indx, mb_next, and mb_prev fields in the
520 * hermon_mbox_t) to implement the fast allocation mechanism.
522 typedef struct hermon_mboxlist_s {
523 kmutex_t mbl_lock;
524 kcondvar_t mbl_cv;
525 hermon_mbox_t *mbl_mbox;
526 uint_t mbl_list_sz;
527 uint_t mbl_num_alloc;
528 uint_t mbl_head_indx;
529 uint_t mbl_tail_indx;
530 uint_t mbl_entries_free;
531 uint_t mbl_waiters;
532 uint_t mbl_pollers;
533 uint_t mbl_signal;
534 } hermon_mboxlist_t;
535 _NOTE(MUTEX_PROTECTS_DATA(hermon_mboxlist_t::mbl_lock,
536 hermon_mboxlist_t::mbl_mbox
537 hermon_mboxlist_t::mbl_list_sz
538 hermon_mboxlist_t::mbl_num_alloc
539 hermon_mboxlist_t::mbl_cv
540 hermon_mboxlist_t::mbl_head_indx
541 hermon_mboxlist_t::mbl_tail_indx
542 hermon_mboxlist_t::mbl_entries_free
543 hermon_mboxlist_t::mbl_waiters
544 hermon_mboxlist_t::mbl_pollers
545 hermon_mboxlist_t::mbl_signal
546 hermon_mbox_t::mb_next
547 hermon_mbox_t::mb_prev))
550 * The hermon_mbox_info_t structure is used by mailbox allocators to specify
551 * the type of mailbox(es) being requested. On a call to hermon_mbox_alloc()
552 * the mbi_alloc_flags may be set to HERMON_ALLOC_INMBOX, HERMON_ALLOC_OUTMBOX,
553 * or both. If it is able to allocate the request type(s) of mailboxes,
554 * hermon_mbox_alloc() will fill in the "mbi_in" and/or "mbi_out" pointers
555 * to point to valid hermon_mbox_t structures from the appropriate
556 * hermon_mboxlist_t (see above).
557 * This same structure is also passed to hermon_mbox_free(). It is the
558 * responsibility of the caller to hermon_mbox_alloc() to return this exact
559 * structure (unmodified) to hermon_mbox_free().
561 * Note: If both "In" and "Out" mailboxes are requested, it is assured that
562 * no deadlock can result (from holding one mailbox while attempting to get
563 * the other). This is assured by the fact that the "In" mailbox will always
564 * be allocated first before attempting to allocate the "Out"
566 typedef struct hermon_mbox_info_s {
567 uint_t mbi_alloc_flags;
568 uint_t mbi_sleep_context;
569 hermon_mbox_t *mbi_in;
570 hermon_mbox_t *mbi_out;
571 } hermon_mbox_info_t;
572 #define HERMON_ALLOC_INMBOX (1 << 0)
573 #define HERMON_ALLOC_OUTMBOX (1 << 1)
577 * The hermon_cmd_t structure is used internally by the Hermon driver to track
578 * all the information necessary to manage outstanding firmware commands on
579 * the Hermon command interface.
581 * Each hermon_cmd_t structure contains a cv and lock which are used by the
582 * posting thread to block for completion (with cmd_status being overloaded
583 * to indicate the condition variable). The cmd_outparam field is used to
584 * return additional status from those Hermon commands that specifically
585 * require it.
587 * The cmd_indx, cmd_next, and cmd_prev fields are used by the outstanding
588 * command alloc/free routines (see hermon_outstanding_cmd_alloc/free() for
589 * more details). They are used (in much the same way as the mb_indx,
590 * mb_next, and mb_prev fields in hermon_mbox_t above) to implement a fast
591 * allocation mechanism.
593 typedef struct hermon_cmd_s {
594 kmutex_t cmd_comp_lock;
595 kcondvar_t cmd_comp_cv;
596 uint64_t cmd_outparm;
597 uint_t cmd_status;
598 uint_t cmd_indx;
599 uint_t cmd_next;
600 uint_t cmd_prev;
601 } hermon_cmd_t;
602 _NOTE(MUTEX_PROTECTS_DATA(hermon_cmd_t::cmd_comp_lock,
603 hermon_cmd_t::cmd_comp_cv
604 hermon_cmd_t::cmd_status))
607 * The hermon_cmdlist_t structure is used in almost exactly the same way as
608 * the hermon_mboxlist_t above, but instead to track all the information
609 * relevant to the pool of outstanding Hermon commands. Specifically, it has
610 * a pointer to an array of hermon_cmd_t structures, a lock and cv used for
611 * blocking on alloc when outstanding command slots are not available, and a
612 * head, tail, and entries free counter to keep track of which (if any)
613 * command slots are currently free. This is used (along with the cmd_indx,
614 * cmd_next, and cmd_prev fields in the hermon_cmd_t) to implement the fast
615 * allocation mechanism.
617 typedef struct hermon_cmdlist_s {
618 kmutex_t cml_lock;
619 kcondvar_t cml_cv;
620 hermon_cmd_t *cml_cmd;
621 uint_t cml_list_sz;
622 uint_t cml_num_alloc;
623 uint_t cml_head_indx;
624 uint_t cml_tail_indx;
625 uint_t cml_entries_free;
626 uint_t cml_waiters;
627 } hermon_cmdlist_t;
628 _NOTE(MUTEX_PROTECTS_DATA(hermon_cmdlist_t::cml_lock,
629 hermon_cmdlist_t::cml_cv
630 hermon_cmdlist_t::cml_cmd
631 hermon_cmdlist_t::cml_list_sz
632 hermon_cmdlist_t::cml_num_alloc
633 hermon_cmdlist_t::cml_head_indx
634 hermon_cmdlist_t::cml_tail_indx
635 hermon_cmdlist_t::cml_entries_free
636 hermon_cmdlist_t::cml_waiters
637 hermon_cmd_t::cmd_next
638 hermon_cmd_t::cmd_prev))
639 _NOTE(LOCK_ORDER(hermon_cmdlist_t::cml_lock
640 hermon_cmd_t::cmd_comp_lock))
643 * The hermon_cmd_post_t structure is used by all the Hermon Firmware Command
644 * routines to post to Hermon firmware. The fields almost exactly mimic
645 * the fields in the Hermon HCR registers. The notable exception is the
646 * addition of the "cp_flags" field (which can be set to HERMON_CMD_SPIN or
647 * HERMON_CMD_NOSPIN). This flag really controls the value of the "e" bit
648 * in the HCR (i.e. the bit to indicate whether command should complete
649 * "in place" - in the HCR - or whether they should have their completions
650 * written to the command completion event queue. HERMON_CMD_SPIN means
651 * to allow commands to complete "in place" and to poll the "go" bit in
652 * the HCR to determine completion.
654 * We use HERMON_SLEEP and HERMON_NOSLEEP for our HERMON_CMD_ #defines. This is
655 * to maintain consistency with the rest of the SLEEP flags. Additionally,
656 * because HERMON_SLEEPFLAG_FOR_CONTEXT() in hermon_rsrc.h returns HERMON_SLEEP
657 * or NOSLEEP we must be compatible with this macro.
659 typedef struct hermon_cmd_post_s {
660 uint64_t cp_inparm;
661 uint64_t cp_outparm;
662 uint32_t cp_inmod;
663 uint16_t cp_opcode;
664 uint16_t cp_opmod;
665 uint32_t cp_flags;
666 } hermon_cmd_post_t;
667 #define HERMON_CMD_SLEEP_NOSPIN HERMON_SLEEP
668 #define HERMON_CMD_NOSLEEP_SPIN HERMON_NOSLEEP
672 * The following are the Hermon Firmware Command routines that accessible
673 * externally (i.e. throughout the rest of the Hermon driver software).
674 * These include the all the alloc/free routines, some initialization
675 * and cleanup routines, and the various specific Hermon firmware commands.
677 int hermon_cmd_post(hermon_state_t *state, hermon_cmd_post_t *cmdpost);
678 int hermon_mbox_alloc(hermon_state_t *state, hermon_mbox_info_t *mbox_info,
679 uint_t mbox_wait);
680 void hermon_mbox_free(hermon_state_t *state, hermon_mbox_info_t *mbox_info);
681 int hermon_cmd_complete_handler(hermon_state_t *state, hermon_eqhdl_t eq,
682 hermon_hw_eqe_t *eqe);
683 int hermon_inmbox_list_init(hermon_state_t *state);
684 int hermon_intr_inmbox_list_init(hermon_state_t *state);
685 int hermon_outmbox_list_init(hermon_state_t *state);
686 int hermon_intr_outmbox_list_init(hermon_state_t *state);
687 void hermon_inmbox_list_fini(hermon_state_t *state);
688 void hermon_intr_inmbox_list_fini(hermon_state_t *state);
689 void hermon_outmbox_list_fini(hermon_state_t *state);
690 void hermon_intr_outmbox_list_fini(hermon_state_t *state);
691 int hermon_outstanding_cmdlist_init(hermon_state_t *state);
692 void hermon_outstanding_cmdlist_fini(hermon_state_t *state);
694 /* Added for MemFree */
695 int hermon_map_cmd_post(hermon_state_t *state, hermon_dma_info_t *dinfo,
696 uint16_t opcode, ddi_dma_cookie_t cookie, uint_t ccount);
697 int hermon_map_fa_cmd_post(hermon_state_t *state);
698 int hermon_run_fw_cmd_post(hermon_state_t *state);
699 int hermon_set_icm_size_cmd_post(hermon_state_t *state);
700 int hermon_map_icm_aux_cmd_post(hermon_state_t *state);
701 int hermon_map_icm_cmd_post(hermon_state_t *state);
702 int hermon_disable_lam_cmd_post(hermon_state_t *state);
703 int hermon_unmap_icm_cmd_post(hermon_state_t *state,
704 hermon_dma_info_t *dma_info);
705 int hermon_unmap_icm_aux_cmd_post(hermon_state_t *state);
706 int hermon_unmap_fa_cmd_post(hermon_state_t *state);
709 * INIT_HCA and CLOSE_HCA - used for initialization and teardown of Hermon
710 * device configuration
712 int hermon_init_hca_cmd_post(hermon_state_t *state,
713 hermon_hw_initqueryhca_t *inithca, uint_t sleepflag);
714 int hermon_close_hca_cmd_post(hermon_state_t *state, uint_t sleepflag);
717 * INIT_PORT, CLOSE_PORT, and SET_PORT - used for bring Hermon ports up and
718 * down, and to set properties of each port (e.g. PortInfo capability mask)
719 * NOTE: New names for the commands in Hermon (previously init_ close_ and
720 * set_ib
722 int hermon_set_port_cmd_post(hermon_state_t *state,
723 hermon_hw_set_port_t *initport, uint_t port, uint_t sleepflag);
724 int hermon_init_port_cmd_post(hermon_state_t *state, uint_t port,
725 uint_t sleepflag);
726 int hermon_close_port_cmd_post(hermon_state_t *state, uint_t port,
727 uint_t sleepflag);
730 * This common function is used to post the following Hermon QP state
731 * transition firmware commands:
732 * RTS2SQD, TOERR, TORST, RST2INIT, INIT2INIT, INIT2RTR, RTR2RTS, RTS2RTS,
733 * SQD2SQD, SQD2RTS, and SQERR2RTS.
735 int hermon_cmn_qp_cmd_post(hermon_state_t *state, uint_t opcode,
736 hermon_hw_qpc_t *qp, uint_t qpindx, uint32_t opmask, uint_t sleepflag);
739 * This common function is used to post the following Hermon query firmware
740 * commands:
741 * QUERY_DEV_LIM/CAP, QUERY_FW, QUERY_ADAPTER, QUERY_HCA, QUERY_MPT,
742 * QUERY_EQ, QUERY_CQ, and QUERY_QP.
743 * New with FCoIB, QUERY_FC
745 int hermon_cmn_query_cmd_post(hermon_state_t *state, uint_t opcode,
746 uint_t opmod, uint_t queryindx, void *query, uint_t size, uint_t sleepflag);
749 * This common function is used to post the following Hermon resource ownership
750 * firmware commands:
751 * HW2SW_MPT, HW2SW_EQ, HW2SW_CQ, SW2HW_MPT, SW2HW_EQ, and SW2HW_CQ
753 int hermon_cmn_ownership_cmd_post(hermon_state_t *state, uint_t opcode,
754 void *hwrsrc, uint_t size, uint_t hwrsrcindx, uint_t sleepflag);
757 * MAD_IFC and helper functions - used for posting IB MADs to Hermon firmware.
758 * The helper functions are for the MADs most frequently used by the Hermon
759 * driver (internally).
761 int hermon_mad_ifc_cmd_post(hermon_state_t *state, uint_t port,
762 uint_t sleepflag, uint32_t *mad, uint32_t *resp);
763 int hermon_getportinfo_cmd_post(hermon_state_t *state, uint_t port,
764 uint_t sleepflag, sm_portinfo_t *portinfo);
765 int hermon_getnodeinfo_cmd_post(hermon_state_t *state, uint_t sleepflag,
766 sm_nodeinfo_t *nodeinfo);
767 int hermon_getnodedesc_cmd_post(hermon_state_t *state, uint_t sleepflag,
768 sm_nodedesc_t *nodedesc);
769 int hermon_getguidinfo_cmd_post(hermon_state_t *state, uint_t port,
770 uint_t guidblock, uint_t sleepflag, sm_guidinfo_t *guidinfo);
771 int hermon_getpkeytable_cmd_post(hermon_state_t *state, uint_t port,
772 uint_t pkeyblock, uint_t sleepflag, sm_pkey_table_t *pkeytable);
773 int hermon_is_ext_port_counters_supported(hermon_state_t *state, uint_t port,
774 uint_t sleepflag, int *ext_width_supported);
775 int hermon_getextperfcntr_cmd_post(hermon_state_t *state, uint_t port,
776 uint_t sleepflag, hermon_hw_sm_extperfcntr_t *perfinfo);
777 int hermon_getperfcntr_cmd_post(hermon_state_t *state, uint_t port,
778 uint_t sleepflag, hermon_hw_sm_perfcntr_t *perfinfo, int reset);
780 * WRITE_MTT - used for write MTT entries to the Hermon MTT table
782 int hermon_write_mtt_cmd_post(hermon_state_t *state, hermon_rsrc_t *mtt,
783 uint64_t start_addr, uint_t nummtt, uint_t sleepflag);
786 * SYNC_TPT - used to sync Hermon TPT caches
788 int hermon_sync_tpt_cmd_post(hermon_state_t *state, uint_t sleepflag);
791 * MAP_EQ - used for map classes of events to Hermon event queues (EQ)
793 int hermon_map_eq_cmd_post(hermon_state_t *state, uint_t map,
794 uint_t eqcindx, uint64_t eqmapmask, uint_t sleepflag);
797 * RESIZE_CQ - used for resize completion queue (CQ)
798 * opmod 0 is resize cq. opmod 1 is modify interrupt moderation.
800 int hermon_resize_cq_cmd_post(hermon_state_t *state, hermon_hw_cqc_t *cqc,
801 uint_t cqcindx, uint32_t *prod_indx, uint_t sleepflag);
802 int hermon_modify_cq_cmd_post(hermon_state_t *state, hermon_hw_cqc_t *cqc,
803 uint_t cqcindx, uint_t opmod, uint_t sleepflag);
806 * CONF_SPECIAL_QP - used to configure a pair of queue pairs for use as
807 * special QP. Necessary to enable full QP0 and/or QP1 operation.
809 int hermon_conf_special_qp_cmd_post(hermon_state_t *state, uint_t qpindx,
810 uint_t qptype, uint_t sleepflag, uint_t opmod);
813 * Get FEXCH HEART BEAT
815 int hermon_get_heart_beat_rq_cmd_post(hermon_state_t *state, uint_t qpindx,
816 uint64_t *outparm);
819 * MGID_HASH, READ_MGM, and WRITE_MGM - used for manipulation of the
820 * hardware resource tables for multicast groups.
821 * NOTE: for intial implementation these functions retain their original
822 * names, though the proper hermon terminology is READ_MCG and
823 * WRITE_MCG - MGID_HASH retains its original name
825 int hermon_mgid_hash_cmd_post(hermon_state_t *state, uint64_t mgid_h,
826 uint64_t mgid_l, uint64_t *mgid_hash, uint_t sleepflag);
827 int hermon_read_mgm_cmd_post(hermon_state_t *state, hermon_hw_mcg_t *mcg,
828 uint_t mcgindx, uint_t sleepflag);
829 int hermon_write_mgm_cmd_post(hermon_state_t *state, hermon_hw_mcg_t *mcg,
830 uint_t mcgindx, uint_t sleepflag);
833 * MOD_STAT_CFG - used to configure (override) settings set in NVRAM before
834 * a call to QUERY_DEV_LIM. This is primarily used for SRQ settings in
835 * the firmware.
837 int hermon_mod_stat_cfg_cmd_post(hermon_state_t *state);
840 * MODIFY_MPT - used to change MPT attributes of a memory region. This
841 * was (Tavor/Arbel) primarily used for Resizing SRQs -- now may be used
842 * to modify MPT paramters
844 int hermon_modify_mpt_cmd_post(hermon_state_t *state, hermon_hw_dmpt_t *mpt,
845 uint_t mptindx, uint_t flags, uint_t sleepflag);
848 * RESIZE_SRQ is new in hermon, replacing opcodes in modify_mpt. It is used
849 * to resize the SRQ, by passing the new information in the same format as
850 * the original srqc, which the HCA will update appropriately
852 int hermon_resize_srq_cmd_post(hermon_state_t *state, hermon_hw_srqc_t *srq,
853 uint_t srqnum, uint_t sleepflag);
856 * CMD_NOP - used to test the interrupt/Event Queue mechanism.
858 int hermon_nop_post(hermon_state_t *state, uint_t interval, uint_t sleep);
859 int hermon_setdebug_post(hermon_state_t *state);
862 * READ_MTT - used to read an mtt entry at address.
864 int hermon_read_mtt_cmd_post(hermon_state_t *state, uint64_t mtt_addr,
865 hermon_hw_mtt_t *mtt);
868 * SENSE_PORT - used to send protocol running on a port
870 int hermon_sense_port_post(hermon_state_t *state, uint_t portnum,
871 uint32_t *protocol);
874 * CONFIG_FC - used to do either a basic config passing in
875 * *hermon_hw_config_fc_basic_s, or config the N_Port table.
876 * passing in pointer to an array of 32-bit id's
877 * Note that either one needs to be cast to void *
879 int hermon_config_fc_cmd_post(hermon_state_t *state, void *cfginfo, int enable,
880 int selector, int n_ports, int portnum, uint_t sleepflag);
883 * CONFIG_INT_MOD - used to configure INTERRUPT moderation
885 int hermon_config_int_mod(hermon_state_t *state, uint_t min_delay,
886 uint_t vector);
889 * HW_HEALTH_CHECK - tests state of the HCA
890 * if command fails, *health is invalid/undefined
892 int hermon_hw_health_check(hermon_state_t *state, int *health);
894 #ifdef __cplusplus
896 #endif
898 #endif /* _SYS_IB_ADAPTERS_HERMON_CMD_H */