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 9 * http://www.opensource.org/licenses/cddl1.txt. 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) 2004-2012 Emulex. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <emlxs.h> 28 29 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 30 EMLXS_MSG_DEF(EMLXS_MBOX_C); 31 32 33 emlxs_table_t emlxs_mb_status_table[] = { 34 {MBX_SUCCESS, "SUCCESS"}, 35 {MBX_FAILURE, "FAILURE"}, 36 {MBXERR_NUM_IOCBS, "NUM_IOCBS"}, 37 {MBXERR_IOCBS_EXCEEDED, "IOCBS_EXCEEDED"}, 38 {MBXERR_BAD_RING_NUMBER, "BAD_RING_NUMBER"}, 39 {MBXERR_MASK_ENTRIES_RANGE, "MASK_ENTRIES_RANGE"}, 40 {MBXERR_MASKS_EXCEEDED, "MASKS_EXCEEDED"}, 41 {MBXERR_BAD_PROFILE, "BAD_PROFILE"}, 42 {MBXERR_BAD_DEF_CLASS, "BAD_DEF_CLASS"}, 43 {MBXERR_BAD_MAX_RESPONDER, "BAD_MAX_RESPONDER"}, 44 {MBXERR_BAD_MAX_ORIGINATOR, "BAD_MAX_ORIGINATOR"}, 45 {MBXERR_RPI_REGISTERED, "RPI_REGISTERED"}, 46 {MBXERR_RPI_FULL, "RPI_FULL"}, 47 {MBXERR_NO_RESOURCES, "NO_RESOURCES"}, 48 {MBXERR_BAD_RCV_LENGTH, "BAD_RCV_LENGTH"}, 49 {MBXERR_DMA_ERROR, "DMA_ERROR"}, 50 {MBXERR_NOT_SUPPORTED, "NOT_SUPPORTED"}, 51 {MBXERR_UNSUPPORTED_FEATURE, "UNSUPPORTED_FEATURE"}, 52 {MBXERR_UNKNOWN_COMMAND, "UNKNOWN_COMMAND"}, 53 {MBXERR_BAD_IP_BIT, "BAD_IP_BIT"}, 54 {MBXERR_BAD_PCB_ALIGN, "BAD_PCB_ALIGN"}, 55 {MBXERR_BAD_HBQ_ID, "BAD_HBQ_ID"}, 56 {MBXERR_BAD_HBQ_STATE, "BAD_HBQ_STATE"}, 57 {MBXERR_BAD_HBQ_MASK_NUM, "BAD_HBQ_MASK_NUM"}, 58 {MBXERR_BAD_HBQ_MASK_SUBSET, "BAD_HBQ_MASK_SUBSET"}, 59 {MBXERR_HBQ_CREATE_FAIL, "HBQ_CREATE_FAIL"}, 60 {MBXERR_HBQ_EXISTING, "HBQ_EXISTING"}, 61 {MBXERR_HBQ_RSPRING_FULL, "HBQ_RSPRING_FULL"}, 62 {MBXERR_HBQ_DUP_MASK, "HBQ_DUP_MASK"}, 63 {MBXERR_HBQ_INVAL_GET_PTR, "HBQ_INVAL_GET_PTR"}, 64 {MBXERR_BAD_HBQ_SIZE, "BAD_HBQ_SIZE"}, 65 {MBXERR_BAD_HBQ_ORDER, "BAD_HBQ_ORDER"}, 66 {MBXERR_INVALID_ID, "INVALID_ID"}, 67 {MBXERR_INVALID_VFI, "INVALID_VFI"}, 68 {MBXERR_FLASH_WRITE_FAILED, "FLASH_WRITE_FAILED"}, 69 {MBXERR_INVALID_LINKSPEED, "INVALID_LINKSPEED"}, 70 {MBXERR_BAD_REDIRECT, "BAD_REDIRECT"}, 71 {MBXERR_RING_ALREADY_CONFIG, "RING_ALREADY_CONFIG"}, 72 {MBXERR_RING_INACTIVE, "RING_INACTIVE"}, 73 {MBXERR_RPI_INACTIVE, "RPI_INACTIVE"}, 74 {MBXERR_NO_ACTIVE_XRI, "NO_ACTIVE_XRI"}, 75 {MBXERR_XRI_NOT_ACTIVE, "XRI_NOT_ACTIVE"}, 76 {MBXERR_RPI_INUSE, "RPI_INUSE"}, 77 {MBXERR_NO_LINK_ATTENTION, "NO_LINK_ATTENTION"}, 78 {MBXERR_INVALID_SLI_MODE, "INVALID_SLI_MODE"}, 79 {MBXERR_INVALID_HOST_PTR, "INVALID_HOST_PTR"}, 80 {MBXERR_CANT_CFG_SLI_MODE, "CANT_CFG_SLI_MODE"}, 81 {MBXERR_BAD_OVERLAY, "BAD_OVERLAY"}, 82 {MBXERR_INVALID_FEAT_REQ, "INVALID_FEAT_REQ"}, 83 {MBXERR_CONFIG_CANT_COMPLETE, "CONFIG_CANT_COMPLETE"}, 84 {MBXERR_DID_ALREADY_REGISTERED, "DID_ALREADY_REGISTERED"}, 85 {MBXERR_DID_INCONSISTENT, "DID_INCONSISTENT"}, 86 {MBXERR_VPI_TOO_LARGE, "VPI_TOO_LARGE"}, 87 {MBXERR_STILL_ASSOCIATED, "STILL_ASSOCIATED"}, 88 {MBXERR_INVALID_VF_STATE, "INVALID_VF_STATE"}, 89 {MBXERR_VFI_ALREADY_REGISTERED, "VFI_ALREADY_REGISTERED"}, 90 {MBXERR_VFI_TOO_LARGE, "VFI_TOO_LARGE"}, 91 {MBXERR_LOAD_FW_FAILED, "LOAD_FW_FAILED"}, 92 {MBXERR_FIND_FW_FAILED, "FIND_FW_FAILED"}, 93 }; 94 95 emlxs_table_t emlxs_mb_cmd_table[] = { 96 {MBX_SHUTDOWN, "SHUTDOWN"}, 97 {MBX_LOAD_SM, "LOAD_SM"}, 98 {MBX_READ_NV, "READ_NV"}, 99 {MBX_WRITE_NV, "WRITE_NV"}, 100 {MBX_RUN_BIU_DIAG, "RUN_BIU_DIAG"}, 101 {MBX_INIT_LINK, "INIT_LINK"}, 102 {MBX_DOWN_LINK, "DOWN_LINK"}, 103 {MBX_CONFIG_LINK, "CONFIG_LINK"}, 104 {MBX_PART_SLIM, "PART_SLIM"}, 105 {MBX_CONFIG_RING, "CONFIG_RING"}, 106 {MBX_RESET_RING, "RESET_RING"}, 107 {MBX_READ_CONFIG, "READ_CONFIG"}, 108 {MBX_READ_RCONFIG, "READ_RCONFIG"}, 109 {MBX_READ_SPARM, "READ_SPARM"}, 110 {MBX_READ_STATUS, "READ_STATUS"}, 111 {MBX_READ_RPI, "READ_RPI"}, 112 {MBX_READ_XRI, "READ_XRI"}, 113 {MBX_READ_REV, "READ_REV"}, 114 {MBX_READ_LNK_STAT, "READ_LNK_STAT"}, 115 {MBX_REG_LOGIN, "REG_LOGIN"}, 116 {MBX_UNREG_LOGIN, "UNREG_RPI"}, 117 {MBX_READ_LA, "READ_LA"}, 118 {MBX_CLEAR_LA, "CLEAR_LA"}, 119 {MBX_DUMP_MEMORY, "DUMP_MEMORY"}, 120 {MBX_DUMP_CONTEXT, "DUMP_CONTEXT"}, 121 {MBX_RUN_DIAGS, "RUN_DIAGS"}, 122 {MBX_RESTART, "RESTART"}, 123 {MBX_UPDATE_CFG, "UPDATE_CFG"}, 124 {MBX_DOWN_LOAD, "DOWN_LOAD"}, 125 {MBX_DEL_LD_ENTRY, "DEL_LD_ENTRY"}, 126 {MBX_RUN_PROGRAM, "RUN_PROGRAM"}, 127 {MBX_SET_MASK, "SET_MASK"}, 128 {MBX_SET_VARIABLE, "SET_VARIABLE"}, 129 {MBX_UNREG_D_ID, "UNREG_D_ID"}, 130 {MBX_KILL_BOARD, "KILL_BOARD"}, 131 {MBX_CONFIG_FARP, "CONFIG_FARP"}, 132 {MBX_LOAD_AREA, "LOAD_AREA"}, 133 {MBX_RUN_BIU_DIAG64, "RUN_BIU_DIAG64"}, 134 {MBX_CONFIG_PORT, "CONFIG_PORT"}, 135 {MBX_READ_SPARM64, "READ_SPARM64"}, 136 {MBX_READ_RPI64, "READ_RPI64"}, 137 {MBX_CONFIG_MSI, "CONFIG_MSI"}, 138 {MBX_CONFIG_MSIX, "CONFIG_MSIX"}, 139 {MBX_REG_LOGIN64, "REG_RPI"}, 140 {MBX_READ_LA64, "READ_LA64"}, 141 {MBX_FLASH_WR_ULA, "FLASH_WR_ULA"}, 142 {MBX_SET_DEBUG, "SET_DEBUG"}, 143 {MBX_GET_DEBUG, "GET_DEBUG"}, 144 {MBX_LOAD_EXP_ROM, "LOAD_EXP_ROM"}, 145 {MBX_BEACON, "BEACON"}, 146 {MBX_CONFIG_HBQ, "CONFIG_HBQ"}, /* SLI3 */ 147 {MBX_REG_VPI, "REG_VPI"}, /* NPIV */ 148 {MBX_UNREG_VPI, "UNREG_VPI"}, /* NPIV */ 149 {MBX_ASYNC_EVENT, "ASYNC_EVENT"}, 150 {MBX_HEARTBEAT, "HEARTBEAT"}, 151 {MBX_READ_EVENT_LOG_STATUS, "READ_EVENT_LOG_STATUS"}, 152 {MBX_READ_EVENT_LOG, "READ_EVENT_LOG"}, 153 {MBX_WRITE_EVENT_LOG, "WRITE_EVENT_LOG"}, 154 {MBX_NV_LOG, "NV_LOG"}, 155 {MBX_PORT_CAPABILITIES, "PORT_CAPABILITIES"}, 156 {MBX_IOV_CONTROL, "IOV_CONTROL"}, 157 {MBX_IOV_MBX, "IOV_MBX"}, 158 {MBX_SLI_CONFIG, "SLI_CONFIG"}, 159 {MBX_REQUEST_FEATURES, "REQUEST_FEATURES"}, 160 {MBX_RESUME_RPI, "RESUME_RPI"}, 161 {MBX_REG_VFI, "REG_VFI"}, 162 {MBX_REG_FCFI, "REG_FCFI"}, 163 {MBX_UNREG_VFI, "UNREG_VFI"}, 164 {MBX_UNREG_FCFI, "UNREG_FCFI"}, 165 {MBX_INIT_VFI, "INIT_VFI"}, 166 {MBX_INIT_VPI, "INIT_VPI"}, 167 {MBX_WRITE_VPARMS, "WRITE_VPARMS"}, 168 {MBX_ACCESS_VDATA, "ACCESS_VDATA"} 169 }; /* emlxs_mb_cmd_table */ 170 171 172 emlxs_table_t emlxs_request_feature_table[] = { 173 {SLI4_FEATURE_INHIBIT_AUTO_ABTS, "IAA "}, /* Bit 0 */ 174 {SLI4_FEATURE_NPIV, "NPIV "}, /* Bit 1 */ 175 {SLI4_FEATURE_DIF, "DIF "}, /* Bit 2 */ 176 {SLI4_FEATURE_VIRTUAL_FABRICS, "VF "}, /* Bit 3 */ 177 {SLI4_FEATURE_FCP_INITIATOR, "FCPI "}, /* Bit 4 */ 178 {SLI4_FEATURE_FCP_TARGET, "FCPT "}, /* Bit 5 */ 179 {SLI4_FEATURE_FCP_COMBO, "FCPC "}, /* Bit 6 */ 180 {SLI4_FEATURE_RSVD1, "RSVD1 "}, /* Bit 7 */ 181 {SLI4_FEATURE_RQD, "RQD "}, /* Bit 8 */ 182 {SLI4_FEATURE_INHIBIT_AUTO_ABTS_R, "IAAR "}, /* Bit 9 */ 183 {SLI4_FEATURE_HIGH_LOGIN_MODE, "HLM "}, /* Bit 10 */ 184 {SLI4_FEATURE_PERF_HINT, "PERFH "} /* Bit 11 */ 185 }; /* emlxs_request_feature_table */ 186 187 188 extern char * 189 emlxs_mb_xlate_status(uint32_t status) 190 { 191 static char buffer[32]; 192 uint32_t i; 193 uint32_t count; 194 195 count = sizeof (emlxs_mb_status_table) / sizeof (emlxs_table_t); 196 for (i = 0; i < count; i++) { 197 if (status == emlxs_mb_status_table[i].code) { 198 return (emlxs_mb_status_table[i].string); 199 } 200 } 201 202 (void) snprintf(buffer, sizeof (buffer), "status=%x", status); 203 return (buffer); 204 205 } /* emlxs_mb_xlate_status() */ 206 207 208 /* SLI4 */ 209 /*ARGSUSED*/ 210 extern void 211 emlxs_mb_resetport(emlxs_hba_t *hba, MAILBOXQ *mbq) 212 { 213 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 214 215 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 216 mbq->nonembed = NULL; 217 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 218 mbq->port = (void *)&PPORT; 219 220 /* 221 * Signifies an embedded command 222 */ 223 mb4->un.varSLIConfig.be.embedded = 1; 224 225 mb4->mbxCommand = MBX_SLI_CONFIG; 226 mb4->mbxOwner = OWN_HOST; 227 mb4->un.varSLIConfig.be.payload_length = IOCTL_HEADER_SZ; 228 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 229 IOCTL_SUBSYSTEM_COMMON; 230 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = COMMON_OPCODE_RESET; 231 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 232 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 0; 233 234 return; 235 236 } /* emlxs_mb_resetport() */ 237 238 239 /* SLI4 */ 240 /*ARGSUSED*/ 241 extern void 242 emlxs_mb_request_features(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t mask) 243 { 244 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 245 246 hba->flag &= ~FC_NPIV_ENABLED; 247 hba->sli.sli4.flag &= ~(EMLXS_SLI4_PHON | EMLXS_SLI4_PHWQ); 248 249 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 250 mbq->nonembed = NULL; 251 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 252 mbq->port = (void *)&PPORT; 253 254 mb4->mbxCommand = MBX_REQUEST_FEATURES; 255 mb4->mbxOwner = OWN_HOST; 256 257 mb4->un.varReqFeatures.featuresRequested = mask; 258 return; 259 260 } /* emlxs_mb_request_features() */ 261 262 263 /* SLI4 */ 264 /*ARGSUSED*/ 265 extern void 266 emlxs_mb_noop(emlxs_hba_t *hba, MAILBOXQ *mbq) 267 { 268 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 269 IOCTL_COMMON_NOP *nop; 270 271 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 272 mbq->nonembed = NULL; 273 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 274 mbq->port = (void *)&PPORT; 275 276 /* 277 * Signifies an embedded command 278 */ 279 mb4->un.varSLIConfig.be.embedded = 1; 280 281 mb4->mbxCommand = MBX_SLI_CONFIG; 282 mb4->mbxOwner = OWN_HOST; 283 mb4->un.varSLIConfig.be.payload_length = sizeof (IOCTL_COMMON_NOP) + 284 IOCTL_HEADER_SZ; 285 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 286 IOCTL_SUBSYSTEM_COMMON; 287 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = COMMON_OPCODE_NOP; 288 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 289 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 290 sizeof (IOCTL_COMMON_NOP); 291 nop = (IOCTL_COMMON_NOP *)&mb4->un.varSLIConfig.payload; 292 nop->params.request.context = -1; 293 294 return; 295 296 } /* emlxs_mb_noop() */ 297 298 299 /* SLI4 */ 300 /*ARGSUSED*/ 301 extern int 302 emlxs_mbext_noop(emlxs_hba_t *hba, MAILBOXQ *mbq) 303 { 304 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 305 IOCTL_COMMON_NOP *nop; 306 MATCHMAP *mp; 307 mbox_req_hdr_t *hdr_req; 308 309 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 310 311 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) { 312 return (1); 313 } 314 /* 315 * Save address for completion 316 * Signifies a non-embedded command 317 */ 318 mb4->un.varSLIConfig.be.embedded = 0; 319 mbq->nonembed = (void *)mp; 320 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 321 mbq->port = (void *)&PPORT; 322 323 mb4->mbxCommand = MBX_SLI_CONFIG; 324 mb4->mbxOwner = OWN_HOST; 325 326 hdr_req = (mbox_req_hdr_t *)mp->virt; 327 hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON; 328 hdr_req->opcode = COMMON_OPCODE_NOP; 329 hdr_req->timeout = 0; 330 hdr_req->req_length = sizeof (IOCTL_COMMON_NOP); 331 nop = (IOCTL_COMMON_NOP *)(hdr_req + 1); 332 nop->params.request.context = -1; 333 334 return (0); 335 336 } /* emlxs_mbext_noop() */ 337 338 339 /* SLI4 */ 340 /*ARGSUSED*/ 341 extern void 342 emlxs_mb_eq_create(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t num) 343 { 344 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 345 IOCTL_COMMON_EQ_CREATE *qp; 346 uint64_t addr; 347 348 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 349 mbq->nonembed = NULL; 350 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 351 mbq->port = (void *)&PPORT; 352 353 /* 354 * Signifies an embedded command 355 */ 356 mb4->un.varSLIConfig.be.embedded = 1; 357 358 mb4->mbxCommand = MBX_SLI_CONFIG; 359 mb4->mbxOwner = OWN_HOST; 360 mb4->un.varSLIConfig.be.payload_length = 361 sizeof (IOCTL_COMMON_EQ_CREATE) + IOCTL_HEADER_SZ; 362 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 363 IOCTL_SUBSYSTEM_COMMON; 364 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = COMMON_OPCODE_EQ_CREATE; 365 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 366 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 367 sizeof (IOCTL_COMMON_EQ_CREATE); 368 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 0; 369 370 qp = (IOCTL_COMMON_EQ_CREATE *)&mb4->un.varSLIConfig.payload; 371 372 /* 1024 * 4 bytes = 4K */ 373 qp->params.request.EQContext.Count = EQ_ELEMENT_COUNT_1024; 374 qp->params.request.EQContext.Valid = 1; 375 qp->params.request.EQContext.DelayMult = EQ_DELAY_MULT; 376 377 addr = hba->sli.sli4.eq[num].addr.phys; 378 qp->params.request.NumPages = 1; 379 qp->params.request.Pages[0].addrLow = PADDR_LO(addr); 380 qp->params.request.Pages[0].addrHigh = PADDR_HI(addr); 381 382 return; 383 384 } /* emlxs_mb_eq_create() */ 385 386 387 /* SLI4 */ 388 /*ARGSUSED*/ 389 extern void 390 emlxs_mb_cq_create(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t num) 391 { 392 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 393 IOCTL_COMMON_CQ_CREATE *qp; 394 IOCTL_COMMON_CQ_CREATE_V2 *qp2; 395 uint64_t addr; 396 uint32_t i; 397 398 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 399 mbq->nonembed = NULL; 400 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 401 mbq->port = (void *)&PPORT; 402 403 /* 404 * Signifies an embedded command 405 */ 406 mb4->un.varSLIConfig.be.embedded = 1; 407 408 mb4->mbxCommand = MBX_SLI_CONFIG; 409 mb4->mbxOwner = OWN_HOST; 410 411 switch (hba->sli.sli4.param.CQV) { 412 case 0: 413 mb4->un.varSLIConfig.be.payload_length = 414 sizeof (IOCTL_COMMON_CQ_CREATE) + IOCTL_HEADER_SZ; 415 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 416 IOCTL_SUBSYSTEM_COMMON; 417 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = 418 COMMON_OPCODE_CQ_CREATE; 419 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 420 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 421 sizeof (IOCTL_COMMON_CQ_CREATE); 422 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 0; 423 424 qp = (IOCTL_COMMON_CQ_CREATE *) 425 &mb4->un.varSLIConfig.payload; 426 427 /* 256 * 16 bytes = 4K */ 428 qp->params.request.CQContext.Count = CQ_ELEMENT_COUNT_256; 429 qp->params.request.CQContext.EQId = 430 (uint8_t)hba->sli.sli4.cq[num].eqid; 431 qp->params.request.CQContext.Valid = 1; 432 qp->params.request.CQContext.Eventable = 1; 433 qp->params.request.CQContext.NoDelay = 0; 434 qp->params.request.CQContext.CoalesceWM = 0; 435 436 addr = hba->sli.sli4.cq[num].addr.phys; 437 qp->params.request.NumPages = 1; 438 qp->params.request.Pages[0].addrLow = PADDR_LO(addr); 439 qp->params.request.Pages[0].addrHigh = PADDR_HI(addr); 440 441 break; 442 443 case 2: 444 default: 445 mb4->un.varSLIConfig.be.payload_length = 446 sizeof (IOCTL_COMMON_CQ_CREATE_V2) + IOCTL_HEADER_SZ; 447 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 448 IOCTL_SUBSYSTEM_COMMON; 449 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = 450 COMMON_OPCODE_CQ_CREATE; 451 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 452 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 453 sizeof (IOCTL_COMMON_CQ_CREATE_V2); 454 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 2; 455 456 qp2 = (IOCTL_COMMON_CQ_CREATE_V2 *) 457 &mb4->un.varSLIConfig.payload; 458 459 qp2->params.request.CQContext.CqeCnt = CQ_ELEMENT_COUNT_1024; 460 qp2->params.request.CQContext.CqeSize = CQE_SIZE_16_BYTES; 461 qp2->params.request.CQContext.EQId = hba->sli.sli4.cq[num].eqid; 462 qp2->params.request.CQContext.Valid = 1; 463 qp2->params.request.CQContext.AutoValid = 0; 464 qp2->params.request.CQContext.Eventable = 1; 465 qp2->params.request.CQContext.NoDelay = 0; 466 qp2->params.request.CQContext.Count1 = 0; 467 qp2->params.request.CQContext.CoalesceWM = 0; 468 469 addr = hba->sli.sli4.cq[num].addr.phys; 470 qp2->params.request.PageSize = CQ_PAGE_SIZE_4K; 471 qp2->params.request.NumPages = EMLXS_NUM_CQ_PAGES_V2; 472 473 for (i = 0; i < EMLXS_NUM_CQ_PAGES_V2; i++) { 474 qp2->params.request.Pages[i].addrLow = PADDR_LO(addr); 475 qp2->params.request.Pages[i].addrHigh = PADDR_HI(addr); 476 addr += 4096; 477 } 478 479 break; 480 } 481 return; 482 483 } /* emlxs_mb_cq_create() */ 484 485 486 /* SLI4 */ 487 /*ARGSUSED*/ 488 extern void 489 emlxs_mb_get_port_name(emlxs_hba_t *hba, MAILBOXQ *mbq) 490 { 491 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 492 493 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 494 mbq->nonembed = NULL; 495 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 496 mbq->port = (void *)&PPORT; 497 498 mb4->un.varSLIConfig.be.embedded = 1; 499 mb4->mbxCommand = MBX_SLI_CONFIG; 500 mb4->mbxOwner = OWN_HOST; 501 502 mb4->un.varSLIConfig.be.payload_length = IOCTL_HEADER_SZ; 503 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 504 IOCTL_SUBSYSTEM_COMMON; 505 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = 506 COMMON_OPCODE_GET_PORT_NAME; 507 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 508 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 0; 509 510 if (hba->model_info.chip & EMLXS_BE_CHIPS) { 511 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 0; /* V0 */ 512 } else { 513 IOCTL_COMMON_GET_PORT_NAME_V1 *pn; 514 515 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 1; /* V1 */ 516 517 pn = (IOCTL_COMMON_GET_PORT_NAME_V1 *) 518 &mb4->un.varSLIConfig.payload; 519 pn->params.request.pt = PORT_TYPE_FC; 520 } 521 522 return; 523 524 } /* emlxs_mb_get_port_name() */ 525 526 527 /* SLI4 */ 528 /*ARGSUSED*/ 529 extern void 530 emlxs_mb_get_sli4_params(emlxs_hba_t *hba, MAILBOXQ *mbq) 531 { 532 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 533 534 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 535 mbq->nonembed = NULL; 536 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 537 mbq->port = (void *)&PPORT; 538 539 mb4->un.varSLIConfig.be.embedded = 1; 540 mb4->mbxCommand = MBX_SLI_CONFIG; 541 mb4->mbxOwner = OWN_HOST; 542 543 mb4->un.varSLIConfig.be.payload_length = IOCTL_HEADER_SZ; 544 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 545 IOCTL_SUBSYSTEM_COMMON; 546 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = 547 COMMON_OPCODE_GET_SLI4_PARAMS; 548 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 549 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 0; 550 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 0; /* V0 */ 551 552 return; 553 554 } /* emlxs_mb_get_sli4_params() */ 555 556 557 /* SLI4 */ 558 /*ARGSUSED*/ 559 extern void 560 emlxs_mb_get_extents_info(emlxs_hba_t *hba, MAILBOXQ *mbq, uint16_t type) 561 { 562 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 563 IOCTL_COMMON_EXTENTS *ep; 564 565 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 566 mbq->nonembed = NULL; 567 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 568 mbq->port = (void *)&PPORT; 569 570 mb4->un.varSLIConfig.be.embedded = 1; 571 mb4->mbxCommand = MBX_SLI_CONFIG; 572 mb4->mbxOwner = OWN_HOST; 573 574 mb4->un.varSLIConfig.be.payload_length = IOCTL_HEADER_SZ; 575 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.subsystem = 576 IOCTL_SUBSYSTEM_COMMON; 577 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.opcode = 578 COMMON_OPCODE_GET_EXTENTS_INFO; 579 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.timeout = 0; 580 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.req_length = 581 sizeof (IOCTL_COMMON_EXTENTS); 582 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.vf_number = 0; 583 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.vh_number = 0; 584 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.pf_number = 0; 585 586 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.version = 0; /* V0 */ 587 588 ep = (IOCTL_COMMON_EXTENTS *)&mb4->un.varSLIConfig.payload; 589 ep->params.request.RscType = type; 590 591 return; 592 593 } /* emlxs_mb_get_extents_info() */ 594 595 596 /* SLI4 */ 597 /*ARGSUSED*/ 598 extern void 599 emlxs_mb_get_extents(emlxs_hba_t *hba, MAILBOXQ *mbq, uint16_t type) 600 { 601 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 602 IOCTL_COMMON_EXTENTS *ep; 603 604 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 605 mbq->nonembed = NULL; 606 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 607 mbq->port = (void *)&PPORT; 608 609 mb4->un.varSLIConfig.be.embedded = 1; 610 mb4->mbxCommand = MBX_SLI_CONFIG; 611 mb4->mbxOwner = OWN_HOST; 612 613 mb4->un.varSLIConfig.be.payload_length = IOCTL_HEADER_SZ; 614 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.subsystem = 615 IOCTL_SUBSYSTEM_COMMON; 616 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.opcode = 617 COMMON_OPCODE_GET_EXTENTS; 618 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.timeout = 0; 619 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.req_length = 620 sizeof (IOCTL_COMMON_EXTENTS); 621 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.vf_number = 0; 622 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.vh_number = 0; 623 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.pf_number = 0; 624 625 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.version = 0; /* V0 */ 626 627 ep = (IOCTL_COMMON_EXTENTS *)&mb4->un.varSLIConfig.payload; 628 ep->params.request.RscType = type; 629 630 return; 631 632 } /* emlxs_mb_get_extents() */ 633 634 635 /* SLI4 */ 636 /*ARGSUSED*/ 637 extern void 638 emlxs_mb_alloc_extents(emlxs_hba_t *hba, MAILBOXQ *mbq, uint16_t type, 639 uint16_t count) 640 { 641 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 642 IOCTL_COMMON_EXTENTS *ep; 643 644 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 645 mbq->nonembed = NULL; 646 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 647 mbq->port = (void *)&PPORT; 648 649 mb4->un.varSLIConfig.be.embedded = 1; 650 mb4->mbxCommand = MBX_SLI_CONFIG; 651 mb4->mbxOwner = OWN_HOST; 652 653 mb4->un.varSLIConfig.be.payload_length = IOCTL_HEADER_SZ; 654 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.subsystem = 655 IOCTL_SUBSYSTEM_COMMON; 656 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.opcode = 657 COMMON_OPCODE_ALLOC_EXTENTS; 658 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.timeout = 0; 659 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.req_length = 660 sizeof (IOCTL_COMMON_EXTENTS); 661 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.vf_number = 0; 662 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.vh_number = 0; 663 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.pf_number = 0; 664 665 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.version = 0; /* V0 */ 666 667 ep = (IOCTL_COMMON_EXTENTS *)&mb4->un.varSLIConfig.payload; 668 ep->params.request.RscType = type; 669 670 count = min(count, MAX_EXTENTS); 671 ep->params.request.RscCnt = count; 672 673 return; 674 675 } /* emlxs_mb_alloc_extents() */ 676 677 678 /* SLI4 */ 679 /*ARGSUSED*/ 680 extern void 681 emlxs_mb_dealloc_extents(emlxs_hba_t *hba, MAILBOXQ *mbq, uint16_t type) 682 { 683 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 684 IOCTL_COMMON_EXTENTS *ep; 685 686 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 687 mbq->nonembed = NULL; 688 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 689 mbq->port = (void *)&PPORT; 690 691 mb4->un.varSLIConfig.be.embedded = 1; 692 mb4->mbxCommand = MBX_SLI_CONFIG; 693 mb4->mbxOwner = OWN_HOST; 694 695 mb4->un.varSLIConfig.be.payload_length = IOCTL_HEADER_SZ; 696 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.subsystem = 697 IOCTL_SUBSYSTEM_COMMON; 698 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.opcode = 699 COMMON_OPCODE_DEALLOC_EXTENTS; 700 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.timeout = 0; 701 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.req_length = 702 sizeof (IOCTL_COMMON_EXTENTS); 703 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.vf_number = 0; 704 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.vh_number = 0; 705 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.pf_number = 0; 706 707 mb4->un.varSLIConfig.be.un_hdr.hdr_req2.version = 0; /* V0 */ 708 709 ep = (IOCTL_COMMON_EXTENTS *)&mb4->un.varSLIConfig.payload; 710 ep->params.request.RscType = type; 711 712 return; 713 714 } /* emlxs_mb_dealloc_extents() */ 715 716 717 /* SLI4 */ 718 /*ARGSUSED*/ 719 extern void 720 emlxs_mb_wq_create(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t num) 721 { 722 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 723 IOCTL_FCOE_WQ_CREATE *qp; 724 IOCTL_FCOE_WQ_CREATE_V1 *qp1; 725 uint64_t addr; 726 int i; 727 728 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 729 mbq->nonembed = NULL; 730 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 731 mbq->port = (void *)&PPORT; 732 733 /* 734 * Signifies an embedded command 735 */ 736 mb4->un.varSLIConfig.be.embedded = 1; 737 738 mb4->mbxCommand = MBX_SLI_CONFIG; 739 mb4->mbxOwner = OWN_HOST; 740 741 switch (hba->sli.sli4.param.WQV) { 742 case 0: 743 mb4->un.varSLIConfig.be.payload_length = 744 sizeof (IOCTL_FCOE_WQ_CREATE) + IOCTL_HEADER_SZ; 745 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 746 IOCTL_SUBSYSTEM_FCOE; 747 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = 748 FCOE_OPCODE_WQ_CREATE; 749 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 750 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 751 sizeof (IOCTL_FCOE_WQ_CREATE); 752 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 0; 753 754 addr = hba->sli.sli4.wq[num].addr.phys; 755 qp = (IOCTL_FCOE_WQ_CREATE *)&mb4->un.varSLIConfig.payload; 756 757 qp->params.request.CQId = hba->sli.sli4.wq[num].cqid; 758 759 qp->params.request.NumPages = EMLXS_NUM_WQ_PAGES; 760 for (i = 0; i < EMLXS_NUM_WQ_PAGES; i++) { 761 qp->params.request.Pages[i].addrLow = PADDR_LO(addr); 762 qp->params.request.Pages[i].addrHigh = PADDR_HI(addr); 763 addr += 4096; 764 } 765 766 break; 767 768 case 1: 769 default: 770 mb4->un.varSLIConfig.be.payload_length = 771 sizeof (IOCTL_FCOE_WQ_CREATE_V1) + IOCTL_HEADER_SZ; 772 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 773 IOCTL_SUBSYSTEM_FCOE; 774 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = 775 FCOE_OPCODE_WQ_CREATE; 776 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 777 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 778 sizeof (IOCTL_FCOE_WQ_CREATE_V1); 779 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 1; 780 781 addr = hba->sli.sli4.wq[num].addr.phys; 782 qp1 = (IOCTL_FCOE_WQ_CREATE_V1 *)&mb4->un.varSLIConfig.payload; 783 784 qp1->params.request.CQId = hba->sli.sli4.wq[num].cqid; 785 qp1->params.request.NumPages = EMLXS_NUM_WQ_PAGES; 786 787 qp1->params.request.WqeCnt = WQ_DEPTH; 788 qp1->params.request.WqeSize = WQE_SIZE_64_BYTES; 789 qp1->params.request.PageSize = WQ_PAGE_SIZE_4K; 790 791 for (i = 0; i < EMLXS_NUM_WQ_PAGES; i++) { 792 qp1->params.request.Pages[i].addrLow = PADDR_LO(addr); 793 qp1->params.request.Pages[i].addrHigh = PADDR_HI(addr); 794 addr += 4096; 795 } 796 797 break; 798 } 799 800 return; 801 802 } /* emlxs_mb_wq_create() */ 803 804 805 /* SLI4 */ 806 /*ARGSUSED*/ 807 extern void 808 emlxs_mb_rq_create(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t num) 809 { 810 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 811 IOCTL_FCOE_RQ_CREATE *qp; 812 IOCTL_FCOE_RQ_CREATE_V1 *qp1; 813 uint64_t addr; 814 815 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 816 mbq->nonembed = NULL; 817 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 818 mbq->port = (void *)&PPORT; 819 820 /* 821 * Signifies an embedded command 822 */ 823 mb4->un.varSLIConfig.be.embedded = 1; 824 825 mb4->mbxCommand = MBX_SLI_CONFIG; 826 mb4->mbxOwner = OWN_HOST; 827 828 switch (hba->sli.sli4.param.RQV) { 829 case 0: 830 mb4->un.varSLIConfig.be.payload_length = 831 sizeof (IOCTL_FCOE_RQ_CREATE) + IOCTL_HEADER_SZ; 832 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 833 IOCTL_SUBSYSTEM_FCOE; 834 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = 835 FCOE_OPCODE_RQ_CREATE; 836 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 837 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 838 sizeof (IOCTL_FCOE_RQ_CREATE); 839 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 0; 840 841 addr = hba->sli.sli4.rq[num].addr.phys; 842 843 qp = (IOCTL_FCOE_RQ_CREATE *)&mb4->un.varSLIConfig.payload; 844 845 qp->params.request.RQContext.RqeCnt = RQ_DEPTH_EXPONENT; 846 qp->params.request.RQContext.BufferSize = RQB_DATA_SIZE; 847 qp->params.request.RQContext.CQId = 848 hba->sli.sli4.rq[num].cqid; 849 850 qp->params.request.NumPages = 1; 851 qp->params.request.Pages[0].addrLow = PADDR_LO(addr); 852 qp->params.request.Pages[0].addrHigh = PADDR_HI(addr); 853 854 break; 855 856 case 1: 857 default: 858 mb4->un.varSLIConfig.be.payload_length = 859 sizeof (IOCTL_FCOE_RQ_CREATE_V1) + IOCTL_HEADER_SZ; 860 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 861 IOCTL_SUBSYSTEM_FCOE; 862 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = 863 FCOE_OPCODE_RQ_CREATE; 864 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 865 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 866 sizeof (IOCTL_FCOE_RQ_CREATE_V1); 867 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 1; 868 869 addr = hba->sli.sli4.rq[num].addr.phys; 870 871 qp1 = (IOCTL_FCOE_RQ_CREATE_V1 *)&mb4->un.varSLIConfig.payload; 872 873 qp1->params.request.RQContext.RqeCnt = RQ_DEPTH; 874 qp1->params.request.RQContext.RqeSize = RQE_SIZE_8_BYTES; 875 qp1->params.request.RQContext.PageSize = RQ_PAGE_SIZE_4K; 876 877 qp1->params.request.RQContext.BufferSize = RQB_DATA_SIZE; 878 qp1->params.request.RQContext.CQId = 879 hba->sli.sli4.rq[num].cqid; 880 881 qp1->params.request.NumPages = 1; 882 qp1->params.request.Pages[0].addrLow = PADDR_LO(addr); 883 qp1->params.request.Pages[0].addrHigh = PADDR_HI(addr); 884 885 break; 886 } 887 888 return; 889 890 } /* emlxs_mb_rq_create() */ 891 892 893 /* SLI4 */ 894 /*ARGSUSED*/ 895 extern void 896 emlxs_mb_mq_create(emlxs_hba_t *hba, MAILBOXQ *mbq) 897 { 898 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 899 IOCTL_COMMON_MQ_CREATE *qp; 900 uint64_t addr; 901 902 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 903 mbq->nonembed = NULL; 904 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 905 mbq->port = (void *)&PPORT; 906 907 /* 908 * Signifies an embedded command 909 */ 910 mb4->un.varSLIConfig.be.embedded = 1; 911 912 mb4->mbxCommand = MBX_SLI_CONFIG; 913 mb4->mbxOwner = OWN_HOST; 914 mb4->un.varSLIConfig.be.payload_length = 915 sizeof (IOCTL_COMMON_MQ_CREATE) + IOCTL_HEADER_SZ; 916 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 917 IOCTL_SUBSYSTEM_COMMON; 918 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = COMMON_OPCODE_MQ_CREATE; 919 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 920 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 921 sizeof (IOCTL_COMMON_MQ_CREATE); 922 923 addr = hba->sli.sli4.mq.addr.phys; 924 qp = (IOCTL_COMMON_MQ_CREATE *)&mb4->un.varSLIConfig.payload; 925 926 qp->params.request.MQContext.Size = MQ_ELEMENT_COUNT_16; 927 qp->params.request.MQContext.Valid = 1; 928 qp->params.request.MQContext.CQId = hba->sli.sli4.mq.cqid; 929 930 qp->params.request.NumPages = 1; 931 qp->params.request.Pages[0].addrLow = PADDR_LO(addr); 932 qp->params.request.Pages[0].addrHigh = PADDR_HI(addr); 933 934 return; 935 936 } /* emlxs_mb_mq_create() */ 937 938 939 /* SLI4 */ 940 /*ARGSUSED*/ 941 extern void 942 emlxs_mb_mq_create_ext(emlxs_hba_t *hba, MAILBOXQ *mbq) 943 { 944 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 945 IOCTL_COMMON_MQ_CREATE_EXT *qp; 946 IOCTL_COMMON_MQ_CREATE_EXT_V1 *qp1; 947 uint64_t addr; 948 949 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 950 mbq->nonembed = NULL; 951 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 952 mbq->port = (void *)&PPORT; 953 954 /* 955 * Signifies an embedded command 956 */ 957 mb4->un.varSLIConfig.be.embedded = 1; 958 959 mb4->mbxCommand = MBX_SLI_CONFIG; 960 mb4->mbxOwner = OWN_HOST; 961 962 switch (hba->sli.sli4.param.MQV) { 963 case 0: 964 mb4->un.varSLIConfig.be.payload_length = 965 sizeof (IOCTL_COMMON_MQ_CREATE_EXT) + IOCTL_HEADER_SZ; 966 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 967 IOCTL_SUBSYSTEM_COMMON; 968 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = 969 COMMON_OPCODE_MQ_CREATE_EXT; 970 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 971 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 972 sizeof (IOCTL_COMMON_MQ_CREATE_EXT); 973 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 0; 974 975 addr = hba->sli.sli4.mq.addr.phys; 976 qp = (IOCTL_COMMON_MQ_CREATE_EXT *) 977 &mb4->un.varSLIConfig.payload; 978 979 qp->params.request.num_pages = 1; 980 qp->params.request.async_event_bitmap = 981 ASYNC_LINK_EVENT | ASYNC_FCF_EVENT | ASYNC_GROUP5_EVENT; 982 qp->params.request.context.Size = MQ_ELEMENT_COUNT_16; 983 qp->params.request.context.Valid = 1; 984 qp->params.request.context.CQId = hba->sli.sli4.mq.cqid; 985 986 qp->params.request.pages[0].addrLow = PADDR_LO(addr); 987 qp->params.request.pages[0].addrHigh = PADDR_HI(addr); 988 989 break; 990 991 case 1: 992 default: 993 mb4->un.varSLIConfig.be.payload_length = 994 sizeof (IOCTL_COMMON_MQ_CREATE) + IOCTL_HEADER_SZ; 995 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 996 IOCTL_SUBSYSTEM_COMMON; 997 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = 998 COMMON_OPCODE_MQ_CREATE_EXT; 999 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 1000 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 1001 sizeof (IOCTL_COMMON_MQ_CREATE_EXT_V1); 1002 mb4->un.varSLIConfig.be.un_hdr.hdr_req.version = 1; 1003 1004 addr = hba->sli.sli4.mq.addr.phys; 1005 qp1 = (IOCTL_COMMON_MQ_CREATE_EXT_V1 *) 1006 &mb4->un.varSLIConfig.payload; 1007 1008 qp1->params.request.num_pages = 1; 1009 qp1->params.request.async_event_bitmap = 1010 ASYNC_LINK_EVENT | ASYNC_FCF_EVENT | ASYNC_GROUP5_EVENT | 1011 ASYNC_FC_EVENT | ASYNC_PORT_EVENT; 1012 qp1->params.request.context.Size = MQ_ELEMENT_COUNT_16; 1013 qp1->params.request.context.Valid = 1; 1014 qp1->params.request.CQId = hba->sli.sli4.mq.cqid; 1015 1016 qp1->params.request.pages[0].addrLow = PADDR_LO(addr); 1017 qp1->params.request.pages[0].addrHigh = PADDR_HI(addr); 1018 1019 break; 1020 } 1021 1022 return; 1023 1024 } /* emlxs_mb_mq_create_ext() */ 1025 1026 1027 /*ARGSUSED*/ 1028 extern void 1029 emlxs_mb_async_event(emlxs_hba_t *hba, MAILBOXQ *mbq) 1030 { 1031 MAILBOX *mb = (MAILBOX *)mbq; 1032 1033 bzero((void *) mb, MAILBOX_CMD_BSIZE); 1034 1035 mb->mbxCommand = MBX_ASYNC_EVENT; 1036 mb->mbxOwner = OWN_HOST; 1037 mb->un.varWords[0] = hba->channel_els; 1038 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 1039 mbq->port = (void *)&PPORT; 1040 1041 return; 1042 1043 } /* emlxs_mb_async_event() */ 1044 1045 1046 /*ARGSUSED*/ 1047 extern void 1048 emlxs_mb_heartbeat(emlxs_hba_t *hba, MAILBOXQ *mbq) 1049 { 1050 MAILBOX *mb = (MAILBOX *)mbq; 1051 1052 bzero((void *) mb, MAILBOX_CMD_BSIZE); 1053 1054 mb->mbxCommand = MBX_HEARTBEAT; 1055 mb->mbxOwner = OWN_HOST; 1056 mbq->mbox_cmpl = NULL; /* no cmpl needed for hbeat */ 1057 mbq->port = (void *)&PPORT; 1058 1059 return; 1060 1061 } /* emlxs_mb_heartbeat() */ 1062 1063 1064 #ifdef MSI_SUPPORT 1065 1066 /*ARGSUSED*/ 1067 extern void 1068 emlxs_mb_config_msi(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t *intr_map, 1069 uint32_t intr_count) 1070 { 1071 MAILBOX *mb = (MAILBOX *)mbq; 1072 uint16_t i; 1073 uint32_t mask; 1074 1075 bzero((void *)mb, MAILBOX_CMD_BSIZE); 1076 1077 mb->mbxCommand = MBX_CONFIG_MSI; 1078 1079 /* Set the default message id to zero */ 1080 mb->un.varCfgMSI.defaultPresent = 1; 1081 mb->un.varCfgMSI.defaultMessageNumber = 0; 1082 1083 for (i = 1; i < intr_count; i++) { 1084 mask = intr_map[i]; 1085 1086 mb->un.varCfgMSI.attConditions |= mask; 1087 1088 #ifdef EMLXS_BIG_ENDIAN 1089 if (mask & HA_R0ATT) { 1090 mb->un.varCfgMSI.messageNumberByHA[3] = i; 1091 } 1092 if (mask & HA_R1ATT) { 1093 mb->un.varCfgMSI.messageNumberByHA[7] = i; 1094 } 1095 if (mask & HA_R2ATT) { 1096 mb->un.varCfgMSI.messageNumberByHA[11] = i; 1097 } 1098 if (mask & HA_R3ATT) { 1099 mb->un.varCfgMSI.messageNumberByHA[15] = i; 1100 } 1101 if (mask & HA_LATT) { 1102 mb->un.varCfgMSI.messageNumberByHA[29] = i; 1103 } 1104 if (mask & HA_MBATT) { 1105 mb->un.varCfgMSI.messageNumberByHA[30] = i; 1106 } 1107 if (mask & HA_ERATT) { 1108 mb->un.varCfgMSI.messageNumberByHA[31] = i; 1109 } 1110 #endif /* EMLXS_BIG_ENDIAN */ 1111 1112 #ifdef EMLXS_LITTLE_ENDIAN 1113 /* Accounts for half word swap of LE architecture */ 1114 if (mask & HA_R0ATT) { 1115 mb->un.varCfgMSI.messageNumberByHA[2] = i; 1116 } 1117 if (mask & HA_R1ATT) { 1118 mb->un.varCfgMSI.messageNumberByHA[6] = i; 1119 } 1120 if (mask & HA_R2ATT) { 1121 mb->un.varCfgMSI.messageNumberByHA[10] = i; 1122 } 1123 if (mask & HA_R3ATT) { 1124 mb->un.varCfgMSI.messageNumberByHA[14] = i; 1125 } 1126 if (mask & HA_LATT) { 1127 mb->un.varCfgMSI.messageNumberByHA[28] = i; 1128 } 1129 if (mask & HA_MBATT) { 1130 mb->un.varCfgMSI.messageNumberByHA[31] = i; 1131 } 1132 if (mask & HA_ERATT) { 1133 mb->un.varCfgMSI.messageNumberByHA[30] = i; 1134 } 1135 #endif /* EMLXS_LITTLE_ENDIAN */ 1136 } 1137 1138 mb->mbxOwner = OWN_HOST; 1139 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 1140 mbq->port = (void *)&PPORT; 1141 1142 return; 1143 1144 } /* emlxs_mb_config_msi() */ 1145 1146 1147 /*ARGSUSED*/ 1148 extern void 1149 emlxs_mb_config_msix(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t *intr_map, 1150 uint32_t intr_count) 1151 { 1152 MAILBOX *mb = (MAILBOX *)mbq; 1153 uint8_t i; 1154 uint32_t mask; 1155 1156 bzero((void *)mb, MAILBOX_CMD_BSIZE); 1157 1158 mb->mbxCommand = MBX_CONFIG_MSIX; 1159 1160 /* Set the default message id to zero */ 1161 mb->un.varCfgMSIX.defaultPresent = 1; 1162 mb->un.varCfgMSIX.defaultMessageNumber = 0; 1163 1164 for (i = 1; i < intr_count; i++) { 1165 mask = intr_map[i]; 1166 1167 mb->un.varCfgMSIX.attConditions1 |= mask; 1168 1169 #ifdef EMLXS_BIG_ENDIAN 1170 if (mask & HA_R0ATT) { 1171 mb->un.varCfgMSIX.messageNumberByHA[3] = i; 1172 } 1173 if (mask & HA_R1ATT) { 1174 mb->un.varCfgMSIX.messageNumberByHA[7] = i; 1175 } 1176 if (mask & HA_R2ATT) { 1177 mb->un.varCfgMSIX.messageNumberByHA[11] = i; 1178 } 1179 if (mask & HA_R3ATT) { 1180 mb->un.varCfgMSIX.messageNumberByHA[15] = i; 1181 } 1182 if (mask & HA_LATT) { 1183 mb->un.varCfgMSIX.messageNumberByHA[29] = i; 1184 } 1185 if (mask & HA_MBATT) { 1186 mb->un.varCfgMSIX.messageNumberByHA[30] = i; 1187 } 1188 if (mask & HA_ERATT) { 1189 mb->un.varCfgMSIX.messageNumberByHA[31] = i; 1190 } 1191 #endif /* EMLXS_BIG_ENDIAN */ 1192 1193 #ifdef EMLXS_LITTLE_ENDIAN 1194 /* Accounts for word swap of LE architecture */ 1195 if (mask & HA_R0ATT) { 1196 mb->un.varCfgMSIX.messageNumberByHA[0] = i; 1197 } 1198 if (mask & HA_R1ATT) { 1199 mb->un.varCfgMSIX.messageNumberByHA[4] = i; 1200 } 1201 if (mask & HA_R2ATT) { 1202 mb->un.varCfgMSIX.messageNumberByHA[8] = i; 1203 } 1204 if (mask & HA_R3ATT) { 1205 mb->un.varCfgMSIX.messageNumberByHA[12] = i; 1206 } 1207 if (mask & HA_LATT) { 1208 mb->un.varCfgMSIX.messageNumberByHA[30] = i; 1209 } 1210 if (mask & HA_MBATT) { 1211 mb->un.varCfgMSIX.messageNumberByHA[29] = i; 1212 } 1213 if (mask & HA_ERATT) { 1214 mb->un.varCfgMSIX.messageNumberByHA[28] = i; 1215 } 1216 #endif /* EMLXS_LITTLE_ENDIAN */ 1217 } 1218 1219 mb->mbxOwner = OWN_HOST; 1220 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 1221 mbq->port = (void *)&PPORT; 1222 1223 return; 1224 1225 } /* emlxs_mb_config_msix() */ 1226 1227 1228 #endif /* MSI_SUPPORT */ 1229 1230 1231 /*ARGSUSED*/ 1232 extern void 1233 emlxs_mb_reset_ring(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t ringno) 1234 { 1235 MAILBOX *mb = (MAILBOX *)mbq; 1236 1237 bzero((void *)mb, MAILBOX_CMD_BSIZE); 1238 1239 mb->mbxCommand = MBX_RESET_RING; 1240 mb->un.varRstRing.ring_no = ringno; 1241 mb->mbxOwner = OWN_HOST; 1242 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 1243 mbq->port = (void *)&PPORT; 1244 1245 return; 1246 1247 } /* emlxs_mb_reset_ring() */ 1248 1249 1250 /*ARGSUSED*/ 1251 extern void 1252 emlxs_mb_dump_vpd(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t offset) 1253 { 1254 1255 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 1256 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 1257 1258 /* Clear the local dump_region */ 1259 bzero(hba->sli.sli4.dump_region.virt, 1260 hba->sli.sli4.dump_region.size); 1261 1262 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 1263 1264 mb4->mbxCommand = MBX_DUMP_MEMORY; 1265 mb4->un.varDmp4.type = DMP_NV_PARAMS; 1266 mb4->un.varDmp4.entry_index = offset; 1267 mb4->un.varDmp4.region_id = DMP_VPD_REGION; 1268 1269 mb4->un.varDmp4.available_cnt = hba->sli.sli4.dump_region.size; 1270 mb4->un.varDmp4.addrHigh = 1271 PADDR_HI(hba->sli.sli4.dump_region.phys); 1272 mb4->un.varDmp4.addrLow = 1273 PADDR_LO(hba->sli.sli4.dump_region.phys); 1274 mb4->un.varDmp4.rsp_cnt = 0; 1275 1276 mb4->mbxOwner = OWN_HOST; 1277 1278 } else { 1279 MAILBOX *mb = (MAILBOX *)mbq; 1280 1281 bzero((void *)mb, MAILBOX_CMD_BSIZE); 1282 1283 mb->mbxCommand = MBX_DUMP_MEMORY; 1284 mb->un.varDmp.cv = 1; 1285 mb->un.varDmp.type = DMP_NV_PARAMS; 1286 mb->un.varDmp.entry_index = offset; 1287 mb->un.varDmp.region_id = DMP_VPD_REGION; 1288 1289 /* limited by mailbox size */ 1290 mb->un.varDmp.word_cnt = DMP_VPD_DUMP_WCOUNT; 1291 1292 mb->un.varDmp.co = 0; 1293 mb->un.varDmp.resp_offset = 0; 1294 mb->mbxOwner = OWN_HOST; 1295 } 1296 1297 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 1298 mbq->port = (void *)&PPORT; 1299 1300 } /* emlxs_mb_dump_vpd() */ 1301 1302 1303 /* SLI4 */ 1304 /*ARGSUSED*/ 1305 extern void 1306 emlxs_mb_dump_fcoe(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t offset) 1307 { 1308 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 1309 1310 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) { 1311 return; 1312 } 1313 1314 /* Clear the local dump_region */ 1315 bzero(hba->sli.sli4.dump_region.virt, 1316 hba->sli.sli4.dump_region.size); 1317 1318 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 1319 1320 mb4->mbxCommand = MBX_DUMP_MEMORY; 1321 mb4->un.varDmp4.type = DMP_NV_PARAMS; 1322 mb4->un.varDmp4.entry_index = offset; 1323 mb4->un.varDmp4.region_id = DMP_FCOE_REGION; 1324 1325 mb4->un.varDmp4.available_cnt = hba->sli.sli4.dump_region.size; 1326 mb4->un.varDmp4.addrHigh = 1327 PADDR_HI(hba->sli.sli4.dump_region.phys); 1328 mb4->un.varDmp4.addrLow = 1329 PADDR_LO(hba->sli.sli4.dump_region.phys); 1330 mb4->un.varDmp4.rsp_cnt = 0; 1331 1332 mb4->mbxOwner = OWN_HOST; 1333 1334 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 1335 mbq->port = (void *)&PPORT; 1336 1337 } /* emlxs_mb_dump_fcoe() */ 1338 1339 1340 /*ARGSUSED*/ 1341 extern void 1342 emlxs_mb_dump(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t offset, uint32_t words) 1343 { 1344 1345 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 1346 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 1347 1348 /* Clear the local dump_region */ 1349 bzero(hba->sli.sli4.dump_region.virt, 1350 hba->sli.sli4.dump_region.size); 1351 1352 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 1353 1354 mb4->mbxCommand = MBX_DUMP_MEMORY; 1355 mb4->un.varDmp4.type = DMP_MEM_REG; 1356 mb4->un.varDmp4.entry_index = offset; 1357 mb4->un.varDmp4.region_id = 0; 1358 1359 mb4->un.varDmp4.available_cnt = min((words*4), 1360 hba->sli.sli4.dump_region.size); 1361 mb4->un.varDmp4.addrHigh = 1362 PADDR_HI(hba->sli.sli4.dump_region.phys); 1363 mb4->un.varDmp4.addrLow = 1364 PADDR_LO(hba->sli.sli4.dump_region.phys); 1365 mb4->un.varDmp4.rsp_cnt = 0; 1366 1367 mb4->mbxOwner = OWN_HOST; 1368 1369 } else { 1370 1371 MAILBOX *mb = (MAILBOX *)mbq; 1372 1373 bzero((void *)mb, MAILBOX_CMD_BSIZE); 1374 1375 mb->mbxCommand = MBX_DUMP_MEMORY; 1376 mb->un.varDmp.type = DMP_MEM_REG; 1377 mb->un.varDmp.word_cnt = words; 1378 mb->un.varDmp.base_adr = offset; 1379 1380 mb->un.varDmp.co = 0; 1381 mb->un.varDmp.resp_offset = 0; 1382 mb->mbxOwner = OWN_HOST; 1383 } 1384 1385 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 1386 mbq->port = (void *)&PPORT; 1387 1388 return; 1389 1390 } /* emlxs_mb_dump() */ 1391 1392 1393 /* 1394 * emlxs_mb_read_nv Issue a READ NVPARAM mailbox command 1395 */ 1396 /*ARGSUSED*/ 1397 extern void 1398 emlxs_mb_read_nv(emlxs_hba_t *hba, MAILBOXQ *mbq) 1399 { 1400 MAILBOX *mb = (MAILBOX *)mbq; 1401 1402 bzero((void *)mb, MAILBOX_CMD_BSIZE); 1403 1404 mb->mbxCommand = MBX_READ_NV; 1405 mb->mbxOwner = OWN_HOST; 1406 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 1407 mbq->port = (void *)&PPORT; 1408 1409 } /* emlxs_mb_read_nv() */ 1410 1411 1412 /* 1413 * emlxs_mb_read_rev Issue a READ REV mailbox command 1414 */ 1415 /*ARGSUSED*/ 1416 extern void 1417 emlxs_mb_read_rev(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t v3) 1418 { 1419 MAILBOX *mb = (MAILBOX *)mbq; 1420 1421 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 1422 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 1423 mbq->nonembed = NULL; 1424 } else { 1425 bzero((void *)mb, MAILBOX_CMD_BSIZE); 1426 1427 mb->un.varRdRev.cv = 1; 1428 1429 if (v3) { 1430 mb->un.varRdRev.cv3 = 1; 1431 } 1432 } 1433 1434 mb->mbxCommand = MBX_READ_REV; 1435 mb->mbxOwner = OWN_HOST; 1436 mbq->mbox_cmpl = NULL; 1437 mbq->port = (void *)&PPORT; 1438 1439 } /* emlxs_mb_read_rev() */ 1440 1441 1442 /* 1443 * emlxs_mb_run_biu_diag Issue a RUN_BIU_DIAG mailbox command 1444 */ 1445 /*ARGSUSED*/ 1446 extern uint32_t 1447 emlxs_mb_run_biu_diag(emlxs_hba_t *hba, MAILBOXQ *mbq, uint64_t out, 1448 uint64_t in) 1449 { 1450 MAILBOX *mb = (MAILBOX *)mbq; 1451 1452 bzero((void *)mb, MAILBOX_CMD_BSIZE); 1453 1454 mb->mbxCommand = MBX_RUN_BIU_DIAG64; 1455 mb->un.varBIUdiag.un.s2.xmit_bde64.tus.f.bdeSize = MEM_ELSBUF_SIZE; 1456 mb->un.varBIUdiag.un.s2.xmit_bde64.addrHigh = PADDR_HI(out); 1457 mb->un.varBIUdiag.un.s2.xmit_bde64.addrLow = PADDR_LO(out); 1458 mb->un.varBIUdiag.un.s2.rcv_bde64.tus.f.bdeSize = MEM_ELSBUF_SIZE; 1459 mb->un.varBIUdiag.un.s2.rcv_bde64.addrHigh = PADDR_HI(in); 1460 mb->un.varBIUdiag.un.s2.rcv_bde64.addrLow = PADDR_LO(in); 1461 mb->mbxOwner = OWN_HOST; 1462 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 1463 mbq->port = (void *)&PPORT; 1464 1465 return (0); 1466 } /* emlxs_mb_run_biu_diag() */ 1467 1468 1469 /* This should only be called with active MBX_NOWAIT mailboxes */ 1470 void 1471 emlxs_mb_retry(emlxs_hba_t *hba, MAILBOXQ *mbq) 1472 { 1473 MAILBOX *mb; 1474 MAILBOX *mbox; 1475 int rc; 1476 1477 mbox = (MAILBOX *)emlxs_mem_get(hba, MEM_MBOX); 1478 if (!mbox) { 1479 return; 1480 } 1481 mb = (MAILBOX *)mbq; 1482 bcopy((uint8_t *)mb, (uint8_t *)mbox, MAILBOX_CMD_BSIZE); 1483 mbox->mbxOwner = OWN_HOST; 1484 mbox->mbxStatus = 0; 1485 1486 mutex_enter(&EMLXS_PORT_LOCK); 1487 1488 HBASTATS.MboxCompleted++; 1489 1490 if (mb->mbxStatus != 0) { 1491 HBASTATS.MboxError++; 1492 } else { 1493 HBASTATS.MboxGood++; 1494 } 1495 1496 hba->mbox_mbq = NULL; 1497 hba->mbox_queue_flag = 0; 1498 1499 mutex_exit(&EMLXS_PORT_LOCK); 1500 1501 rc = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_NOWAIT, 0); 1502 if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { 1503 emlxs_mem_put(hba, MEM_MBOX, (void *)mbox); 1504 } 1505 return; 1506 1507 } /* emlxs_mb_retry() */ 1508 1509 1510 /* SLI3 */ 1511 static uint32_t 1512 emlxs_read_la_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 1513 { 1514 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 1515 MAILBOX *mb; 1516 MAILBOXQ *mbox; 1517 MATCHMAP *mp; 1518 READ_LA_VAR la; 1519 int i; 1520 uint32_t control; 1521 1522 mb = (MAILBOX *)mbq; 1523 if (mb->mbxStatus) { 1524 if (mb->mbxStatus == MBXERR_NO_RESOURCES) { 1525 control = mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize; 1526 if (control == 0) { 1527 (void) emlxs_mb_read_la(hba, mbq); 1528 } 1529 emlxs_mb_retry(hba, mbq); 1530 return (1); 1531 } 1532 /* Enable Link Attention interrupts */ 1533 mutex_enter(&EMLXS_PORT_LOCK); 1534 1535 if (!(hba->sli.sli3.hc_copy & HC_LAINT_ENA)) { 1536 hba->sli.sli3.hc_copy |= HC_LAINT_ENA; 1537 WRITE_CSR_REG(hba, FC_HC_REG(hba), 1538 hba->sli.sli3.hc_copy); 1539 #ifdef FMA_SUPPORT 1540 /* Access handle validation */ 1541 EMLXS_CHK_ACC_HANDLE(hba, 1542 hba->sli.sli3.csr_acc_handle); 1543 #endif /* FMA_SUPPORT */ 1544 } 1545 1546 mutex_exit(&EMLXS_PORT_LOCK); 1547 return (0); 1548 } 1549 bcopy((void *)&mb->un.varReadLA, (void *)&la, sizeof (READ_LA_VAR)); 1550 1551 mp = (MATCHMAP *)mbq->bp; 1552 if (mp) { 1553 bcopy((caddr_t)mp->virt, (caddr_t)port->alpa_map, 128); 1554 } else { 1555 bzero((caddr_t)port->alpa_map, 128); 1556 } 1557 1558 if (la.attType == AT_LINK_UP) { 1559 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_linkup_atten_msg, 1560 "tag=%d -> %d ALPA=%x", 1561 (uint32_t)hba->link_event_tag, 1562 (uint32_t)la.eventTag, 1563 (uint32_t)la.granted_AL_PA); 1564 } else { 1565 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_linkdown_atten_msg, 1566 "tag=%d -> %d ALPA=%x", 1567 (uint32_t)hba->link_event_tag, 1568 (uint32_t)la.eventTag, 1569 (uint32_t)la.granted_AL_PA); 1570 } 1571 1572 if (la.pb) { 1573 hba->flag |= FC_BYPASSED_MODE; 1574 } else { 1575 hba->flag &= ~FC_BYPASSED_MODE; 1576 } 1577 1578 if (hba->link_event_tag == la.eventTag) { 1579 HBASTATS.LinkMultiEvent++; 1580 } else if (hba->link_event_tag + 1 < la.eventTag) { 1581 HBASTATS.LinkMultiEvent++; 1582 1583 /* Make sure link is declared down */ 1584 emlxs_linkdown(hba); 1585 } 1586 1587 hba->link_event_tag = la.eventTag; 1588 port->lip_type = 0; 1589 1590 /* If link not already up then declare it up now */ 1591 if ((la.attType == AT_LINK_UP) && (hba->state < FC_LINK_UP)) { 1592 1593 #ifdef MENLO_SUPPORT 1594 if ((hba->model_info.device_id == PCI_DEVICE_ID_HORNET) && 1595 (hba->flag & (FC_ILB_MODE | FC_ELB_MODE))) { 1596 la.topology = TOPOLOGY_LOOP; 1597 la.granted_AL_PA = 0; 1598 port->alpa_map[0] = 1; 1599 port->alpa_map[1] = 0; 1600 la.lipType = LT_PORT_INIT; 1601 } 1602 #endif /* MENLO_SUPPORT */ 1603 /* Save the linkspeed */ 1604 hba->linkspeed = la.UlnkSpeed; 1605 1606 /* Check for old model adapters that only */ 1607 /* supported 1Gb */ 1608 if ((hba->linkspeed == 0) && 1609 (hba->model_info.chip & EMLXS_DRAGONFLY_CHIP)) { 1610 hba->linkspeed = LA_1GHZ_LINK; 1611 } 1612 1613 if ((hba->topology = la.topology) == TOPOLOGY_LOOP) { 1614 port->granted_alpa = la.granted_AL_PA; 1615 port->did = port->granted_alpa; 1616 port->lip_type = la.lipType; 1617 if (hba->flag & FC_SLIM2_MODE) { 1618 i = la.un.lilpBde64.tus.f.bdeSize; 1619 } else { 1620 i = la.un.lilpBde.bdeSize; 1621 } 1622 1623 if (i == 0) { 1624 port->alpa_map[0] = 0; 1625 } else { 1626 uint8_t *alpa_map; 1627 uint32_t j; 1628 1629 /* Check number of devices in map */ 1630 if (port->alpa_map[0] > 127) { 1631 port->alpa_map[0] = 127; 1632 } 1633 1634 alpa_map = (uint8_t *)port->alpa_map; 1635 1636 EMLXS_MSGF(EMLXS_CONTEXT, 1637 &emlxs_link_atten_msg, 1638 "alpa_map: %d device(s): " 1639 "%02x %02x %02x %02x %02x %02x " 1640 "%02x", alpa_map[0], alpa_map[1], 1641 alpa_map[2], alpa_map[3], 1642 alpa_map[4], alpa_map[5], 1643 alpa_map[6], alpa_map[7]); 1644 1645 for (j = 8; j <= alpa_map[0]; j += 8) { 1646 EMLXS_MSGF(EMLXS_CONTEXT, 1647 &emlxs_link_atten_msg, 1648 "alpa_map: " 1649 "%02x %02x %02x %02x %02x " 1650 "%02x %02x %02x", 1651 alpa_map[j], 1652 alpa_map[j + 1], 1653 alpa_map[j + 2], 1654 alpa_map[j + 3], 1655 alpa_map[j + 4], 1656 alpa_map[j + 5], 1657 alpa_map[j + 6], 1658 alpa_map[j + 7]); 1659 } 1660 } 1661 } 1662 #ifdef MENLO_SUPPORT 1663 /* Check if Menlo maintenance mode is enabled */ 1664 if (hba->model_info.device_id == 1665 PCI_DEVICE_ID_HORNET) { 1666 if (la.mm == 1) { 1667 EMLXS_MSGF(EMLXS_CONTEXT, 1668 &emlxs_link_atten_msg, 1669 "Maintenance Mode enabled."); 1670 1671 mutex_enter(&EMLXS_PORT_LOCK); 1672 hba->flag |= FC_MENLO_MODE; 1673 mutex_exit(&EMLXS_PORT_LOCK); 1674 1675 mutex_enter(&EMLXS_LINKUP_LOCK); 1676 cv_broadcast(&EMLXS_LINKUP_CV); 1677 mutex_exit(&EMLXS_LINKUP_LOCK); 1678 } else { 1679 EMLXS_MSGF(EMLXS_CONTEXT, 1680 &emlxs_link_atten_msg, 1681 "Maintenance Mode disabled."); 1682 } 1683 1684 /* Check FCoE attention bit */ 1685 if (la.fa == 1) { 1686 emlxs_thread_spawn(hba, 1687 emlxs_fcoe_attention_thread, 1688 0, 0); 1689 } 1690 } 1691 #endif /* MENLO_SUPPORT */ 1692 1693 if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba, 1694 MEM_MBOX))) { 1695 /* This should turn on DELAYED ABTS for */ 1696 /* ELS timeouts */ 1697 emlxs_mb_set_var(hba, mbox, 0x00052198, 0x1); 1698 1699 emlxs_mb_put(hba, mbox); 1700 } 1701 1702 if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba, 1703 MEM_MBOX))) { 1704 /* If link not already down then */ 1705 /* declare it down now */ 1706 if (emlxs_mb_read_sparam(hba, mbox) == 0) { 1707 emlxs_mb_put(hba, mbox); 1708 } else { 1709 emlxs_mem_put(hba, MEM_MBOX, 1710 (void *)mbox); 1711 } 1712 } 1713 1714 if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba, 1715 MEM_MBOX))) { 1716 emlxs_mb_config_link(hba, mbox); 1717 1718 emlxs_mb_put(hba, mbox); 1719 } 1720 1721 /* Declare the linkup here */ 1722 emlxs_linkup(hba); 1723 } 1724 1725 /* If link not already down then declare it down now */ 1726 else if (la.attType == AT_LINK_DOWN) { 1727 /* Make sure link is declared down */ 1728 emlxs_linkdown(hba); 1729 } 1730 1731 /* Enable Link attention interrupt */ 1732 mutex_enter(&EMLXS_PORT_LOCK); 1733 1734 if (!(hba->sli.sli3.hc_copy & HC_LAINT_ENA)) { 1735 hba->sli.sli3.hc_copy |= HC_LAINT_ENA; 1736 WRITE_CSR_REG(hba, FC_HC_REG(hba), hba->sli.sli3.hc_copy); 1737 #ifdef FMA_SUPPORT 1738 /* Access handle validation */ 1739 EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle); 1740 #endif /* FMA_SUPPORT */ 1741 } 1742 1743 mutex_exit(&EMLXS_PORT_LOCK); 1744 1745 return (0); 1746 1747 } /* emlxs_read_la_mbcmpl() */ 1748 1749 1750 extern uint32_t 1751 emlxs_mb_read_la(emlxs_hba_t *hba, MAILBOXQ *mbq) 1752 { 1753 MAILBOX *mb = (MAILBOX *)mbq; 1754 MATCHMAP *mp; 1755 1756 bzero((void *)mb, MAILBOX_CMD_BSIZE); 1757 1758 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) { 1759 mb->mbxCommand = MBX_READ_LA64; 1760 1761 return (1); 1762 } 1763 1764 mb->mbxCommand = MBX_READ_LA64; 1765 mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize = 128; 1766 mb->un.varReadLA.un.lilpBde64.addrHigh = PADDR_HI(mp->phys); 1767 mb->un.varReadLA.un.lilpBde64.addrLow = PADDR_LO(mp->phys); 1768 mb->mbxOwner = OWN_HOST; 1769 mbq->mbox_cmpl = emlxs_read_la_mbcmpl; 1770 mbq->port = (void *)&PPORT; 1771 1772 /* 1773 * save address for completion 1774 */ 1775 mbq->bp = (void *)mp; 1776 1777 return (0); 1778 1779 } /* emlxs_mb_read_la() */ 1780 1781 1782 /* SLI3 */ 1783 static uint32_t 1784 emlxs_clear_la_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 1785 { 1786 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 1787 MAILBOX *mb; 1788 MAILBOXQ *mbox; 1789 emlxs_port_t *vport; 1790 uint32_t la_enable; 1791 int i, rc; 1792 1793 mb = (MAILBOX *)mbq; 1794 if (mb->mbxStatus) { 1795 la_enable = 1; 1796 1797 if (mb->mbxStatus == 0x1601) { 1798 /* Get a buffer which will be used for */ 1799 /* mailbox commands */ 1800 if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba, 1801 MEM_MBOX))) { 1802 /* Get link attention message */ 1803 if (emlxs_mb_read_la(hba, mbox) == 0) { 1804 rc = EMLXS_SLI_ISSUE_MBOX_CMD(hba, 1805 (MAILBOX *)mbox, MBX_NOWAIT, 0); 1806 if ((rc != MBX_BUSY) && 1807 (rc != MBX_SUCCESS)) { 1808 emlxs_mem_put(hba, 1809 MEM_MBOX, (void *)mbox); 1810 } 1811 la_enable = 0; 1812 } else { 1813 emlxs_mem_put(hba, MEM_MBOX, 1814 (void *)mbox); 1815 } 1816 } 1817 } 1818 1819 mutex_enter(&EMLXS_PORT_LOCK); 1820 if (la_enable) { 1821 if (!(hba->sli.sli3.hc_copy & HC_LAINT_ENA)) { 1822 /* Enable Link Attention interrupts */ 1823 hba->sli.sli3.hc_copy |= HC_LAINT_ENA; 1824 WRITE_CSR_REG(hba, FC_HC_REG(hba), 1825 hba->sli.sli3.hc_copy); 1826 #ifdef FMA_SUPPORT 1827 /* Access handle validation */ 1828 EMLXS_CHK_ACC_HANDLE(hba, 1829 hba->sli.sli3.csr_acc_handle); 1830 #endif /* FMA_SUPPORT */ 1831 } 1832 } else { 1833 if (hba->sli.sli3.hc_copy & HC_LAINT_ENA) { 1834 /* Disable Link Attention interrupts */ 1835 hba->sli.sli3.hc_copy &= ~HC_LAINT_ENA; 1836 WRITE_CSR_REG(hba, FC_HC_REG(hba), 1837 hba->sli.sli3.hc_copy); 1838 #ifdef FMA_SUPPORT 1839 /* Access handle validation */ 1840 EMLXS_CHK_ACC_HANDLE(hba, 1841 hba->sli.sli3.csr_acc_handle); 1842 #endif /* FMA_SUPPORT */ 1843 } 1844 } 1845 mutex_exit(&EMLXS_PORT_LOCK); 1846 1847 return (0); 1848 } 1849 /* Enable on Link Attention interrupts */ 1850 mutex_enter(&EMLXS_PORT_LOCK); 1851 1852 if (!(hba->sli.sli3.hc_copy & HC_LAINT_ENA)) { 1853 hba->sli.sli3.hc_copy |= HC_LAINT_ENA; 1854 WRITE_CSR_REG(hba, FC_HC_REG(hba), hba->sli.sli3.hc_copy); 1855 #ifdef FMA_SUPPORT 1856 /* Access handle validation */ 1857 EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle); 1858 #endif /* FMA_SUPPORT */ 1859 } 1860 1861 if (hba->state >= FC_LINK_UP) { 1862 EMLXS_STATE_CHANGE_LOCKED(hba, FC_READY); 1863 } 1864 1865 mutex_exit(&EMLXS_PORT_LOCK); 1866 1867 /* Adapter is now ready for FCP traffic */ 1868 if (hba->state == FC_READY) { 1869 1870 /* Register vpi's for all ports that have did's */ 1871 for (i = 0; i < MAX_VPORTS; i++) { 1872 vport = &VPORT(i); 1873 1874 if (!(vport->flag & EMLXS_PORT_BOUND) || 1875 !(vport->did)) { 1876 continue; 1877 } 1878 1879 (void) emlxs_mb_reg_vpi(vport, NULL); 1880 } 1881 1882 /* Attempt to send any pending IO */ 1883 EMLXS_SLI_ISSUE_IOCB_CMD(hba, &hba->chan[hba->channel_fcp], 0); 1884 } 1885 return (0); 1886 1887 } /* emlxs_clear_la_mbcmpl() */ 1888 1889 1890 /* SLI3 */ 1891 extern void 1892 emlxs_mb_clear_la(emlxs_hba_t *hba, MAILBOXQ *mbq) 1893 { 1894 MAILBOX *mb = (MAILBOX *)mbq; 1895 1896 #ifdef FC_RPI_CHECK 1897 emlxs_rpi_check(hba); 1898 #endif /* FC_RPI_CHECK */ 1899 1900 bzero((void *)mb, MAILBOX_CMD_BSIZE); 1901 1902 mb->un.varClearLA.eventTag = hba->link_event_tag; 1903 mb->mbxCommand = MBX_CLEAR_LA; 1904 mb->mbxOwner = OWN_HOST; 1905 mbq->mbox_cmpl = emlxs_clear_la_mbcmpl; 1906 mbq->port = (void *)&PPORT; 1907 1908 return; 1909 1910 } /* emlxs_mb_clear_la() */ 1911 1912 1913 /* 1914 * emlxs_mb_read_status Issue a READ STATUS mailbox command 1915 */ 1916 /*ARGSUSED*/ 1917 extern void 1918 emlxs_mb_read_status(emlxs_hba_t *hba, MAILBOXQ *mbq) 1919 { 1920 MAILBOX *mb = (MAILBOX *)mbq; 1921 1922 bzero((void *)mb, MAILBOX_CMD_BSIZE); 1923 1924 mb->mbxCommand = MBX_READ_STATUS; 1925 mb->mbxOwner = OWN_HOST; 1926 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 1927 mbq->port = (void *)&PPORT; 1928 1929 } /* fc_read_status() */ 1930 1931 1932 /* 1933 * emlxs_mb_read_lnk_stat Issue a LINK STATUS mailbox command 1934 */ 1935 /*ARGSUSED*/ 1936 extern void 1937 emlxs_mb_read_lnk_stat(emlxs_hba_t *hba, MAILBOXQ *mbq) 1938 { 1939 MAILBOX *mb = (MAILBOX *)mbq; 1940 1941 bzero((void *)mb, MAILBOX_CMD_BSIZE); 1942 1943 mb->mbxCommand = MBX_READ_LNK_STAT; 1944 mb->mbxOwner = OWN_HOST; 1945 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 1946 mbq->port = (void *)&PPORT; 1947 1948 } /* emlxs_mb_read_lnk_stat() */ 1949 1950 1951 1952 1953 1954 1955 /* 1956 * emlxs_mb_config_ring Issue a CONFIG RING mailbox command 1957 */ 1958 extern void 1959 emlxs_mb_config_ring(emlxs_hba_t *hba, int32_t ring, MAILBOXQ *mbq) 1960 { 1961 MAILBOX *mb = (MAILBOX *)mbq; 1962 int32_t i; 1963 int32_t j; 1964 1965 bzero((void *)mb, MAILBOX_CMD_BSIZE); 1966 1967 j = 0; 1968 for (i = 0; i < ring; i++) { 1969 j += hba->sli.sli3.ring_masks[i]; 1970 } 1971 1972 for (i = 0; i < hba->sli.sli3.ring_masks[ring]; i++) { 1973 if ((j + i) >= 6) { 1974 break; 1975 } 1976 1977 mb->un.varCfgRing.rrRegs[i].rval = 1978 hba->sli.sli3.ring_rval[j + i]; 1979 mb->un.varCfgRing.rrRegs[i].rmask = 1980 hba->sli.sli3.ring_rmask[j + i]; 1981 mb->un.varCfgRing.rrRegs[i].tval = 1982 hba->sli.sli3.ring_tval[j + i]; 1983 mb->un.varCfgRing.rrRegs[i].tmask = 1984 hba->sli.sli3.ring_tmask[j + i]; 1985 } 1986 1987 mb->un.varCfgRing.ring = ring; 1988 mb->un.varCfgRing.profile = 0; 1989 mb->un.varCfgRing.maxOrigXchg = 0; 1990 mb->un.varCfgRing.maxRespXchg = 0; 1991 mb->un.varCfgRing.recvNotify = 1; 1992 mb->un.varCfgRing.numMask = hba->sli.sli3.ring_masks[ring]; 1993 mb->mbxCommand = MBX_CONFIG_RING; 1994 mb->mbxOwner = OWN_HOST; 1995 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 1996 mbq->port = (void *)&PPORT; 1997 1998 return; 1999 2000 } /* emlxs_mb_config_ring() */ 2001 2002 2003 /* 2004 * emlxs_mb_config_link Issue a CONFIG LINK mailbox command 2005 */ 2006 extern void 2007 emlxs_mb_config_link(emlxs_hba_t *hba, MAILBOXQ *mbq) 2008 { 2009 MAILBOX *mb = (MAILBOX *)mbq; 2010 emlxs_port_t *port = &PPORT; 2011 emlxs_config_t *cfg = &CFG; 2012 2013 bzero((void *)mb, MAILBOX_CMD_BSIZE); 2014 2015 /* 2016 * NEW_FEATURE SLI-2, Coalescing Response Feature. 2017 */ 2018 if (cfg[CFG_CR_DELAY].current) { 2019 mb->un.varCfgLnk.cr = 1; 2020 mb->un.varCfgLnk.ci = 1; 2021 mb->un.varCfgLnk.cr_delay = cfg[CFG_CR_DELAY].current; 2022 mb->un.varCfgLnk.cr_count = cfg[CFG_CR_COUNT].current; 2023 } 2024 2025 if (cfg[CFG_ACK0].current) { 2026 mb->un.varCfgLnk.ack0_enable = 1; 2027 } 2028 2029 mb->un.varCfgLnk.myId = port->did; 2030 mb->un.varCfgLnk.edtov = hba->fc_edtov; 2031 mb->un.varCfgLnk.arbtov = hba->fc_arbtov; 2032 mb->un.varCfgLnk.ratov = hba->fc_ratov; 2033 mb->un.varCfgLnk.rttov = hba->fc_rttov; 2034 mb->un.varCfgLnk.altov = hba->fc_altov; 2035 mb->un.varCfgLnk.crtov = hba->fc_crtov; 2036 mb->un.varCfgLnk.citov = hba->fc_citov; 2037 mb->mbxCommand = MBX_CONFIG_LINK; 2038 mb->mbxOwner = OWN_HOST; 2039 mbq->mbox_cmpl = NULL; 2040 mbq->port = (void *)port; 2041 2042 return; 2043 2044 } /* emlxs_mb_config_link() */ 2045 2046 2047 static uint32_t 2048 emlxs_init_link_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 2049 { 2050 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 2051 emlxs_config_t *cfg = &CFG; 2052 MAILBOX *mb; 2053 2054 mb = (MAILBOX *)mbq; 2055 if (mb->mbxStatus) { 2056 if ((hba->flag & FC_SLIM2_MODE) && 2057 (hba->mbox_queue_flag == MBX_NOWAIT)) { 2058 /* Retry only MBX_NOWAIT requests */ 2059 2060 if ((cfg[CFG_LINK_SPEED].current > 0) && 2061 ((mb->mbxStatus == 0x0011) || 2062 (mb->mbxStatus == 0x0500))) { 2063 2064 EMLXS_MSGF(EMLXS_CONTEXT, 2065 &emlxs_mbox_event_msg, 2066 "Retrying. %s: status=%x. Auto-speed set.", 2067 emlxs_mb_cmd_xlate(mb->mbxCommand), 2068 (uint32_t)mb->mbxStatus); 2069 2070 mb->un.varInitLnk.link_flags &= 2071 ~FLAGS_LINK_SPEED; 2072 mb->un.varInitLnk.link_speed = 0; 2073 2074 emlxs_mb_retry(hba, mbq); 2075 return (1); 2076 } 2077 } 2078 } 2079 return (0); 2080 2081 } /* emlxs_init_link_mbcmpl() */ 2082 2083 2084 /* 2085 * emlxs_mb_init_link Issue an INIT LINK mailbox command 2086 */ 2087 extern void 2088 emlxs_mb_init_link(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t topology, 2089 uint32_t linkspeed) 2090 { 2091 MAILBOX *mb = (MAILBOX *)mbq; 2092 emlxs_vpd_t *vpd = &VPD; 2093 emlxs_config_t *cfg = &CFG; 2094 2095 if ((hba->sli_mode == EMLXS_HBA_SLI4_MODE) && 2096 (SLI4_FCOE_MODE)) { 2097 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 2098 mbq->nonembed = NULL; 2099 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 2100 mbq->port = (void *)&PPORT; 2101 2102 mb->mbxCommand = (volatile uint8_t) MBX_INIT_LINK; 2103 mb->mbxOwner = OWN_HOST; 2104 return; 2105 } 2106 2107 bzero((void *)mb, MAILBOX_CMD_BSIZE); 2108 2109 switch (topology) { 2110 case FLAGS_LOCAL_LB: 2111 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP; 2112 mb->un.varInitLnk.link_flags |= FLAGS_LOCAL_LB; 2113 break; 2114 case FLAGS_TOPOLOGY_MODE_LOOP_PT: 2115 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP; 2116 mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER; 2117 break; 2118 case FLAGS_TOPOLOGY_MODE_PT_PT: 2119 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT; 2120 break; 2121 case FLAGS_TOPOLOGY_MODE_LOOP: 2122 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP; 2123 break; 2124 case FLAGS_TOPOLOGY_MODE_PT_LOOP: 2125 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT; 2126 mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER; 2127 break; 2128 } 2129 2130 if (cfg[CFG_LILP_ENABLE].current == 0) { 2131 /* Disable LIRP/LILP support */ 2132 mb->un.varInitLnk.link_flags |= FLAGS_LIRP_LILP; 2133 } 2134 2135 /* 2136 * Setting up the link speed 2137 */ 2138 switch (linkspeed) { 2139 case 0: 2140 break; 2141 2142 case 1: 2143 if (!(vpd->link_speed & LMT_1GB_CAPABLE)) { 2144 linkspeed = 0; 2145 } 2146 break; 2147 2148 case 2: 2149 if (!(vpd->link_speed & LMT_2GB_CAPABLE)) { 2150 linkspeed = 0; 2151 } 2152 break; 2153 2154 case 4: 2155 if (!(vpd->link_speed & LMT_4GB_CAPABLE)) { 2156 linkspeed = 0; 2157 } 2158 break; 2159 2160 case 8: 2161 if (!(vpd->link_speed & LMT_8GB_CAPABLE)) { 2162 linkspeed = 0; 2163 } 2164 break; 2165 2166 case 10: 2167 if (!(vpd->link_speed & LMT_10GB_CAPABLE)) { 2168 linkspeed = 0; 2169 } 2170 break; 2171 2172 case 16: 2173 if (!(vpd->link_speed & LMT_16GB_CAPABLE)) { 2174 linkspeed = 0; 2175 } 2176 break; 2177 2178 default: 2179 linkspeed = 0; 2180 break; 2181 2182 } 2183 2184 if ((linkspeed > 0) && (vpd->feaLevelHigh >= 0x02)) { 2185 mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED; 2186 mb->un.varInitLnk.link_speed = linkspeed; 2187 } 2188 2189 mb->un.varInitLnk.link_flags |= FLAGS_PREABORT_RETURN; 2190 2191 mb->un.varInitLnk.fabric_AL_PA = 2192 (uint8_t)cfg[CFG_ASSIGN_ALPA].current; 2193 mb->mbxCommand = (volatile uint8_t) MBX_INIT_LINK; 2194 mb->mbxOwner = OWN_HOST; 2195 mbq->mbox_cmpl = emlxs_init_link_mbcmpl; 2196 mbq->port = (void *)&PPORT; 2197 2198 2199 return; 2200 2201 } /* emlxs_mb_init_link() */ 2202 2203 2204 /* 2205 * emlxs_mb_down_link Issue a DOWN LINK mailbox command 2206 */ 2207 /*ARGSUSED*/ 2208 extern void 2209 emlxs_mb_down_link(emlxs_hba_t *hba, MAILBOXQ *mbq) 2210 { 2211 MAILBOX *mb = (MAILBOX *)mbq; 2212 2213 bzero((void *)mb, MAILBOX_CMD_BSIZE); 2214 2215 mb->mbxCommand = MBX_DOWN_LINK; 2216 mb->mbxOwner = OWN_HOST; 2217 mbq->mbox_cmpl = NULL; 2218 mbq->port = (void *)&PPORT; 2219 2220 return; 2221 2222 } /* emlxs_mb_down_link() */ 2223 2224 2225 static uint32_t 2226 emlxs_read_sparam_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 2227 { 2228 emlxs_port_t *port = &PPORT; 2229 MAILBOX *mb; 2230 MATCHMAP *mp; 2231 emlxs_port_t *vport; 2232 int32_t i; 2233 uint32_t control; 2234 uint8_t null_wwn[8]; 2235 2236 mb = (MAILBOX *)mbq; 2237 if (mb->mbxStatus) { 2238 if (mb->mbxStatus == MBXERR_NO_RESOURCES) { 2239 control = mb->un.varRdSparm.un.sp64.tus.f.bdeSize; 2240 if (control == 0) { 2241 (void) emlxs_mb_read_sparam(hba, mbq); 2242 } 2243 emlxs_mb_retry(hba, mbq); 2244 return (1); 2245 } 2246 return (0); 2247 } 2248 mp = (MATCHMAP *)mbq->bp; 2249 if (!mp) { 2250 return (0); 2251 } 2252 2253 bcopy((caddr_t)mp->virt, (caddr_t)&hba->sparam, sizeof (SERV_PARM)); 2254 2255 /* Initialize the node name and port name only once */ 2256 bzero(null_wwn, 8); 2257 if ((bcmp((caddr_t)&hba->wwnn, (caddr_t)null_wwn, 8) == 0) && 2258 (bcmp((caddr_t)&hba->wwpn, (caddr_t)null_wwn, 8) == 0)) { 2259 bcopy((caddr_t)&hba->sparam.nodeName, 2260 (caddr_t)&hba->wwnn, sizeof (NAME_TYPE)); 2261 2262 bcopy((caddr_t)&hba->sparam.portName, 2263 (caddr_t)&hba->wwpn, sizeof (NAME_TYPE)); 2264 } else { 2265 bcopy((caddr_t)&hba->wwnn, 2266 (caddr_t)&hba->sparam.nodeName, sizeof (NAME_TYPE)); 2267 2268 bcopy((caddr_t)&hba->wwpn, 2269 (caddr_t)&hba->sparam.portName, sizeof (NAME_TYPE)); 2270 } 2271 2272 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2273 "SPARAM: EDTOV hba=%x mbox_csp=%x BBC=%x", 2274 hba->fc_edtov, hba->sparam.cmn.e_d_tov, 2275 hba->sparam.cmn.bbCreditlsb); 2276 2277 /* Initialize the physical port */ 2278 bcopy((caddr_t)&hba->sparam, (caddr_t)&port->sparam, 2279 sizeof (SERV_PARM)); 2280 bcopy((caddr_t)&hba->wwpn, (caddr_t)&port->wwpn, 2281 sizeof (NAME_TYPE)); 2282 bcopy((caddr_t)&hba->wwnn, (caddr_t)&port->wwnn, 2283 sizeof (NAME_TYPE)); 2284 2285 /* Initialize the virtual ports */ 2286 for (i = 1; i < MAX_VPORTS; i++) { 2287 vport = &VPORT(i); 2288 if (! (vport->flag & EMLXS_PORT_BOUND)) { 2289 continue; 2290 } 2291 2292 bcopy((caddr_t)&hba->sparam, 2293 (caddr_t)&vport->sparam, 2294 sizeof (SERV_PARM)); 2295 2296 bcopy((caddr_t)&vport->wwnn, 2297 (caddr_t)&vport->sparam.nodeName, 2298 sizeof (NAME_TYPE)); 2299 2300 bcopy((caddr_t)&vport->wwpn, 2301 (caddr_t)&vport->sparam.portName, 2302 sizeof (NAME_TYPE)); 2303 } 2304 2305 return (0); 2306 2307 } /* emlxs_read_sparam_mbcmpl() */ 2308 2309 2310 /* 2311 * emlxs_mb_read_sparam Issue a READ SPARAM mailbox command 2312 */ 2313 extern uint32_t 2314 emlxs_mb_read_sparam(emlxs_hba_t *hba, MAILBOXQ *mbq) 2315 { 2316 MAILBOX *mb = (MAILBOX *)mbq; 2317 MATCHMAP *mp; 2318 2319 bzero((void *)mb, MAILBOX_CMD_BSIZE); 2320 2321 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) { 2322 mb->mbxCommand = MBX_READ_SPARM64; 2323 2324 return (1); 2325 } 2326 2327 mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (SERV_PARM); 2328 mb->un.varRdSparm.un.sp64.addrHigh = PADDR_HI(mp->phys); 2329 mb->un.varRdSparm.un.sp64.addrLow = PADDR_LO(mp->phys); 2330 mb->mbxCommand = MBX_READ_SPARM64; 2331 mb->mbxOwner = OWN_HOST; 2332 mbq->mbox_cmpl = emlxs_read_sparam_mbcmpl; 2333 mbq->port = (void *)&PPORT; 2334 2335 /* 2336 * save address for completion 2337 */ 2338 mbq->bp = (void *)mp; 2339 2340 return (0); 2341 2342 } /* emlxs_mb_read_sparam() */ 2343 2344 2345 /* 2346 * emlxs_mb_read_rpi Issue a READ RPI mailbox command 2347 */ 2348 /*ARGSUSED*/ 2349 extern uint32_t 2350 emlxs_mb_read_rpi(emlxs_hba_t *hba, uint32_t rpi, MAILBOXQ *mbq, 2351 uint32_t flag) 2352 { 2353 MAILBOX *mb = (MAILBOX *)mbq; 2354 2355 bzero((void *)mb, MAILBOX_CMD_BSIZE); 2356 2357 /* 2358 * Set flag to issue action on cmpl 2359 */ 2360 mb->un.varWords[30] = flag; 2361 mb->un.varRdRPI.reqRpi = (volatile uint16_t) rpi; 2362 mb->mbxCommand = MBX_READ_RPI64; 2363 mb->mbxOwner = OWN_HOST; 2364 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 2365 mbq->port = (void *)&PPORT; 2366 2367 return (0); 2368 } /* emlxs_mb_read_rpi() */ 2369 2370 2371 /* 2372 * emlxs_mb_read_xri Issue a READ XRI mailbox command 2373 */ 2374 /*ARGSUSED*/ 2375 extern uint32_t 2376 emlxs_mb_read_xri(emlxs_hba_t *hba, uint32_t xri, MAILBOXQ *mbq, 2377 uint32_t flag) 2378 { 2379 MAILBOX *mb = (MAILBOX *)mbq; 2380 2381 bzero((void *)mb, MAILBOX_CMD_BSIZE); 2382 2383 /* 2384 * Set flag to issue action on cmpl 2385 */ 2386 mb->un.varWords[30] = flag; 2387 mb->un.varRdXRI.reqXri = (volatile uint16_t)xri; 2388 mb->mbxCommand = MBX_READ_XRI; 2389 mb->mbxOwner = OWN_HOST; 2390 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 2391 mbq->port = (void *)&PPORT; 2392 2393 return (0); 2394 } /* emlxs_mb_read_xri() */ 2395 2396 2397 /*ARGSUSED*/ 2398 extern int32_t 2399 emlxs_mb_check_sparm(emlxs_hba_t *hba, SERV_PARM *nsp) 2400 { 2401 uint32_t nsp_value; 2402 uint32_t *iptr; 2403 2404 if (nsp->cmn.fPort) { 2405 return (0); 2406 } 2407 2408 /* Validate the service parameters */ 2409 iptr = (uint32_t *)&nsp->portName; 2410 if (iptr[0] == 0 && iptr[1] == 0) { 2411 return (1); 2412 } 2413 2414 iptr = (uint32_t *)&nsp->nodeName; 2415 if (iptr[0] == 0 && iptr[1] == 0) { 2416 return (2); 2417 } 2418 2419 if (nsp->cls2.classValid) { 2420 nsp_value = 2421 ((nsp->cls2.rcvDataSizeMsb & 0x0f) << 8) | nsp->cls2. 2422 rcvDataSizeLsb; 2423 2424 /* If the receive data length is zero then set it to */ 2425 /* the CSP value */ 2426 if (!nsp_value) { 2427 nsp->cls2.rcvDataSizeMsb = nsp->cmn.bbRcvSizeMsb; 2428 nsp->cls2.rcvDataSizeLsb = nsp->cmn.bbRcvSizeLsb; 2429 return (0); 2430 } 2431 } 2432 2433 if (nsp->cls3.classValid) { 2434 nsp_value = 2435 ((nsp->cls3.rcvDataSizeMsb & 0x0f) << 8) | nsp->cls3. 2436 rcvDataSizeLsb; 2437 2438 /* If the receive data length is zero then set it to */ 2439 /* the CSP value */ 2440 if (!nsp_value) { 2441 nsp->cls3.rcvDataSizeMsb = nsp->cmn.bbRcvSizeMsb; 2442 nsp->cls3.rcvDataSizeLsb = nsp->cmn.bbRcvSizeLsb; 2443 return (0); 2444 } 2445 } 2446 2447 return (0); 2448 2449 } /* emlxs_mb_check_sparm() */ 2450 2451 2452 2453 2454 /* 2455 * emlxs_mb_set_var Issue a special debug mbox command to write slim 2456 */ 2457 /*ARGSUSED*/ 2458 extern void 2459 emlxs_mb_set_var(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t addr, 2460 uint32_t value) 2461 { 2462 MAILBOX *mb = (MAILBOX *)mbq; 2463 2464 bzero((void *)mb, MAILBOX_CMD_BSIZE); 2465 2466 /* addr = 0x090597 is AUTO ABTS disable for ELS commands */ 2467 /* addr = 0x052198 is DELAYED ABTS enable for ELS commands */ 2468 /* addr = 0x100506 is for setting PCI MAX READ value */ 2469 2470 /* 2471 * Always turn on DELAYED ABTS for ELS timeouts 2472 */ 2473 if ((addr == 0x052198) && (value == 0)) { 2474 value = 1; 2475 } 2476 2477 mb->un.varWords[0] = addr; 2478 mb->un.varWords[1] = value; 2479 mb->mbxCommand = MBX_SET_VARIABLE; 2480 mb->mbxOwner = OWN_HOST; 2481 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 2482 mbq->port = (void *)&PPORT; 2483 2484 } /* emlxs_mb_set_var() */ 2485 2486 2487 /* 2488 * Disable Traffic Cop 2489 */ 2490 /*ARGSUSED*/ 2491 extern void 2492 emlxs_disable_tc(emlxs_hba_t *hba, MAILBOXQ *mbq) 2493 { 2494 MAILBOX *mb = (MAILBOX *)mbq; 2495 2496 bzero((void *)mb, MAILBOX_CMD_BSIZE); 2497 2498 mb->un.varWords[0] = 0x50797; 2499 mb->un.varWords[1] = 0; 2500 mb->un.varWords[2] = 0xfffffffe; 2501 mb->mbxCommand = MBX_SET_VARIABLE; 2502 mb->mbxOwner = OWN_HOST; 2503 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 2504 mbq->port = (void *)&PPORT; 2505 2506 } /* emlxs_disable_tc() */ 2507 2508 2509 extern void 2510 emlxs_mb_config_hbq(emlxs_hba_t *hba, MAILBOXQ *mbq, int hbq_id) 2511 { 2512 HBQ_INIT_t *hbq; 2513 MAILBOX *mb = (MAILBOX *)mbq; 2514 int i; 2515 2516 bzero((void *)mb, MAILBOX_CMD_BSIZE); 2517 2518 hbq = &hba->sli.sli3.hbq_table[hbq_id]; 2519 2520 mb->un.varCfgHbq.hbqId = hbq_id; 2521 mb->un.varCfgHbq.numEntries = hbq->HBQ_numEntries; 2522 mb->un.varCfgHbq.recvNotify = hbq->HBQ_recvNotify; 2523 mb->un.varCfgHbq.numMask = hbq->HBQ_num_mask; 2524 mb->un.varCfgHbq.profile = hbq->HBQ_profile; 2525 mb->un.varCfgHbq.ringMask = hbq->HBQ_ringMask; 2526 mb->un.varCfgHbq.headerLen = hbq->HBQ_headerLen; 2527 mb->un.varCfgHbq.logEntry = hbq->HBQ_logEntry; 2528 mb->un.varCfgHbq.hbqaddrLow = PADDR_LO(hbq->HBQ_host_buf.phys); 2529 mb->un.varCfgHbq.hbqaddrHigh = PADDR_HI(hbq->HBQ_host_buf.phys); 2530 mb->mbxCommand = MBX_CONFIG_HBQ; 2531 mb->mbxOwner = OWN_HOST; 2532 mbq->mbox_cmpl = NULL; 2533 mbq->port = (void *)&PPORT; 2534 2535 /* Copy info for profiles 2,3,5. Other profiles this area is reserved */ 2536 if ((hbq->HBQ_profile == 2) || (hbq->HBQ_profile == 3) || 2537 (hbq->HBQ_profile == 5)) { 2538 bcopy(&hbq->profiles.allprofiles, 2539 &mb->un.varCfgHbq.profiles.allprofiles, 2540 sizeof (hbq->profiles)); 2541 } 2542 2543 /* Return if no rctl / type masks for this HBQ */ 2544 if (!hbq->HBQ_num_mask) { 2545 return; 2546 } 2547 2548 /* Otherwise we setup specific rctl / type masks for this HBQ */ 2549 for (i = 0; i < hbq->HBQ_num_mask; i++) { 2550 mb->un.varCfgHbq.hbqMasks[i].tmatch = 2551 hbq->HBQ_Masks[i].tmatch; 2552 mb->un.varCfgHbq.hbqMasks[i].tmask = hbq->HBQ_Masks[i].tmask; 2553 mb->un.varCfgHbq.hbqMasks[i].rctlmatch = 2554 hbq->HBQ_Masks[i].rctlmatch; 2555 mb->un.varCfgHbq.hbqMasks[i].rctlmask = 2556 hbq->HBQ_Masks[i].rctlmask; 2557 } 2558 2559 return; 2560 2561 } /* emlxs_mb_config_hbq() */ 2562 2563 2564 /* SLI3 */ 2565 static uint32_t 2566 emlxs_reg_vpi_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 2567 { 2568 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 2569 MAILBOX *mb; 2570 2571 mb = (MAILBOX *)mbq; 2572 2573 mutex_enter(&EMLXS_PORT_LOCK); 2574 2575 if (mb->mbxStatus != MBX_SUCCESS) { 2576 port->flag &= ~EMLXS_PORT_REG_VPI; 2577 mutex_exit(&EMLXS_PORT_LOCK); 2578 2579 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2580 "cmpl_reg_vpi:%d failed. status=%x", 2581 port->vpi, mb->mbxStatus); 2582 return (0); 2583 } 2584 2585 port->flag |= EMLXS_PORT_REG_VPI_CMPL; 2586 2587 mutex_exit(&EMLXS_PORT_LOCK); 2588 2589 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2590 "cmpl_reg_vpi:%d ", 2591 port->vpi); 2592 2593 return (0); 2594 2595 } /* emlxs_reg_vpi_mbcmpl */ 2596 2597 2598 /* SLI3 */ 2599 extern uint32_t 2600 emlxs_mb_reg_vpi(emlxs_port_t *port, emlxs_buf_t *sbp) 2601 { 2602 emlxs_hba_t *hba = HBA; 2603 MAILBOXQ *mbq; 2604 MAILBOX *mb; 2605 int rval; 2606 2607 if (hba->sli_mode > EMLXS_HBA_SLI3_MODE) { 2608 return (1); 2609 } 2610 2611 if (!(hba->flag & FC_NPIV_ENABLED)) { 2612 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2613 "reg_vpi:%d failed. NPIV disabled.", 2614 port->vpi); 2615 return (1); 2616 } 2617 2618 if (port->flag & EMLXS_PORT_REG_VPI) { 2619 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2620 "reg_vpi:%d failed. Already registered.", 2621 port->vpi); 2622 return (0); 2623 } 2624 2625 mutex_enter(&EMLXS_PORT_LOCK); 2626 2627 /* Can't reg vpi until ClearLA is sent */ 2628 if (hba->state != FC_READY) { 2629 mutex_exit(&EMLXS_PORT_LOCK); 2630 2631 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2632 "reg_vpi:%d failed. HBA state not READY", 2633 port->vpi); 2634 return (1); 2635 } 2636 2637 /* Must have port id */ 2638 if (!port->did) { 2639 mutex_exit(&EMLXS_PORT_LOCK); 2640 2641 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2642 "reg_vpi:%d failed. Port did=0", 2643 port->vpi); 2644 return (1); 2645 } 2646 2647 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 2648 mutex_exit(&EMLXS_PORT_LOCK); 2649 2650 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2651 "reg_vpi:%d failed. Unable to allocate mbox.", 2652 port->vpi); 2653 return (1); 2654 } 2655 2656 port->flag |= EMLXS_PORT_REG_VPI; 2657 2658 mutex_exit(&EMLXS_PORT_LOCK); 2659 2660 mb = (MAILBOX *)mbq->mbox; 2661 bzero((void *)mb, MAILBOX_CMD_BSIZE); 2662 2663 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2664 "reg_vpi:%d", port->vpi); 2665 2666 mb->un.varRegVpi.vpi = port->vpi; 2667 mb->un.varRegVpi.sid = port->did; 2668 mb->mbxCommand = MBX_REG_VPI; 2669 mb->mbxOwner = OWN_HOST; 2670 2671 mbq->sbp = (void *)sbp; 2672 mbq->mbox_cmpl = emlxs_reg_vpi_mbcmpl; 2673 mbq->context = NULL; 2674 mbq->port = (void *)port; 2675 2676 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 2677 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 2678 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2679 "reg_vpi:%d failed. Unable to send request.", 2680 port->vpi); 2681 2682 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 2683 return (1); 2684 } 2685 2686 return (0); 2687 2688 } /* emlxs_mb_reg_vpi() */ 2689 2690 2691 /* SLI3 */ 2692 static uint32_t 2693 emlxs_unreg_vpi_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 2694 { 2695 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 2696 MAILBOX *mb; 2697 2698 mb = (MAILBOX *)mbq->mbox; 2699 2700 if (mb->mbxStatus != MBX_SUCCESS) { 2701 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2702 "unreg_vpi_mbcmpl:%d failed. status=%x", 2703 port->vpi, mb->mbxStatus); 2704 return (0); 2705 } 2706 2707 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2708 "unreg_vpi_mbcmpl:%d", port->vpi); 2709 2710 mutex_enter(&EMLXS_PORT_LOCK); 2711 port->flag &= ~EMLXS_PORT_REG_VPI_CMPL; 2712 mutex_exit(&EMLXS_PORT_LOCK); 2713 2714 return (0); 2715 2716 } /* emlxs_unreg_vpi_mbcmpl() */ 2717 2718 2719 /* SLI3 */ 2720 extern uint32_t 2721 emlxs_mb_unreg_vpi(emlxs_port_t *port) 2722 { 2723 emlxs_hba_t *hba = HBA; 2724 MAILBOXQ *mbq; 2725 MAILBOX *mb; 2726 int rval; 2727 2728 if (hba->sli_mode > EMLXS_HBA_SLI3_MODE) { 2729 return (1); 2730 } 2731 2732 mutex_enter(&EMLXS_PORT_LOCK); 2733 2734 if (!(port->flag & EMLXS_PORT_REG_VPI) || 2735 !(port->flag & EMLXS_PORT_REG_VPI_CMPL)) { 2736 2737 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2738 "unreg_vpi:%d failed. Not registered. flag=%x", 2739 port->vpi, port->flag); 2740 2741 mutex_exit(&EMLXS_PORT_LOCK); 2742 return (0); 2743 } 2744 2745 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 2746 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2747 "unreg_vpi:%d failed. Unable to allocate mbox.", 2748 port->vpi); 2749 2750 mutex_exit(&EMLXS_PORT_LOCK); 2751 return (1); 2752 } 2753 2754 port->flag &= ~EMLXS_PORT_REG_VPI; 2755 2756 mutex_exit(&EMLXS_PORT_LOCK); 2757 2758 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2759 "unreg_vpi:%d", port->vpi); 2760 2761 mb = (MAILBOX *)mbq->mbox; 2762 bzero((void *)mb, MAILBOX_CMD_BSIZE); 2763 mb->un.varUnregVpi.vpi = port->vpi; 2764 mb->mbxCommand = MBX_UNREG_VPI; 2765 mb->mbxOwner = OWN_HOST; 2766 2767 mbq->mbox_cmpl = emlxs_unreg_vpi_mbcmpl; 2768 mbq->context = NULL; 2769 mbq->port = (void *)port; 2770 2771 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 2772 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 2773 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2774 "unreg_vpi:%d failed. Unable to send request.", 2775 port->vpi); 2776 2777 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 2778 return (1); 2779 } 2780 2781 return (0); 2782 2783 } /* emlxs_mb_unreg_vpi() */ 2784 2785 2786 /* 2787 * emlxs_mb_config_farp Issue a CONFIG FARP mailbox command 2788 */ 2789 extern void 2790 emlxs_mb_config_farp(emlxs_hba_t *hba, MAILBOXQ *mbq) 2791 { 2792 MAILBOX *mb = (MAILBOX *)mbq; 2793 2794 bzero((void *)mb, MAILBOX_CMD_BSIZE); 2795 2796 bcopy((uint8_t *)&hba->wwpn, 2797 (uint8_t *)&mb->un.varCfgFarp.portname, sizeof (NAME_TYPE)); 2798 2799 bcopy((uint8_t *)&hba->wwpn, 2800 (uint8_t *)&mb->un.varCfgFarp.nodename, sizeof (NAME_TYPE)); 2801 2802 mb->un.varCfgFarp.filterEnable = 1; 2803 mb->un.varCfgFarp.portName = 1; 2804 mb->un.varCfgFarp.nodeName = 1; 2805 mb->mbxCommand = MBX_CONFIG_FARP; 2806 mb->mbxOwner = OWN_HOST; 2807 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 2808 mbq->port = (void *)&PPORT; 2809 2810 } /* emlxs_mb_config_farp() */ 2811 2812 2813 /* 2814 * emlxs_mb_read_nv Issue a READ CONFIG mailbox command 2815 */ 2816 /*ARGSUSED*/ 2817 extern void 2818 emlxs_mb_read_config(emlxs_hba_t *hba, MAILBOXQ *mbq) 2819 { 2820 MAILBOX *mb = (MAILBOX *)mbq; 2821 2822 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 2823 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 2824 mbq->nonembed = NULL; 2825 } else { 2826 bzero((void *)mb, MAILBOX_CMD_BSIZE); 2827 } 2828 2829 mb->mbxCommand = MBX_READ_CONFIG; 2830 mb->mbxOwner = OWN_HOST; 2831 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 2832 mbq->port = (void *)&PPORT; 2833 2834 } /* emlxs_mb_read_config() */ 2835 2836 2837 /* 2838 * NAME: emlxs_mb_put 2839 * 2840 * FUNCTION: put mailbox cmd onto the mailbox queue. 2841 * 2842 * EXECUTION ENVIRONMENT: process and interrupt level. 2843 * 2844 * NOTES: 2845 * 2846 * CALLED FROM: EMLXS_SLI_ISSUE_MBOX_CMD 2847 * 2848 * INPUT: hba - pointer to the device info area 2849 * mbp - pointer to mailbox queue entry of mailbox cmd 2850 * 2851 * RETURNS: NULL - command queued 2852 */ 2853 extern void 2854 emlxs_mb_put(emlxs_hba_t *hba, MAILBOXQ *mbq) 2855 { 2856 2857 mutex_enter(&EMLXS_MBOX_LOCK); 2858 2859 if (hba->mbox_queue.q_first) { 2860 2861 /* 2862 * queue command to end of list 2863 */ 2864 ((MAILBOXQ *)hba->mbox_queue.q_last)->next = mbq; 2865 hba->mbox_queue.q_last = (uint8_t *)mbq; 2866 hba->mbox_queue.q_cnt++; 2867 } else { 2868 2869 /* 2870 * add command to empty list 2871 */ 2872 hba->mbox_queue.q_first = (uint8_t *)mbq; 2873 hba->mbox_queue.q_last = (uint8_t *)mbq; 2874 hba->mbox_queue.q_cnt = 1; 2875 } 2876 2877 mbq->next = NULL; 2878 2879 mutex_exit(&EMLXS_MBOX_LOCK); 2880 } /* emlxs_mb_put() */ 2881 2882 2883 /* 2884 * NAME: emlxs_mb_get 2885 * 2886 * FUNCTION: get a mailbox command from mailbox command queue 2887 * 2888 * EXECUTION ENVIRONMENT: interrupt level. 2889 * 2890 * NOTES: 2891 * 2892 * CALLED FROM: emlxs_handle_mb_event 2893 * 2894 * INPUT: hba - pointer to the device info area 2895 * 2896 * RETURNS: NULL - no match found mb pointer - pointer to a mailbox command 2897 */ 2898 extern MAILBOXQ * 2899 emlxs_mb_get(emlxs_hba_t *hba) 2900 { 2901 MAILBOXQ *p_first = NULL; 2902 2903 mutex_enter(&EMLXS_MBOX_LOCK); 2904 2905 if (hba->mbox_queue.q_first) { 2906 p_first = (MAILBOXQ *)hba->mbox_queue.q_first; 2907 hba->mbox_queue.q_first = (uint8_t *)p_first->next; 2908 2909 if (hba->mbox_queue.q_first == NULL) { 2910 hba->mbox_queue.q_last = NULL; 2911 hba->mbox_queue.q_cnt = 0; 2912 } else { 2913 hba->mbox_queue.q_cnt--; 2914 } 2915 2916 p_first->next = NULL; 2917 } 2918 2919 mutex_exit(&EMLXS_MBOX_LOCK); 2920 2921 return (p_first); 2922 2923 } /* emlxs_mb_get() */ 2924 2925 2926 /* EMLXS_PORT_LOCK must be held when calling this */ 2927 void 2928 emlxs_mb_init(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t flag, uint32_t tmo) 2929 { 2930 MATCHMAP *mp; 2931 2932 HBASTATS.MboxIssued++; 2933 hba->mbox_queue_flag = flag; 2934 2935 /* Set the Mailbox timer */ 2936 if (hba->timer_tics) { 2937 hba->mbox_timer = hba->timer_tics + tmo; 2938 } else { 2939 hba->mbox_timer = DRV_TIME + tmo; 2940 } 2941 2942 /* Initialize mailbox */ 2943 mbq->flag &= MBQ_INIT_MASK; 2944 mbq->next = 0; 2945 2946 mutex_enter(&EMLXS_MBOX_LOCK); 2947 hba->mbox_mbq = (void *)mbq; 2948 mutex_exit(&EMLXS_MBOX_LOCK); 2949 2950 if (mbq->nonembed) { 2951 mp = (MATCHMAP *) mbq->nonembed; 2952 EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 2953 DDI_DMA_SYNC_FORDEV); 2954 } 2955 2956 if (mbq->bp) { 2957 mp = (MATCHMAP *) mbq->bp; 2958 EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 2959 DDI_DMA_SYNC_FORDEV); 2960 } 2961 return; 2962 2963 } /* emlxs_mb_init() */ 2964 2965 2966 extern void 2967 emlxs_mb_fini(emlxs_hba_t *hba, MAILBOX *mb, uint32_t mbxStatus) 2968 { 2969 emlxs_port_t *port = &PPORT; 2970 MATCHMAP *mbox_nonembed; 2971 MATCHMAP *mbox_bp; 2972 emlxs_buf_t *mbox_sbp; 2973 fc_unsol_buf_t *mbox_ubp; 2974 IOCBQ *mbox_iocbq; 2975 MAILBOXQ *mbox_mbq; 2976 MAILBOX *mbox; 2977 uint32_t mbox_queue_flag; 2978 2979 mutex_enter(&EMLXS_PORT_LOCK); 2980 2981 if (hba->mbox_queue_flag) { 2982 HBASTATS.MboxCompleted++; 2983 2984 if (mbxStatus != MBX_SUCCESS) { 2985 HBASTATS.MboxError++; 2986 } else { 2987 HBASTATS.MboxGood++; 2988 } 2989 } 2990 2991 mutex_enter(&EMLXS_MBOX_LOCK); 2992 mbox_queue_flag = hba->mbox_queue_flag; 2993 mbox_mbq = (MAILBOXQ *)hba->mbox_mbq; 2994 2995 if (mbox_mbq) { 2996 mbox_nonembed = (MATCHMAP *)mbox_mbq->nonembed; 2997 mbox_bp = (MATCHMAP *)mbox_mbq->bp; 2998 mbox_sbp = (emlxs_buf_t *)mbox_mbq->sbp; 2999 mbox_ubp = (fc_unsol_buf_t *)mbox_mbq->ubp; 3000 mbox_iocbq = (IOCBQ *)mbox_mbq->iocbq; 3001 } else { 3002 mbox_nonembed = NULL; 3003 mbox_bp = NULL; 3004 mbox_sbp = NULL; 3005 mbox_ubp = NULL; 3006 mbox_iocbq = NULL; 3007 } 3008 3009 hba->mbox_mbq = NULL; 3010 hba->mbox_queue_flag = 0; 3011 hba->mbox_timer = 0; 3012 mutex_exit(&EMLXS_MBOX_LOCK); 3013 3014 mutex_exit(&EMLXS_PORT_LOCK); 3015 3016 #ifdef SFCT_SUPPORT 3017 if (mb && mbox_sbp && mbox_sbp->fct_cmd) { 3018 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3019 "FCT mailbox: %s: status=%x", 3020 emlxs_mb_cmd_xlate(mb->mbxCommand), 3021 mb->mbxStatus); 3022 } 3023 #endif /* SFCT_SUPPORT */ 3024 3025 if (mbox_queue_flag == MBX_NOWAIT) { 3026 /* Check for deferred MBUF cleanup */ 3027 if (mbox_bp) { 3028 emlxs_mem_put(hba, MEM_BUF, (void *)mbox_bp); 3029 } 3030 if (mbox_nonembed) { 3031 emlxs_mem_put(hba, MEM_BUF, 3032 (void *)mbox_nonembed); 3033 } 3034 if (mbox_mbq) { 3035 emlxs_mem_put(hba, MEM_MBOX, 3036 (void *)mbox_mbq); 3037 } 3038 } else { /* MBX_WAIT */ 3039 if (mbox_mbq) { 3040 if (mb) { 3041 /* Copy the local mailbox provided back into */ 3042 /* the original mailbox */ 3043 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 3044 bcopy((uint32_t *)mb, 3045 (uint32_t *)mbox_mbq, 3046 MAILBOX_CMD_SLI4_BSIZE); 3047 } else { 3048 bcopy((uint32_t *)mb, 3049 (uint32_t *)mbox_mbq, 3050 MAILBOX_CMD_BSIZE); 3051 } 3052 } 3053 3054 mbox = (MAILBOX *)mbox_mbq; 3055 mbox->mbxStatus = (uint16_t)mbxStatus; 3056 3057 /* Mark mailbox complete */ 3058 mbox_mbq->flag |= MBQ_COMPLETED; 3059 } 3060 3061 /* Wake up the sleeping thread */ 3062 if (mbox_queue_flag == MBX_SLEEP) { 3063 mutex_enter(&EMLXS_MBOX_LOCK); 3064 cv_broadcast(&EMLXS_MBOX_CV); 3065 mutex_exit(&EMLXS_MBOX_LOCK); 3066 } 3067 } 3068 3069 emlxs_mb_deferred_cmpl(port, mbxStatus, mbox_sbp, mbox_ubp, mbox_iocbq); 3070 3071 return; 3072 3073 } /* emlxs_mb_fini() */ 3074 3075 3076 extern void 3077 emlxs_mb_deferred_cmpl(emlxs_port_t *port, uint32_t mbxStatus, emlxs_buf_t *sbp, 3078 fc_unsol_buf_t *ubp, IOCBQ *iocbq) 3079 { 3080 emlxs_hba_t *hba = HBA; 3081 emlxs_ub_priv_t *ub_priv; 3082 3083 #ifdef SFCT_SUPPORT 3084 if (sbp && sbp->fct_cmd && (sbp->fct_state == EMLXS_FCT_REG_PENDING)) { 3085 mutex_enter(&EMLXS_PKT_LOCK); 3086 sbp->fct_flags |= EMLXS_FCT_REGISTERED; 3087 cv_broadcast(&EMLXS_PKT_CV); 3088 mutex_exit(&EMLXS_PKT_LOCK); 3089 3090 sbp = NULL; 3091 } 3092 #endif /* SFCT_SUPPORT */ 3093 3094 /* Check for deferred pkt completion */ 3095 if (sbp) { 3096 if (mbxStatus != MBX_SUCCESS) { 3097 /* Set error status */ 3098 sbp->pkt_flags &= ~PACKET_STATE_VALID; 3099 emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 3100 IOERR_NO_RESOURCES, 1); 3101 } 3102 3103 emlxs_pkt_complete(sbp, -1, 0, 1); 3104 } 3105 3106 /* Check for deferred ub completion */ 3107 if (ubp) { 3108 ub_priv = ubp->ub_fca_private; 3109 3110 if (mbxStatus == MBX_SUCCESS) { 3111 emlxs_ub_callback(ub_priv->port, ubp); 3112 } else { 3113 (void) emlxs_fca_ub_release(ub_priv->port, 1, 3114 &ubp->ub_token); 3115 } 3116 } 3117 3118 /* Special handling for restricted login */ 3119 if (iocbq == (IOCBQ *)1) { 3120 iocbq = NULL; 3121 } 3122 3123 /* Check for deferred iocb tx */ 3124 if (iocbq) { 3125 /* Check for driver special codes */ 3126 /* These indicate the mailbox is being flushed */ 3127 if (mbxStatus >= MBX_DRIVER_RESERVED) { 3128 /* Set the error status and return it */ 3129 iocbq->iocb.ULPSTATUS = IOSTAT_LOCAL_REJECT; 3130 iocbq->iocb.un.grsp.perr.statLocalError = 3131 IOERR_ABORT_REQUESTED; 3132 3133 emlxs_proc_channel_event(hba, iocbq->channel, 3134 iocbq); 3135 } else { 3136 EMLXS_SLI_ISSUE_IOCB_CMD(hba, iocbq->channel, 3137 iocbq); 3138 } 3139 } 3140 3141 return; 3142 3143 } /* emlxs_mb_deferred_cmpl() */ 3144 3145 3146 extern void 3147 emlxs_mb_flush(emlxs_hba_t *hba) 3148 { 3149 MAILBOXQ *mbq; 3150 uint32_t mbxStatus; 3151 3152 mbxStatus = (hba->flag & FC_HARDWARE_ERROR) ? 3153 MBX_HARDWARE_ERROR : MBX_NOT_FINISHED; 3154 3155 /* Flush out the active mbox command */ 3156 emlxs_mb_fini(hba, NULL, mbxStatus); 3157 3158 /* Flush out the queued mbox commands */ 3159 while (mbq = (MAILBOXQ *)emlxs_mb_get(hba)) { 3160 mutex_enter(&EMLXS_MBOX_LOCK); 3161 hba->mbox_queue_flag = MBX_NOWAIT; 3162 hba->mbox_mbq = (void *)mbq; 3163 mutex_exit(&EMLXS_MBOX_LOCK); 3164 3165 emlxs_mb_fini(hba, NULL, mbxStatus); 3166 } 3167 3168 return; 3169 3170 } /* emlxs_mb_flush */ 3171 3172 3173 extern char * 3174 emlxs_mb_cmd_xlate(uint8_t cmd) 3175 { 3176 static char buffer[32]; 3177 uint32_t i; 3178 uint32_t count; 3179 3180 count = sizeof (emlxs_mb_cmd_table) / sizeof (emlxs_table_t); 3181 for (i = 0; i < count; i++) { 3182 if (cmd == emlxs_mb_cmd_table[i].code) { 3183 return (emlxs_mb_cmd_table[i].string); 3184 } 3185 } 3186 3187 (void) snprintf(buffer, sizeof (buffer), "Cmd=0x%x", cmd); 3188 return (buffer); 3189 3190 } /* emlxs_mb_cmd_xlate() */ 3191 3192 extern char * 3193 emlxs_request_feature_xlate(uint32_t mask) 3194 { 3195 static char buffer[64]; 3196 uint32_t i; 3197 3198 bzero((char *)&buffer[0], 64); 3199 for (i = 0; i < 12; i++) { 3200 if (mask & (1<<i)) { 3201 (void) strlcat(buffer, 3202 emlxs_request_feature_table[i].string, 3203 sizeof (buffer)); 3204 } 3205 } 3206 return (buffer); 3207 } 3208