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