1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 #ifndef _SYS_IB_ADAPTERS_HERMON_CMD_H 27 #define _SYS_IB_ADAPTERS_HERMON_CMD_H 28 29 /* 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. 37 */ 38 39 #include <sys/types.h> 40 #include <sys/conf.h> 41 #include <sys/ddi.h> 42 #include <sys/sunddi.h> 43 44 #include <sys/ib/mgt/sm_attr.h> 45 46 #ifdef __cplusplus 47 extern "C" { 48 #endif 49 50 51 /* 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) 55 */ 56 #define HERMON_CMD_POLL_DELAY 1 57 #define HERMON_CMD_POLL_MAX 3000000 58 59 /* 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). 68 */ 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 74 75 /* 76 * These are the defines for the Hermon command type (opcodes). They are 77 * specified by the Hermon PRM 78 */ 79 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 98 99 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 108 109 /* EQ Commands */ 110 #define MAP_EQ 0x12 111 #define SW2HW_EQ 0x13 112 #define HW2SW_EQ 0x14 113 #define QUERY_EQ 0x15 114 115 /* CQ Commands */ 116 #define SW2HW_CQ 0x16 117 #define HW2SW_CQ 0x17 118 #define QUERY_CQ 0x18 119 #define MODIFY_CQ 0x2C 120 121 /* Modify CQ Command - opcode modifiers */ 122 #define RESIZE_CQ 0x0 123 #define MODIFY_MODERATION_CQ 0x1 124 #define MODIFY_EQN 0x2 125 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 */ 141 142 /* SPECIAL QPs Commands */ 143 #define CONF_SPECIAL_QP 0x23 144 #define MAD_IFC 0x24 145 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 158 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 165 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 171 172 #define SET_VLAN_FLTR 0x47 173 #define SET_MCAST_FLTR 0x48 174 175 #define CONFIG_FC 0x4A 176 #define QUERY_FC 0x4B 177 #define HEART_BEAT_RQ 0x4C 178 179 #define SENSE_PORT 0x4D 180 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 190 191 /* 192 * Commands mentioned but not defined in PRM v35 193 * REL_ICM_AUX 194 * INIT_VM 195 */ 196 197 /* 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. 205 */ 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 227 228 /* 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 232 */ 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 237 238 #define HERMON_CMD_SPEC_QP_OPMOD(smi, gsi) \ 239 ((smi & 0x01) | ((gsi & 0x01) << 1)) 240 241 /* 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. 245 */ 246 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 */ 269 270 271 272 /* 273 * The Hermon RTS2SQD command can take the following flag as part of its 274 * input modifier to request the Send Queue Drained event 275 */ 276 #define HERMON_CMD_REQ_SQD_EVENT 0x80000000 277 278 /* 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 283 */ 284 #define HERMON_CMD_DIRECT_TO_RESET (1 << 1) 285 286 /* 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. 290 */ 291 #define HERMON_CMD_DO_OUTMBOX (0) 292 #define HERMON_CMD_NO_OUTMBOX (1 << 0) 293 294 295 /* 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. 299 */ 300 301 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 305 306 /* 307 * The following defines are used by the MAD_IFC command and the helper 308 * routines that get PortInfo, NodeInfo, GUIDInfo, and PKeyTable entries. 309 * 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. 312 * 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. 315 */ 316 #define HERMON_CMD_MKEY_CHECK 0 317 #define HERMON_CMD_MKEY_DONTCHECK 1 318 #define HERMON_CMD_BKEY_DONTCHECK 2 319 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 326 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 332 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 339 340 #define HERMON_IS_EXT_WIDTH_SUPPORTED 0x0000020000000000 341 #define HERMON_IS_EXT_WIDTH_SUPPORTED_NOIETF 0x0000040000000000 342 343 344 /* 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 348 */ 349 #define HERMON_CMD_WRITEMTT_RSVD_SZ 0x10 350 #define HERMON_CMD_SETPORT_SZ 0x8 351 #define HERMON_CMD_MGIDHASH_SZ 0x10 352 353 /* 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 357 */ 358 #define HERMON_CMD_RSRC_HW2SW 0 359 #define HERMON_CMD_RSRC_SW2HW 1 360 361 /* 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. 364 * 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 373 */ 374 375 376 #ifdef _LITTLE_ENDIAN 377 #define HERMON_GETPORTINFO_SWAP(portinfo) \ 378 { \ 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); \ 394 } 395 #else 396 #define HERMON_GETPORTINFO_SWAP(portinfo) 397 #endif 398 399 #ifdef _LITTLE_ENDIAN 400 #define HERMON_GETNODEINFO_SWAP(nodeinfo) \ 401 { \ 402 uint32_t tmp; \ 403 \ 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])); \ 421 } 422 #else 423 #define HERMON_GETNODEINFO_SWAP(nodeinfo) \ 424 { \ 425 uint32_t tmp; \ 426 \ 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]); \ 443 } 444 #endif 445 446 #ifdef _LITTLE_ENDIAN 447 #define HERMON_GETGUIDINFO_SWAP(guidinfo) \ 448 { \ 449 int i; \ 450 \ 451 for (i = 0; i < 8; i++) { \ 452 (guidinfo)->GUIDBlocks[i] = \ 453 ddi_swap64((guidinfo)->GUIDBlocks[i]); \ 454 } \ 455 } 456 #else 457 #define HERMON_GETGUIDINFO_SWAP(guidinfo) 458 #endif 459 460 #ifdef _LITTLE_ENDIAN 461 #define HERMON_GETPKEYTABLE_SWAP(pkeytable) \ 462 { \ 463 int i; \ 464 \ 465 for (i = 0; i < 32; i++) { \ 466 (pkeytable)->P_KeyTableBlocks[i] = \ 467 ddi_swap16((pkeytable)->P_KeyTableBlocks[i]); \ 468 } \ 469 } 470 #else 471 #define HERMON_GETPKEYTABLE_SWAP(pkeytable) 472 #endif 473 474 /* 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. 478 */ 479 #define HERMON_CMD_MODIFY_MPT_RESIZESRQ 3 480 #define HERMON_CMD_MODIFY_MPT_SWAPFULL 5 481 482 /* 483 * Hermon MOD_STAT_CFG Opcode Modifier 484 */ 485 #define HERMON_MOD_STAT_CFG_PTR 0x0 486 #define HERMON_MOD_STAT_CFG_INLINE 0x1 487 #define HERMON_MOD_STAT_CFG_DEFAULTS 0xF 488 489 490 /* 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. 497 * 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. 502 */ 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; 512 513 /* 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. 521 */ 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)) 548 549 /* 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(). 560 * 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" 565 */ 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) 574 575 576 /* 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. 580 * 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. 586 * 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. 592 */ 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)) 605 606 /* 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. 616 */ 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)) 641 642 /* 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. 653 * 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. 658 */ 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 669 670 671 /* 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. 676 */ 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); 693 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); 707 708 /* 709 * INIT_HCA and CLOSE_HCA - used for initialization and teardown of Hermon 710 * device configuration 711 */ 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); 715 716 /* 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 721 */ 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); 728 729 /* 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. 734 */ 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); 737 738 /* 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 744 */ 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); 747 748 /* 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 752 */ 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); 755 756 /* 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). 760 */ 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); 779 /* 780 * WRITE_MTT - used for write MTT entries to the Hermon MTT table 781 */ 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); 784 785 /* 786 * SYNC_TPT - used to sync Hermon TPT caches 787 */ 788 int hermon_sync_tpt_cmd_post(hermon_state_t *state, uint_t sleepflag); 789 790 /* 791 * MAP_EQ - used for map classes of events to Hermon event queues (EQ) 792 */ 793 int hermon_map_eq_cmd_post(hermon_state_t *state, uint_t map, 794 uint_t eqcindx, uint64_t eqmapmask, uint_t sleepflag); 795 796 /* 797 * RESIZE_CQ - used for resize completion queue (CQ) 798 * opmod 0 is resize cq. opmod 1 is modify interrupt moderation. 799 */ 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); 804 805 /* 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. 808 */ 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); 811 812 /* 813 * Get FEXCH HEART BEAT 814 */ 815 int hermon_get_heart_beat_rq_cmd_post(hermon_state_t *state, uint_t qpindx, 816 uint64_t *outparm); 817 818 /* 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 824 */ 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); 831 832 /* 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. 836 */ 837 int hermon_mod_stat_cfg_cmd_post(hermon_state_t *state); 838 839 /* 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 843 */ 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); 846 847 /* 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 851 */ 852 int hermon_resize_srq_cmd_post(hermon_state_t *state, hermon_hw_srqc_t *srq, 853 uint_t srqnum, uint_t sleepflag); 854 855 /* 856 * CMD_NOP - used to test the interrupt/Event Queue mechanism. 857 */ 858 int hermon_nop_post(hermon_state_t *state, uint_t interval, uint_t sleep); 859 int hermon_setdebug_post(hermon_state_t *state); 860 861 /* 862 * READ_MTT - used to read an mtt entry at address. 863 */ 864 int hermon_read_mtt_cmd_post(hermon_state_t *state, uint64_t mtt_addr, 865 hermon_hw_mtt_t *mtt); 866 867 /* 868 * SENSE_PORT - used to send protocol running on a port 869 */ 870 int hermon_sense_port_post(hermon_state_t *state, uint_t portnum, 871 uint32_t *protocol); 872 873 /* 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 * 878 */ 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); 881 882 /* 883 * CONFIG_INT_MOD - used to configure INTERRUPT moderation 884 */ 885 int hermon_config_int_mod(hermon_state_t *state, uint_t min_delay, 886 uint_t vector); 887 888 /* 889 * HW_HEALTH_CHECK - tests state of the HCA 890 * if command fails, *health is invalid/undefined 891 */ 892 int hermon_hw_health_check(hermon_state_t *state, int *health); 893 894 #ifdef __cplusplus 895 } 896 #endif 897 898 #endif /* _SYS_IB_ADAPTERS_HERMON_CMD_H */ 899