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 Emulex. All rights reserved. 24 * Use is subject to License terms. 25 */ 26 27 #define EMLXS_FW_TABLE_DEF 28 #define EMLXS_MODEL_DEF 29 30 #include <emlxs.h> 31 32 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 33 EMLXS_MSG_DEF(EMLXS_HBA_C); 34 35 static uint32_t emlxs_decode_biu_rev(uint32_t rev); 36 static uint32_t emlxs_decode_endec_rev(uint32_t rev); 37 static void emlxs_parse_prog_types(emlxs_hba_t *hba, char *types); 38 static int32_t emlxs_parse_vpd(emlxs_hba_t *hba, uint8_t *vpd, 39 uint32_t size); 40 static void emlxs_build_prog_types(emlxs_hba_t *hba, char *prog_types); 41 static void emlxs_handle_async_event(emlxs_hba_t *hba, RING *rp, 42 IOCBQ *iocbq); 43 static void emlxs_process_link_speed(emlxs_hba_t *hba); 44 static void emlxs_decode_label(char *label, char *buffer); 45 46 #ifdef MODFW_SUPPORT 47 static void emlxs_fw_load(emlxs_hba_t *hba, emlxs_firmware_t *fw); 48 static void emlxs_fw_unload(emlxs_hba_t *hba, emlxs_firmware_t *fw); 49 #endif /* MODFW_SUPPORT */ 50 51 #ifdef MSI_SUPPORT 52 uint32_t emlxs_msi_map[EMLXS_MSI_MODES][EMLXS_MSI_MAX_INTRS] = 53 {EMLXS_MSI_MAP1, EMLXS_MSI_MAP2, EMLXS_MSI_MAP4, EMLXS_MSI_MAP8}; 54 uint32_t emlxs_msi_mask[EMLXS_MSI_MODES] = 55 {EMLXS_MSI0_MASK1, EMLXS_MSI0_MASK2, EMLXS_MSI0_MASK4, 56 EMLXS_MSI0_MASK8}; 57 #endif /* MSI_SUPPORT */ 58 59 60 static uint32_t emlxs_disable_traffic_cop = 1; 61 62 emlxs_table_t emlxs_ring_table[] = { 63 {FC_FCP_RING, "FCP Ring"}, 64 {FC_IP_RING, "IP Ring"}, 65 {FC_ELS_RING, "ELS Ring"}, 66 {FC_CT_RING, "CT Ring"} 67 68 }; /* emlxs_ring_table */ 69 70 71 emlxs_table_t emlxs_ffstate_table[] = { 72 {0, "NULL"}, 73 {FC_ERROR, "ERROR"}, 74 {FC_KILLED, "KILLED"}, 75 {FC_WARM_START, "WARM_START"}, 76 {FC_INIT_START, "INIT_START"}, 77 {FC_INIT_NVPARAMS, "INIT_NVPARAMS"}, 78 {FC_INIT_REV, "INIT_REV"}, 79 {FC_INIT_CFGPORT, "INIT_CFGPORT"}, 80 {FC_INIT_CFGRING, "INIT_CFGRING"}, 81 {FC_INIT_INITLINK, "INIT_INITLINK"}, 82 {FC_LINK_DOWN, "LINK_DOWN"}, 83 {FC_LINK_UP, "LINK_UP"}, 84 {FC_CLEAR_LA, "CLEAR_LA"}, 85 {FC_READY, "READY"} 86 87 }; /* emlxs_ffstate_table */ 88 89 90 /* 91 * emlxs_ffinit() 92 * 93 * This routine will start initialization of the FireFly Chipset 94 */ 95 extern int 96 emlxs_ffinit(emlxs_hba_t *hba) 97 { 98 emlxs_port_t *port = &PPORT; 99 emlxs_config_t *cfg; 100 emlxs_vpd_t *vpd; 101 MAILBOX *mb; 102 RING *rp; 103 MATCHMAP *mp; 104 MATCHMAP *mp1; 105 uint8_t *inptr; 106 uint8_t *outptr; 107 uint32_t status; 108 uint32_t i; 109 uint32_t j; 110 uint32_t read_rev_reset; 111 uint32_t key = 0; 112 uint32_t fw_check; 113 uint32_t rval; 114 uint32_t offset; 115 uint8_t vpd_data[DMP_VPD_SIZE]; 116 uint32_t MaxRbusSize; 117 uint32_t MaxIbusSize; 118 uint32_t sli_mode; 119 uint32_t sli_mode_mask; 120 121 cfg = &CFG; 122 vpd = &VPD; 123 mb = 0; 124 MaxRbusSize = 0; 125 MaxIbusSize = 0; 126 read_rev_reset = 0; 127 128 if (hba->bus_type == SBUS_FC) { 129 (void) READ_SBUS_CSR_REG(hba, FC_SHS_REG(hba, 130 hba->sbus_csr_addr)); 131 #ifdef FMA_SUPPORT 132 if (emlxs_fm_check_acc_handle(hba, hba->sbus_csr_handle) 133 != DDI_FM_OK) { 134 EMLXS_MSGF(EMLXS_CONTEXT, 135 &emlxs_invalid_access_handle_msg, NULL); 136 return (EIO); 137 } 138 #endif /* FMA_SUPPORT */ 139 } 140 141 #ifdef SLI3_SUPPORT 142 /* Initialize sli mode based on configuration parameter */ 143 switch (cfg[CFG_SLI_MODE].current) { 144 case 2: /* SLI2 mode */ 145 sli_mode = EMLXS_HBA_SLI2_MODE; 146 sli_mode_mask = EMLXS_SLI2_MASK; 147 break; 148 149 case 3: /* SLI3 mode */ 150 sli_mode = EMLXS_HBA_SLI3_MODE; 151 sli_mode_mask = EMLXS_SLI3_MASK; 152 break; 153 154 case 0: /* Best available */ 155 case 1: /* Best available */ 156 default: 157 if (hba->model_info.sli_mask & EMLXS_SLI4_MASK) { 158 sli_mode = EMLXS_HBA_SLI4_MODE; 159 sli_mode_mask = EMLXS_SLI4_MASK; 160 } else if (hba->model_info.sli_mask & EMLXS_SLI3_MASK) { 161 sli_mode = EMLXS_HBA_SLI3_MODE; 162 sli_mode_mask = EMLXS_SLI3_MASK; 163 } else if (hba->model_info.sli_mask & EMLXS_SLI2_MASK) { 164 sli_mode = EMLXS_HBA_SLI2_MODE; 165 sli_mode_mask = EMLXS_SLI2_MASK; 166 } 167 } 168 /* SBUS adapters only available in SLI2 */ 169 if (hba->bus_type == SBUS_FC) { 170 sli_mode = EMLXS_HBA_SLI2_MODE; 171 sli_mode_mask = EMLXS_SLI2_MASK; 172 } 173 174 #endif /* SLI3_SUPPORT */ 175 176 /* Set the fw_check flag */ 177 fw_check = cfg[CFG_FW_CHECK].current; 178 179 hba->mbox_queue_flag = 0; 180 hba->hc_copy = 0; 181 hba->fc_edtov = FF_DEF_EDTOV; 182 hba->fc_ratov = FF_DEF_RATOV; 183 hba->fc_altov = FF_DEF_ALTOV; 184 hba->fc_arbtov = FF_DEF_ARBTOV; 185 186 reset: 187 188 /* Reset and initialize the adapter */ 189 if (emlxs_sli_online(hba)) { 190 return (EIO); 191 } 192 193 #ifdef FMA_SUPPORT 194 /* Access handle validation */ 195 if ((emlxs_fm_check_acc_handle(hba, hba->pci_acc_handle) 196 != DDI_FM_OK) || 197 (emlxs_fm_check_acc_handle(hba, hba->slim_acc_handle) 198 != DDI_FM_OK) || 199 (emlxs_fm_check_acc_handle(hba, hba->csr_acc_handle) 200 != DDI_FM_OK)) { 201 EMLXS_MSGF(EMLXS_CONTEXT, 202 &emlxs_invalid_access_handle_msg, NULL); 203 return (EIO); 204 } 205 #endif /* FMA_SUPPORT */ 206 207 /* 208 * Allocate some memory for buffers 209 */ 210 if (emlxs_mem_alloc_buffer(hba) == 0) { 211 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 212 "Unable to allocate memory buffers."); 213 214 emlxs_ffstate_change(hba, FC_ERROR); 215 216 return (ENOMEM); 217 } 218 219 /* 220 * Get a buffer which will be used repeatedly for mailbox commands 221 */ 222 if ((mb = (MAILBOX *) emlxs_mem_get(hba, MEM_MBOX | MEM_PRI)) == 0) { 223 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 224 "Unable to allocate mailbox buffer."); 225 226 emlxs_ffstate_change(hba, FC_ERROR); 227 (void) emlxs_mem_free_buffer(hba); 228 229 return (ENOMEM); 230 } 231 232 /* Check for the LP9802 (This is a special case) */ 233 /* We need to check for dual channel adapter */ 234 if (hba->model_info.device_id == PCI_DEVICE_ID_LP9802) { 235 /* Try to determine if this is a DC adapter */ 236 if (emlxs_get_max_sram(hba, &MaxRbusSize, &MaxIbusSize) == 0) { 237 if (MaxRbusSize == REDUCED_SRAM_CFG) { 238 /* LP9802DC */ 239 for (i = 1; i < EMLXS_PCI_MODEL_COUNT; i++) { 240 if (emlxs_pci_model[i].id == LP9802DC) { 241 bcopy(&emlxs_pci_model[i], 242 &hba->model_info, 243 sizeof (emlxs_model_t)); 244 break; 245 } 246 } 247 } else if (hba->model_info.id != LP9802) { 248 /* LP9802 */ 249 for (i = 1; i < EMLXS_PCI_MODEL_COUNT; i++) { 250 if (emlxs_pci_model[i].id == LP9802) { 251 bcopy(&emlxs_pci_model[i], 252 &hba->model_info, 253 sizeof (emlxs_model_t)); 254 break; 255 } 256 } 257 } 258 } 259 } 260 261 /* 262 * Setup and issue mailbox READ REV command 263 */ 264 vpd->opFwRev = 0; 265 vpd->postKernRev = 0; 266 vpd->sli1FwRev = 0; 267 vpd->sli2FwRev = 0; 268 vpd->sli3FwRev = 0; 269 vpd->sli4FwRev = 0; 270 271 vpd->postKernName[0] = 0; 272 vpd->opFwName[0] = 0; 273 vpd->sli1FwName[0] = 0; 274 vpd->sli2FwName[0] = 0; 275 vpd->sli3FwName[0] = 0; 276 vpd->sli4FwName[0] = 0; 277 278 vpd->opFwLabel[0] = 0; 279 vpd->sli1FwLabel[0] = 0; 280 vpd->sli2FwLabel[0] = 0; 281 vpd->sli3FwLabel[0] = 0; 282 vpd->sli4FwLabel[0] = 0; 283 284 emlxs_ffstate_change(hba, FC_INIT_REV); 285 emlxs_mb_read_rev(hba, mb, 0); 286 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 287 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 288 "Unable to read rev. Mailbox cmd=%x status=%x", 289 mb->mbxCommand, mb->mbxStatus); 290 291 emlxs_ffstate_change(hba, FC_ERROR); 292 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 293 (void) emlxs_mem_free_buffer(hba); 294 295 return (EIO); 296 } 297 298 if (mb->un.varRdRev.rr == 0) { 299 /* Old firmware */ 300 if (read_rev_reset == 0) { 301 /* Clean up */ 302 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 303 (void) emlxs_mem_free_buffer(hba); 304 305 read_rev_reset = 1; 306 307 goto reset; 308 } else { 309 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 310 "Outdated firmware detected."); 311 } 312 313 vpd->rBit = 0; 314 } else { 315 if (mb->un.varRdRev.un.b.ProgType != FUNC_FIRMWARE) { 316 if (read_rev_reset == 0) { 317 /* Clean up */ 318 (void) emlxs_mem_put(hba, MEM_MBOX, 319 (uint8_t *)mb); 320 (void) emlxs_mem_free_buffer(hba); 321 322 read_rev_reset = 1; 323 324 goto reset; 325 } else { 326 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 327 "Non-operational firmware detected. " 328 "type=%x", 329 mb->un.varRdRev.un.b.ProgType); 330 } 331 } 332 333 vpd->rBit = 1; 334 vpd->sli1FwRev = mb->un.varRdRev.sliFwRev1; 335 bcopy((char *)mb->un.varRdRev.sliFwName1, vpd->sli1FwLabel, 336 16); 337 vpd->sli2FwRev = mb->un.varRdRev.sliFwRev2; 338 bcopy((char *)mb->un.varRdRev.sliFwName2, vpd->sli2FwLabel, 339 16); 340 341 /* 342 * Lets try to read the SLI3 version 343 * Setup and issue mailbox READ REV(v3) command 344 */ 345 emlxs_ffstate_change(hba, FC_INIT_REV); 346 emlxs_mb_read_rev(hba, mb, 1); 347 348 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 349 MBX_SUCCESS) { 350 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 351 "Unable to read rev (v3). Mailbox cmd=%x status=%x", 352 mb->mbxCommand, mb->mbxStatus); 353 354 emlxs_ffstate_change(hba, FC_ERROR); 355 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 356 (void) emlxs_mem_free_buffer(hba); 357 358 return (EIO); 359 } 360 361 if (mb->un.varRdRev.rf3) { 362 /* 363 * vpd->sli2FwRev = mb->un.varRdRev.sliFwRev1; 364 * Not needed 365 */ 366 vpd->sli3FwRev = mb->un.varRdRev.sliFwRev2; 367 bcopy((char *)mb->un.varRdRev.sliFwName2, 368 vpd->sli3FwLabel, 16); 369 } 370 } 371 372 373 if ((sli_mode == EMLXS_HBA_SLI3_MODE) && (vpd->sli3FwRev == 0)) { 374 if (vpd->sli2FwRev) { 375 sli_mode = EMLXS_HBA_SLI2_MODE; 376 sli_mode_mask = EMLXS_SLI2_MASK; 377 } else { 378 sli_mode = 0; 379 sli_mode_mask = 0; 380 } 381 } 382 383 else if ((sli_mode == EMLXS_HBA_SLI2_MODE) && (vpd->sli2FwRev == 0)) { 384 if (vpd->sli3FwRev) { 385 sli_mode = EMLXS_HBA_SLI3_MODE; 386 sli_mode_mask = EMLXS_SLI3_MASK; 387 } else { 388 sli_mode = 0; 389 sli_mode_mask = 0; 390 } 391 } 392 393 if (!(hba->model_info.sli_mask & sli_mode_mask)) { 394 #ifdef SLI3_SUPPORT 395 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 396 "Firmware not available. sli-mode=%d", 397 cfg[CFG_SLI_MODE].current); 398 #else 399 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 400 "Firmware not available. sli-mode=2"); 401 #endif /* SLI3_SUPPORT */ 402 403 emlxs_ffstate_change(hba, FC_ERROR); 404 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 405 (void) emlxs_mem_free_buffer(hba); 406 407 return (EIO); 408 } 409 410 /* Save information as VPD data */ 411 vpd->postKernRev = mb->un.varRdRev.postKernRev; 412 vpd->opFwRev = mb->un.varRdRev.opFwRev; 413 bcopy((char *)mb->un.varRdRev.opFwName, vpd->opFwLabel, 16); 414 vpd->biuRev = mb->un.varRdRev.biuRev; 415 vpd->smRev = mb->un.varRdRev.smRev; 416 vpd->smFwRev = mb->un.varRdRev.un.smFwRev; 417 vpd->endecRev = mb->un.varRdRev.endecRev; 418 vpd->fcphHigh = mb->un.varRdRev.fcphHigh; 419 vpd->fcphLow = mb->un.varRdRev.fcphLow; 420 vpd->feaLevelHigh = mb->un.varRdRev.feaLevelHigh; 421 vpd->feaLevelLow = mb->un.varRdRev.feaLevelLow; 422 423 /* Decode FW names */ 424 emlxs_decode_version(vpd->postKernRev, vpd->postKernName); 425 emlxs_decode_version(vpd->opFwRev, vpd->opFwName); 426 emlxs_decode_version(vpd->sli1FwRev, vpd->sli1FwName); 427 emlxs_decode_version(vpd->sli2FwRev, vpd->sli2FwName); 428 emlxs_decode_version(vpd->sli3FwRev, vpd->sli3FwName); 429 emlxs_decode_version(vpd->sli4FwRev, vpd->sli4FwName); 430 431 /* Decode FW labels */ 432 emlxs_decode_label(vpd->opFwLabel, vpd->opFwLabel); 433 emlxs_decode_label(vpd->sli1FwLabel, vpd->sli1FwLabel); 434 emlxs_decode_label(vpd->sli2FwLabel, vpd->sli2FwLabel); 435 emlxs_decode_label(vpd->sli3FwLabel, vpd->sli3FwLabel); 436 emlxs_decode_label(vpd->sli4FwLabel, vpd->sli4FwLabel); 437 438 key = emlxs_get_key(hba, mb); 439 440 /* Get adapter VPD information */ 441 offset = 0; 442 bzero(vpd_data, sizeof (vpd_data)); 443 vpd->port_index = (uint32_t)-1; 444 445 while (offset < DMP_VPD_SIZE) { 446 emlxs_mb_dump_vpd(hba, mb, offset); 447 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 448 MBX_SUCCESS) { 449 /* 450 * Let it go through even if failed. 451 * Not all adapter's have VPD info and thus will 452 * fail here. This is not a problem 453 */ 454 455 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 456 "No VPD found. offset=%x status=%x", offset, 457 mb->mbxStatus); 458 break; 459 } else { 460 if (mb->un.varDmp.ra == 1) { 461 uint32_t *lp1, *lp2; 462 uint32_t bsize; 463 uint32_t wsize; 464 465 /* 466 * mb->un.varDmp.word_cnt is actually byte 467 * count for the dump reply 468 */ 469 bsize = mb->un.varDmp.word_cnt; 470 471 /* Stop if no data was received */ 472 if (bsize == 0) { 473 break; 474 } 475 476 /* Check limit on byte size */ 477 bsize = (bsize > 478 (sizeof (vpd_data) - offset)) ? 479 (sizeof (vpd_data) - offset) : bsize; 480 481 /* 482 * Convert size from bytes to words with 483 * minimum of 1 word 484 */ 485 wsize = (bsize > 4) ? (bsize >> 2) : 1; 486 487 /* 488 * Transfer data into vpd_data buffer one 489 * word at a time 490 */ 491 lp1 = (uint32_t *)&mb->un.varDmp.resp_offset; 492 lp2 = (uint32_t *)&vpd_data[offset]; 493 494 for (i = 0; i < wsize; i++) { 495 status = *lp1++; 496 *lp2++ = SWAP_LONG(status); 497 } 498 499 /* Increment total byte count saved */ 500 offset += (wsize << 2); 501 502 /* 503 * Stop if less than a full transfer was 504 * received 505 */ 506 if (wsize < DMP_VPD_DUMP_WCOUNT) { 507 break; 508 } 509 510 } else { 511 EMLXS_MSGF(EMLXS_CONTEXT, 512 &emlxs_init_debug_msg, 513 "No VPD acknowledgment. offset=%x", 514 offset); 515 break; 516 } 517 } 518 519 } 520 521 if (vpd_data[0]) { 522 (void) emlxs_parse_vpd(hba, (uint8_t *)vpd_data, offset); 523 524 /* 525 * If there is a VPD part number, and it does not 526 * match the current default HBA model info, 527 * replace the default data with an entry that 528 * does match. 529 * 530 * After emlxs_parse_vpd model holds the VPD value 531 * for V2 and part_num hold the value for PN. These 532 * 2 values are NOT necessarily the same. 533 */ 534 535 rval = 0; 536 if ((vpd->model[0] != 0) && 537 (strcmp(&vpd->model[0], hba->model_info.model) != 0)) { 538 539 /* First scan for a V2 match */ 540 541 for (i = 1; i < EMLXS_PCI_MODEL_COUNT; i++) { 542 if (strcmp(&vpd->model[0], 543 emlxs_pci_model[i].model) == 0) { 544 bcopy(&emlxs_pci_model[i], 545 &hba->model_info, 546 sizeof (emlxs_model_t)); 547 rval = 1; 548 break; 549 } 550 } 551 } 552 553 if (!rval && (vpd->part_num[0] != 0) && 554 (strcmp(&vpd->part_num[0], hba->model_info.model) != 0)) { 555 556 /* Next scan for a PN match */ 557 558 for (i = 1; i < EMLXS_PCI_MODEL_COUNT; i++) { 559 if (strcmp(&vpd->part_num[0], 560 emlxs_pci_model[i].model) == 0) { 561 bcopy(&emlxs_pci_model[i], 562 &hba->model_info, 563 sizeof (emlxs_model_t)); 564 break; 565 } 566 } 567 } 568 569 /* 570 * Now lets update hba->model_info with the real 571 * VPD data, if any. 572 */ 573 574 /* 575 * Replace the default model description with vpd data 576 */ 577 if (vpd->model_desc[0] != 0) { 578 (void) strcpy(hba->model_info.model_desc, 579 vpd->model_desc); 580 } 581 582 /* Replace the default model with vpd data */ 583 if (vpd->model[0] != 0) { 584 (void) strcpy(hba->model_info.model, vpd->model); 585 } 586 587 /* Replace the default program types with vpd data */ 588 if (vpd->prog_types[0] != 0) { 589 emlxs_parse_prog_types(hba, vpd->prog_types); 590 } 591 } 592 593 /* 594 * Since the adapter model may have changed with the vpd data 595 * lets double check if adapter is not supported 596 */ 597 if (hba->model_info.flags & EMLXS_NOT_SUPPORTED) { 598 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 599 "Unsupported adapter found. " 600 "Id:%d Device id:0x%x SSDID:0x%x Model:%s", 601 hba->model_info.id, hba->model_info.device_id, 602 hba->model_info.ssdid, hba->model_info.model); 603 604 emlxs_ffstate_change(hba, FC_ERROR); 605 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 606 (void) emlxs_mem_free_buffer(hba); 607 608 return (EIO); 609 } 610 611 /* Read the adapter's wakeup parms */ 612 (void) emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1); 613 emlxs_decode_version(hba->wakeup_parms.u0.boot_bios_wd[0], 614 vpd->boot_version); 615 616 /* Get fcode version property */ 617 emlxs_get_fcode_version(hba); 618 619 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 620 "Firmware: kern=%08x stub=%08x sli1=%08x", vpd->postKernRev, 621 vpd->opFwRev, vpd->sli1FwRev); 622 623 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 624 "Firmware: sli2=%08x sli3=%08x sli4=%08x fl=%x", vpd->sli2FwRev, 625 vpd->sli3FwRev, vpd->sli4FwRev, vpd->feaLevelHigh); 626 627 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 628 "BIOS: boot=%s fcode=%s", vpd->boot_version, vpd->fcode_version); 629 630 /* 631 * If firmware checking is enabled and the adapter model indicates 632 * a firmware image, then perform firmware version check 633 */ 634 if (((fw_check == 1) && (hba->model_info.flags & EMLXS_SUN_BRANDED) && 635 hba->model_info.fwid) || ((fw_check == 2) && 636 hba->model_info.fwid)) { 637 emlxs_firmware_t *fw; 638 639 /* Find firmware image indicated by adapter model */ 640 fw = NULL; 641 for (i = 0; i < EMLXS_FW_COUNT; i++) { 642 if (emlxs_fw_table[i].id == hba->model_info.fwid) { 643 fw = &emlxs_fw_table[i]; 644 break; 645 } 646 } 647 648 /* 649 * If the image was found, then verify current firmware 650 * versions of adapter 651 */ 652 if (fw) { 653 if ((vpd->postKernRev != fw->kern) || 654 (vpd->opFwRev != fw->stub) || 655 (vpd->sli1FwRev != fw->sli1) || 656 (vpd->sli2FwRev != fw->sli2) || 657 (fw->sli3 && (vpd->sli3FwRev != fw->sli3)) || 658 (fw->sli4 && (vpd->sli4FwRev != fw->sli4))) { 659 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 660 "Firmware update needed. " 661 "Updating. id=%d fw=%d", 662 hba->model_info.id, hba->model_info.fwid); 663 664 #ifdef MODFW_SUPPORT 665 /* 666 * Load the firmware image now 667 * If MODFW_SUPPORT is not defined, the 668 * firmware image will already be defined 669 * in the emlxs_fw_table 670 */ 671 emlxs_fw_load(hba, fw); 672 #endif /* MODFW_SUPPORT */ 673 674 if (fw->image && fw->size) { 675 if (emlxs_fw_download(hba, 676 (char *)fw->image, fw->size, 0)) { 677 EMLXS_MSGF(EMLXS_CONTEXT, 678 &emlxs_init_msg, 679 "Firmware update failed."); 680 } 681 #ifdef MODFW_SUPPORT 682 /* 683 * Unload the firmware image from 684 * kernel memory 685 */ 686 emlxs_fw_unload(hba, fw); 687 #endif /* MODFW_SUPPORT */ 688 689 (void) emlxs_mem_put(hba, MEM_MBOX, 690 (uint8_t *)mb); 691 (void) emlxs_mem_free_buffer(hba); 692 693 fw_check = 0; 694 695 goto reset; 696 } 697 698 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 699 "Firmware image unavailable."); 700 } 701 } else { 702 /* This should not happen */ 703 704 /* 705 * This means either the adapter database is not 706 * correct or a firmware image is missing from the 707 * compile 708 */ 709 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 710 "Firmware image unavailable. id=%d fw=%d", 711 hba->model_info.id, hba->model_info.fwid); 712 } 713 } 714 715 /* 716 * Add our interrupt routine to kernel's interrupt chain & enable it 717 * If MSI is enabled this will cause Solaris to program the MSI address 718 * and data registers in PCI config space 719 */ 720 if (EMLXS_INTR_ADD(hba) != DDI_SUCCESS) { 721 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 722 "Unable to add interrupt(s)."); 723 724 emlxs_ffstate_change(hba, FC_ERROR); 725 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 726 (void) emlxs_mem_free_buffer(hba); 727 728 return (EIO); 729 } 730 731 emlxs_ffstate_change(hba, FC_INIT_CFGPORT); 732 (void) emlxs_mb_config_port(hba, mb, sli_mode, key); 733 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 734 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 735 "Unable to configure port. " 736 "Mailbox cmd=%x status=%x slimode=%d key=%x", 737 mb->mbxCommand, mb->mbxStatus, sli_mode, key); 738 739 #ifdef SLI3_SUPPORT 740 for (sli_mode--; sli_mode > 0; sli_mode--) { 741 /* Check if sli_mode is supported by this adapter */ 742 if (hba->model_info.sli_mask & 743 EMLXS_SLI_MASK(sli_mode)) { 744 sli_mode_mask = EMLXS_SLI_MASK(sli_mode); 745 break; 746 } 747 } 748 749 if (sli_mode) { 750 /* Clean up */ 751 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 752 (void) emlxs_mem_free_buffer(hba); 753 754 fw_check = 0; 755 756 goto reset; 757 } 758 #endif /* SLI3_SUPPORT */ 759 760 hba->flag &= ~FC_SLIM2_MODE; 761 emlxs_ffstate_change(hba, FC_ERROR); 762 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 763 (void) emlxs_mem_free_buffer(hba); 764 765 return (EIO); 766 } 767 #ifdef SLI3_SUPPORT 768 /* Check if SLI3 mode was achieved */ 769 if (mb->un.varCfgPort.rMA && 770 (mb->un.varCfgPort.sli_mode == EMLXS_HBA_SLI3_MODE)) { 771 772 #ifdef NPIV_SUPPORT 773 if (mb->un.varCfgPort.vpi_max > 1) { 774 hba->flag |= FC_NPIV_ENABLED; 775 776 if (hba->model_info.chip >= EMLXS_SATURN_CHIP) { 777 hba->vpi_max = 778 min(mb->un.varCfgPort.vpi_max, 779 MAX_VPORTS - 1); 780 } else { 781 hba->vpi_max = 782 min(mb->un.varCfgPort.vpi_max, 783 MAX_VPORTS_LIMITED - 1); 784 } 785 } 786 787 #if (EMLXS_MODREV >= EMLXS_MODREV5) 788 hba->fca_tran->fca_num_npivports = 789 (cfg[CFG_NPIV_ENABLE].current) ? hba->vpi_max : 0; 790 #endif /* >= EMLXS_MODREV5 */ 791 792 #endif /* NPIV_SUPPORT */ 793 794 if (mb->un.varCfgPort.gerbm && mb->un.varCfgPort.max_hbq) { 795 hba->flag |= FC_HBQ_ENABLED; 796 } 797 798 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 799 "SLI3 mode: flag=%x vpi_max=%d", hba->flag, hba->vpi_max); 800 } else { 801 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 802 "SLI2 mode: flag=%x", hba->flag); 803 sli_mode = EMLXS_HBA_SLI2_MODE; 804 sli_mode_mask = EMLXS_SLI2_MASK; 805 hba->sli_mode = sli_mode; 806 } 807 #endif /* SLI3_SUPPORT */ 808 809 /* Get and save the current firmware version (based on sli_mode) */ 810 emlxs_decode_firmware_rev(hba, vpd); 811 812 emlxs_pcix_mxr_update(hba, 0); 813 814 /* 815 * Setup and issue mailbox RUN BIU DIAG command Setup test buffers 816 */ 817 mp = 0; 818 mp1 = 0; 819 if (((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF | MEM_PRI)) == 0) || 820 ((mp1 = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF | MEM_PRI)) == 0)) { 821 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 822 "Unable to allocate diag buffers."); 823 824 emlxs_ffstate_change(hba, FC_ERROR); 825 826 if (mp) { 827 (void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp); 828 } 829 if (mp1) { 830 (void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp1); 831 } 832 833 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 834 (void) emlxs_mem_free_buffer(hba); 835 836 return (ENOMEM); 837 } 838 839 bcopy((caddr_t)&emlxs_diag_pattern[0], (caddr_t)mp->virt, 840 MEM_ELSBUF_SIZE); 841 emlxs_mpdata_sync(mp->dma_handle, 0, MEM_ELSBUF_SIZE, 842 DDI_DMA_SYNC_FORDEV); 843 844 bzero(mp1->virt, MEM_ELSBUF_SIZE); 845 emlxs_mpdata_sync(mp1->dma_handle, 0, MEM_ELSBUF_SIZE, 846 DDI_DMA_SYNC_FORDEV); 847 848 (void) emlxs_mb_run_biu_diag(hba, mb, mp->phys, mp1->phys); 849 850 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 851 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 852 "Unable to run BIU diag. Mailbox cmd=%x status=%x", 853 mb->mbxCommand, mb->mbxStatus); 854 855 emlxs_ffstate_change(hba, FC_ERROR); 856 857 (void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp); 858 (void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp1); 859 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 860 (void) emlxs_mem_free_buffer(hba); 861 862 return (EIO); 863 } 864 865 emlxs_mpdata_sync(mp1->dma_handle, 0, MEM_ELSBUF_SIZE, 866 DDI_DMA_SYNC_FORKERNEL); 867 868 outptr = mp->virt; 869 inptr = mp1->virt; 870 871 for (i = 0; i < MEM_ELSBUF_SIZE; i++) { 872 if (*outptr++ != *inptr++) { 873 outptr--; 874 inptr--; 875 876 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 877 "BIU diagnostic failed. " 878 "offset %x value %x should be %x.", 879 i, (uint32_t)*inptr, (uint32_t)*outptr); 880 881 emlxs_ffstate_change(hba, FC_ERROR); 882 883 (void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp); 884 (void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp1); 885 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 886 (void) emlxs_mem_free_buffer(hba); 887 888 return (EIO); 889 } 890 } 891 892 (void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp); 893 (void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp1); 894 895 /* 896 * Setup and issue mailbox CONFIGURE RING command 897 */ 898 for (i = 0; i < (uint32_t)hba->ring_count; i++) { 899 /* 900 * Initialize cmd/rsp ring pointers 901 */ 902 rp = &hba->ring[i]; 903 904 rp->hba = hba; 905 rp->ringno = (uint8_t)i; 906 907 rp->fc_iocbhd = 0; 908 rp->fc_iocbtl = 0; 909 rp->fc_cmdidx = 0; 910 rp->fc_rspidx = 0; 911 rp->fc_iotag = 1; /* Used for pkt io */ 912 rp->fc_abort_iotag = rp->max_iotag; /* Used for abort or */ 913 /* close XRI iotags */ 914 emlxs_ffstate_change(hba, FC_INIT_CFGRING); 915 emlxs_mb_config_ring(hba, i, mb); 916 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 917 MBX_SUCCESS) { 918 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 919 "Unable to configure ring. " 920 "Mailbox cmd=%x status=%x", 921 mb->mbxCommand, mb->mbxStatus); 922 923 emlxs_ffstate_change(hba, FC_ERROR); 924 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 925 (void) emlxs_mem_free_buffer(hba); 926 927 return (EIO); 928 } 929 } 930 931 /* 932 * Setup link timers 933 */ 934 emlxs_ffstate_change(hba, FC_INIT_INITLINK); 935 emlxs_mb_config_link(hba, mb); 936 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 937 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 938 "Unable to configure link. Mailbox cmd=%x status=%x", 939 mb->mbxCommand, mb->mbxStatus); 940 941 emlxs_ffstate_change(hba, FC_ERROR); 942 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 943 emlxs_ffcleanup(hba); 944 (void) emlxs_mem_free_buffer(hba); 945 946 return (EIO); 947 } 948 #ifdef MAX_RRDY_PATCH 949 /* Set MAX_RRDY if one is provided */ 950 if (cfg[CFG_MAX_RRDY].current) { 951 emlxs_mb_set_var(hba, (MAILBOX *)mb, 0x00060412, 952 cfg[CFG_MAX_RRDY].current); 953 954 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 955 MBX_SUCCESS) { 956 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 957 "MAX_RRDY: Unable to set. status=%x value=%d", 958 mb->mbxStatus, cfg[CFG_MAX_RRDY].current); 959 } else { 960 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 961 "MAX_RRDY: %d", cfg[CFG_MAX_RRDY].current); 962 } 963 } 964 #endif /* MAX_RRDY_PATCH */ 965 966 /* 967 * We need to get login parameters for NID 968 */ 969 (void) emlxs_mb_read_sparam(hba, mb); 970 mp = (MATCHMAP *)(((MAILBOXQ *)mb)->bp); 971 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 972 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 973 "Unable to read parameters. Mailbox cmd=%x status=%x", 974 mb->mbxCommand, mb->mbxStatus); 975 976 emlxs_ffstate_change(hba, FC_ERROR); 977 (void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp); 978 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 979 emlxs_ffcleanup(hba); 980 (void) emlxs_mem_free_buffer(hba); 981 982 return (EIO); 983 } 984 985 /* Free the buffer since we were polling */ 986 (void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp); 987 988 /* If no serial number in VPD data, then use the WWPN */ 989 if (vpd->serial_num[0] == 0) { 990 outptr = (uint8_t *)&hba->wwpn.IEEE[0]; 991 for (i = 0; i < 12; i++) { 992 status = *outptr++; 993 j = ((status & 0xf0) >> 4); 994 if (j <= 9) { 995 vpd->serial_num[i] = 996 (char)((uint8_t)'0' + (uint8_t)j); 997 } else { 998 vpd->serial_num[i] = 999 (char)((uint8_t)'A' + (uint8_t)(j - 10)); 1000 } 1001 1002 i++; 1003 j = (status & 0xf); 1004 if (j <= 9) { 1005 vpd->serial_num[i] = 1006 (char)((uint8_t)'0' + (uint8_t)j); 1007 } else { 1008 vpd->serial_num[i] = 1009 (char)((uint8_t)'A' + (uint8_t)(j - 10)); 1010 } 1011 } 1012 1013 /* 1014 * Set port number and port index to zero 1015 * The WWN's are unique to each port and therefore port_num 1016 * must equal zero. This effects the hba_fru_details structure 1017 * in fca_bind_port() 1018 */ 1019 vpd->port_num[0] = 0; 1020 vpd->port_index = 0; 1021 } 1022 1023 /* 1024 * Make first attempt to set a port index 1025 * Check if this is a multifunction adapter 1026 */ 1027 if ((vpd->port_index == -1) && 1028 (hba->model_info.chip >= EMLXS_THOR_CHIP)) { 1029 char *buffer; 1030 int32_t i; 1031 1032 /* 1033 * The port address looks like this: 1034 * 1 - for port index 0 1035 * 1,1 - for port index 1 1036 * 1,2 - for port index 2 1037 */ 1038 buffer = ddi_get_name_addr(hba->dip); 1039 1040 if (buffer) { 1041 vpd->port_index = 0; 1042 1043 /* Reverse scan for a comma */ 1044 for (i = strlen(buffer) - 1; i > 0; i--) { 1045 if (buffer[i] == ',') { 1046 /* Comma found - set index now */ 1047 vpd->port_index = 1048 emlxs_strtol(&buffer[i + 1], 10); 1049 break; 1050 } 1051 } 1052 } 1053 } 1054 1055 /* Make final attempt to set a port index */ 1056 if (vpd->port_index == -1) { 1057 dev_info_t *p_dip; 1058 dev_info_t *c_dip; 1059 1060 p_dip = ddi_get_parent(hba->dip); 1061 c_dip = ddi_get_child(p_dip); 1062 1063 vpd->port_index = 0; 1064 while (c_dip && (hba->dip != c_dip)) { 1065 c_dip = ddi_get_next_sibling(c_dip); 1066 vpd->port_index++; 1067 } 1068 } 1069 1070 if (vpd->port_num[0] == 0) { 1071 if (hba->model_info.channels > 1) { 1072 (void) sprintf(vpd->port_num, "%d", vpd->port_index); 1073 } 1074 } 1075 1076 if (vpd->id[0] == 0) { 1077 (void) strcpy(vpd->id, hba->model_info.model_desc); 1078 } 1079 1080 if (vpd->manufacturer[0] == 0) { 1081 (void) strcpy(vpd->manufacturer, hba->model_info.manufacturer); 1082 } 1083 1084 if (vpd->part_num[0] == 0) { 1085 (void) strcpy(vpd->part_num, hba->model_info.model); 1086 } 1087 1088 if (vpd->model_desc[0] == 0) { 1089 (void) strcpy(vpd->model_desc, hba->model_info.model_desc); 1090 } 1091 1092 if (vpd->model[0] == 0) { 1093 (void) strcpy(vpd->model, hba->model_info.model); 1094 } 1095 1096 if (vpd->prog_types[0] == 0) { 1097 emlxs_build_prog_types(hba, vpd->prog_types); 1098 } 1099 1100 /* Create the symbolic names */ 1101 (void) sprintf(hba->snn, "Emulex %s FV%s DV%s %s", 1102 hba->model_info.model, hba->vpd.fw_version, emlxs_version, 1103 (char *)utsname.nodename); 1104 1105 (void) sprintf(hba->spn, 1106 "Emulex PPN-%01x%01x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", 1107 hba->wwpn.nameType, hba->wwpn.IEEEextMsn, hba->wwpn.IEEEextLsb, 1108 hba->wwpn.IEEE[0], hba->wwpn.IEEE[1], hba->wwpn.IEEE[2], 1109 hba->wwpn.IEEE[3], hba->wwpn.IEEE[4], hba->wwpn.IEEE[5]); 1110 1111 if (cfg[CFG_NETWORK_ON].current) { 1112 if ((hba->sparam.portName.nameType != NAME_IEEE) || 1113 (hba->sparam.portName.IEEEextMsn != 0) || 1114 (hba->sparam.portName.IEEEextLsb != 0)) { 1115 1116 cfg[CFG_NETWORK_ON].current = 0; 1117 1118 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 1119 "WWPN doesn't conform to IP profile: nameType=%x", 1120 hba->sparam.portName.nameType); 1121 } 1122 1123 /* Issue CONFIG FARP */ 1124 emlxs_mb_config_farp(hba, mb); 1125 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 1126 MBX_SUCCESS) { 1127 /* 1128 * Let it go through even if failed. 1129 */ 1130 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 1131 "Unable to configure FARP. " 1132 "Mailbox cmd=%x status=%x", 1133 mb->mbxCommand, mb->mbxStatus); 1134 } 1135 } 1136 #ifdef MSI_SUPPORT 1137 /* Configure MSI map if required */ 1138 if (hba->intr_count > 1) { 1139 emlxs_mb_config_msix(hba, mb, hba->intr_map, hba->intr_count); 1140 1141 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) == 1142 MBX_SUCCESS) { 1143 goto msi_configured; 1144 } 1145 1146 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1147 "Unable to config MSIX. Mailbox cmd=0x%x status=0x%x", 1148 mb->mbxCommand, mb->mbxStatus); 1149 1150 emlxs_mb_config_msi(hba, mb, hba->intr_map, hba->intr_count); 1151 1152 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) == 1153 MBX_SUCCESS) { 1154 goto msi_configured; 1155 } 1156 1157 1158 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1159 "Unable to config MSI. Mailbox cmd=0x%x status=0x%x", 1160 mb->mbxCommand, mb->mbxStatus); 1161 1162 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1163 "Attempting single interrupt mode..."); 1164 1165 /* First cleanup old interrupts */ 1166 (void) emlxs_msi_remove(hba); 1167 (void) emlxs_msi_uninit(hba); 1168 1169 status = emlxs_msi_init(hba, 1); 1170 1171 if (status != DDI_SUCCESS) { 1172 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 1173 "Unable to initialize interrupt. status=%d", 1174 status); 1175 1176 emlxs_ffstate_change(hba, FC_ERROR); 1177 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 1178 emlxs_ffcleanup(hba); 1179 (void) emlxs_mem_free_buffer(hba); 1180 1181 return (EIO); 1182 } 1183 1184 /* 1185 * Reset adapter - The adapter needs to be reset because 1186 * the bus cannot handle the MSI change without handshaking 1187 * with the adapter again 1188 */ 1189 1190 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 1191 (void) emlxs_mem_free_buffer(hba); 1192 fw_check = 0; 1193 goto reset; 1194 } 1195 1196 msi_configured: 1197 1198 #endif /* MSI_SUPPORT */ 1199 1200 /* 1201 * We always disable the firmware traffic cop feature 1202 */ 1203 if (emlxs_disable_traffic_cop) { 1204 emlxs_disable_tc(hba, (MAILBOX *)mb); 1205 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 1206 MBX_SUCCESS) { 1207 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 1208 "Unable to disable traffic cop. " 1209 "Mailbox cmd=%x status=%x", 1210 mb->mbxCommand, mb->mbxStatus); 1211 1212 (void) EMLXS_INTR_REMOVE(hba); 1213 emlxs_ffstate_change(hba, FC_ERROR); 1214 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 1215 emlxs_ffcleanup(hba); 1216 (void) emlxs_mem_free_buffer(hba); 1217 1218 return (EIO); 1219 } 1220 } 1221 1222 emlxs_mb_read_config(hba, (MAILBOX *)mb); 1223 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 1224 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 1225 "Unable to read configuration. Mailbox cmd=%x status=%x", 1226 mb->mbxCommand, mb->mbxStatus); 1227 1228 (void) EMLXS_INTR_REMOVE(hba); 1229 emlxs_ffstate_change(hba, FC_ERROR); 1230 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 1231 emlxs_ffcleanup(hba); 1232 (void) emlxs_mem_free_buffer(hba); 1233 1234 return (EIO); 1235 } 1236 1237 /* Save the link speed capabilities */ 1238 vpd->link_speed = mb->un.varRdConfig.lmt; 1239 emlxs_process_link_speed(hba); 1240 1241 /* Set the io throttle */ 1242 hba->io_throttle = mb->un.varRdConfig.max_xri - IO_THROTTLE_RESERVE; 1243 1244 /* Set the max node count */ 1245 if (cfg[CFG_NUM_NODES].current > 0) { 1246 hba->max_nodes = 1247 min(cfg[CFG_NUM_NODES].current, 1248 mb->un.varRdConfig.max_rpi); 1249 } else { 1250 hba->max_nodes = mb->un.varRdConfig.max_rpi; 1251 } 1252 1253 /* Register for async events */ 1254 emlxs_mb_async_event(hba, mb); 1255 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 1256 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1257 "Async events disabled. Mailbox status=%x", 1258 mb->mbxStatus); 1259 } else { 1260 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1261 "Async events enabled."); 1262 hba->flag |= FC_ASYNC_EVENTS; 1263 } 1264 1265 emlxs_ffstate_change(hba, FC_LINK_DOWN); 1266 1267 emlxs_intr_initialize(hba); 1268 1269 #ifdef SLI3_SUPPORT 1270 1271 if (hba->flag & FC_HBQ_ENABLED) { 1272 if (hba->tgt_mode) { 1273 if (emlxs_hbq_setup(hba, EMLXS_FCT_HBQ_ID)) { 1274 return (ENOMEM); 1275 } 1276 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1277 "FCT Ring: Posted %d buffers.", MEM_FCTBUF_COUNT); 1278 } 1279 1280 if (cfg[CFG_NETWORK_ON].current) { 1281 if (emlxs_hbq_setup(hba, EMLXS_IP_HBQ_ID)) { 1282 return (ENOMEM); 1283 } 1284 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1285 "IP Ring: Posted %d buffers.", MEM_IPBUF_COUNT); 1286 } 1287 1288 if (emlxs_hbq_setup(hba, EMLXS_ELS_HBQ_ID)) { 1289 return (ENOMEM); 1290 } 1291 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1292 "ELS Ring: Posted %d buffers.", MEM_ELSBUF_COUNT); 1293 1294 if (emlxs_hbq_setup(hba, EMLXS_CT_HBQ_ID)) { 1295 return (ENOMEM); 1296 } 1297 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1298 "CT Ring: Posted %d buffers.", MEM_CTBUF_COUNT); 1299 } else 1300 #endif /* SLI3_SUPPORT */ 1301 { 1302 if (hba->tgt_mode) { 1303 /* Post the FCT unsol buffers */ 1304 rp = &hba->ring[FC_FCT_RING]; 1305 for (j = 0; j < MEM_FCTBUF_COUNT; j += 2) { 1306 (void) emlxs_post_buffer(hba, rp, 2); 1307 } 1308 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1309 "FCP Ring: Posted %d buffers.", MEM_FCTBUF_COUNT); 1310 } 1311 1312 if (cfg[CFG_NETWORK_ON].current) { 1313 /* Post the IP unsol buffers */ 1314 rp = &hba->ring[FC_IP_RING]; 1315 for (j = 0; j < MEM_IPBUF_COUNT; j += 2) { 1316 (void) emlxs_post_buffer(hba, rp, 2); 1317 } 1318 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1319 "IP Ring: Posted %d buffers.", MEM_IPBUF_COUNT); 1320 } 1321 1322 /* Post the ELS unsol buffers */ 1323 rp = &hba->ring[FC_ELS_RING]; 1324 for (j = 0; j < MEM_ELSBUF_COUNT; j += 2) { 1325 (void) emlxs_post_buffer(hba, rp, 2); 1326 } 1327 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1328 "ELS Ring: Posted %d buffers.", MEM_ELSBUF_COUNT); 1329 1330 1331 /* Post the CT unsol buffers */ 1332 rp = &hba->ring[FC_CT_RING]; 1333 for (j = 0; j < MEM_CTBUF_COUNT; j += 2) { 1334 (void) emlxs_post_buffer(hba, rp, 2); 1335 } 1336 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1337 "CT Ring: Posted %d buffers.", MEM_CTBUF_COUNT); 1338 } 1339 1340 1341 /* 1342 * Setup and issue mailbox INITIALIZE LINK command At this point, 1343 * the interrupt will be generated by the HW 1344 */ 1345 emlxs_mb_init_link(hba, 1346 mb, cfg[CFG_TOPOLOGY].current, cfg[CFG_LINK_SPEED].current); 1347 1348 rval = emlxs_sli_issue_mbox_cmd(hba, mb, MBX_NOWAIT, 0); 1349 1350 if (rval != MBX_SUCCESS && rval != MBX_BUSY) { 1351 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 1352 "Unable to initialize link. Mailbox cmd=%x status=%x", 1353 mb->mbxCommand, mb->mbxStatus); 1354 1355 (void) EMLXS_INTR_REMOVE(hba); 1356 emlxs_ffstate_change(hba, FC_ERROR); 1357 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 1358 emlxs_ffcleanup(hba); 1359 (void) emlxs_mem_free_buffer(hba); 1360 1361 return (EIO); 1362 } 1363 1364 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 1365 1366 /* 1367 * Enable link attention interrupt 1368 */ 1369 emlxs_enable_latt(hba); 1370 1371 /* Wait for link to come up */ 1372 i = cfg[CFG_LINKUP_DELAY].current; 1373 while (i && (hba->state < FC_LINK_UP)) { 1374 /* Check for hardware error */ 1375 if (hba->state == FC_ERROR) { 1376 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 1377 "Adapter error.", mb->mbxCommand, mb->mbxStatus); 1378 1379 (void) EMLXS_INTR_REMOVE(hba); 1380 emlxs_ffcleanup(hba); 1381 (void) emlxs_mem_free_buffer(hba); 1382 1383 return (EIO); 1384 } 1385 1386 DELAYMS(1000); 1387 i--; 1388 } 1389 1390 out: 1391 1392 /* 1393 * The leadvile driver will now handle the FLOGI at the driver level 1394 */ 1395 1396 return (0); 1397 } /* emlxs_ffinit() */ 1398 1399 1400 #ifdef MSI_SUPPORT 1401 1402 /* EMLXS_INTR_INIT */ 1403 int32_t 1404 emlxs_msi_init(emlxs_hba_t *hba, uint32_t max) 1405 { 1406 emlxs_port_t *port = &PPORT; 1407 int32_t pass = 0; 1408 int32_t type = 0; 1409 char s_type[16]; 1410 int32_t types; 1411 int32_t count; 1412 int32_t nintrs; 1413 int32_t mode; 1414 int32_t actual; 1415 int32_t new_actual; 1416 int32_t i; 1417 int32_t ret; 1418 ddi_intr_handle_t *htable = NULL; 1419 ddi_intr_handle_t *new_htable = NULL; 1420 uint32_t *intr_pri = NULL; 1421 int32_t *intr_cap = NULL; 1422 int32_t hilevel_pri; 1423 emlxs_config_t *cfg = &CFG; 1424 char buf[64]; 1425 1426 if (!(hba->intr_flags & EMLXS_MSI_ENABLED)) { 1427 return (emlxs_intx_init(hba, max)); 1428 } 1429 1430 if (hba->intr_flags & EMLXS_MSI_INITED) { 1431 return (DDI_SUCCESS); 1432 } 1433 1434 /* Set max interrupt count if not specified */ 1435 if (max == 0) { 1436 if ((cfg[CFG_MSI_MODE].current == 2) || 1437 (cfg[CFG_MSI_MODE].current == 3)) { 1438 max = EMLXS_MSI_MAX_INTRS; 1439 } else { 1440 max = 1; 1441 } 1442 } 1443 1444 /* Filter max interrupt count with adapter model specification */ 1445 if (hba->model_info.intr_limit && (max > hba->model_info.intr_limit)) { 1446 max = hba->model_info.intr_limit; 1447 } 1448 1449 /* Get the available interrupt types from the kernel */ 1450 types = 0; 1451 ret = ddi_intr_get_supported_types(hba->dip, &types); 1452 1453 if ((ret != DDI_SUCCESS)) { 1454 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1455 "MSI: ddi_intr_get_supported_types failed. ret=%d", ret); 1456 1457 /* Default to fixed type */ 1458 types = DDI_INTR_TYPE_FIXED; 1459 } 1460 1461 /* Check if fixed interrupts are being forced */ 1462 if (cfg[CFG_MSI_MODE].current == 0) { 1463 types &= DDI_INTR_TYPE_FIXED; 1464 } 1465 1466 /* Check if MSI interrupts are being forced */ 1467 else if ((cfg[CFG_MSI_MODE].current == 1) || 1468 (cfg[CFG_MSI_MODE].current == 2)) { 1469 types &= (DDI_INTR_TYPE_MSI | DDI_INTR_TYPE_FIXED); 1470 } 1471 1472 begin: 1473 1474 /* Set interrupt type and interrupt count */ 1475 type = 0; 1476 1477 /* Check if MSIX is fully supported */ 1478 if ((types & DDI_INTR_TYPE_MSIX) && 1479 (hba->model_info.flags & EMLXS_MSIX_SUPPORTED)) { 1480 /* Get the max interrupt count from the adapter */ 1481 nintrs = 0; 1482 ret = 1483 ddi_intr_get_nintrs(hba->dip, DDI_INTR_TYPE_MSIX, 1484 &nintrs); 1485 1486 if (ret == DDI_SUCCESS && nintrs) { 1487 type = DDI_INTR_TYPE_MSIX; 1488 (void) strcpy(s_type, "TYPE_MSIX"); 1489 goto initialize; 1490 } 1491 } 1492 1493 /* Check if MSI is fully supported */ 1494 if ((types & DDI_INTR_TYPE_MSI) && 1495 (hba->model_info.flags & EMLXS_MSI_SUPPORTED)) { 1496 /* Get the max interrupt count from the adapter */ 1497 nintrs = 0; 1498 ret = 1499 ddi_intr_get_nintrs(hba->dip, DDI_INTR_TYPE_MSI, &nintrs); 1500 1501 if (ret == DDI_SUCCESS && nintrs) { 1502 type = DDI_INTR_TYPE_MSI; 1503 (void) strcpy(s_type, "TYPE_MSI"); 1504 goto initialize; 1505 } 1506 } 1507 1508 /* Check if fixed interrupts are fully supported */ 1509 if ((types & DDI_INTR_TYPE_FIXED) && 1510 (hba->model_info.flags & EMLXS_INTX_SUPPORTED)) { 1511 /* Get the max interrupt count from the adapter */ 1512 nintrs = 0; 1513 ret = 1514 ddi_intr_get_nintrs(hba->dip, DDI_INTR_TYPE_FIXED, 1515 &nintrs); 1516 1517 if (ret == DDI_SUCCESS) { 1518 type = DDI_INTR_TYPE_FIXED; 1519 (void) strcpy(s_type, "TYPE_FIXED"); 1520 goto initialize; 1521 } 1522 } 1523 1524 goto init_failed; 1525 1526 1527 initialize: 1528 1529 pass++; 1530 mode = 0; 1531 actual = 0; 1532 htable = NULL; 1533 intr_pri = NULL; 1534 intr_cap = NULL; 1535 hilevel_pri = 0; 1536 1537 if (pass == 1) { 1538 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1539 "MSI: %s: mode=%d types=0x%x nintrs=%d", s_type, 1540 cfg[CFG_MSI_MODE].current, types, nintrs); 1541 } 1542 1543 /* Validate interrupt count */ 1544 count = min(nintrs, max); 1545 1546 if (count >= 8) { 1547 count = 8; 1548 } else if (count >= 4) { 1549 count = 4; 1550 } else if (count >= 2) { 1551 count = 2; 1552 } else { 1553 count = 1; 1554 } 1555 1556 /* Allocate an array of interrupt handles */ 1557 htable = 1558 kmem_alloc((size_t)(count * sizeof (ddi_intr_handle_t)), 1559 KM_SLEEP); 1560 1561 if (htable == NULL) { 1562 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1563 "MSI: Unable to allocate interrupt handle table"); 1564 1565 goto init_failed; 1566 } 1567 1568 /* Allocate 'count' interrupts */ 1569 ret = 1570 ddi_intr_alloc(hba->dip, htable, type, EMLXS_MSI_INUMBER, count, 1571 &actual, DDI_INTR_ALLOC_NORMAL); 1572 1573 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1574 "MSI: %s: count=%d actual=%d", s_type, count, actual); 1575 1576 if ((ret != DDI_SUCCESS) || (actual == 0)) { 1577 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1578 "MSI: Unable to allocate interrupts. error=%d", ret); 1579 1580 goto init_failed; 1581 } 1582 1583 if (actual != count) { 1584 /* Validate actual count */ 1585 if (actual >= 8) { 1586 new_actual = 8; 1587 } else if (actual >= 4) { 1588 new_actual = 4; 1589 } else if (actual >= 2) { 1590 new_actual = 2; 1591 } else { 1592 new_actual = 1; 1593 } 1594 1595 if (new_actual < actual) { 1596 /* Free extra handles */ 1597 for (i = new_actual; i < actual; i++) { 1598 (void) ddi_intr_free(htable[i]); 1599 } 1600 1601 actual = new_actual; 1602 } 1603 1604 /* Allocate a new array of interrupt handles */ 1605 new_htable = 1606 kmem_alloc((size_t)(actual * sizeof (ddi_intr_handle_t)), 1607 KM_SLEEP); 1608 1609 if (new_htable == NULL) { 1610 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1611 "MSI: Unable to allocate new " 1612 "interrupt handle table"); 1613 1614 goto init_failed; 1615 } 1616 1617 /* Copy old array to new array */ 1618 bcopy((uint8_t *)htable, (uint8_t *)new_htable, 1619 (actual * sizeof (ddi_intr_handle_t))); 1620 1621 /* Free the old array */ 1622 kmem_free(htable, (count * sizeof (ddi_intr_handle_t))); 1623 1624 htable = new_htable; 1625 count = actual; 1626 } 1627 1628 /* Allocate interrupt priority table */ 1629 intr_pri = 1630 (uint32_t *)kmem_alloc((size_t)(count * sizeof (uint32_t)), 1631 KM_SLEEP); 1632 1633 if (intr_pri == NULL) { 1634 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1635 "MSI: Unable to allocate interrupt priority table"); 1636 1637 goto init_failed; 1638 } 1639 1640 /* Allocate interrupt capability table */ 1641 intr_cap = kmem_alloc((size_t)(count * sizeof (uint32_t)), KM_SLEEP); 1642 1643 if (intr_cap == NULL) { 1644 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1645 "MSI: Unable to allocate interrupt capability table"); 1646 1647 goto init_failed; 1648 } 1649 1650 /* Get minimum hilevel priority */ 1651 hilevel_pri = ddi_intr_get_hilevel_pri(); 1652 1653 /* Fill the priority and capability tables */ 1654 for (i = 0; i < count; ++i) { 1655 ret = ddi_intr_get_pri(htable[i], &intr_pri[i]); 1656 1657 if (ret != DDI_SUCCESS) { 1658 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1659 "MSI: ddi_intr_get_pri(%d) failed. " 1660 "handle=%p ret=%d", 1661 i, &htable[i], ret); 1662 1663 /* Clean up the interrupts */ 1664 goto init_failed; 1665 } 1666 1667 if (intr_pri[i] >= hilevel_pri) { 1668 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1669 "MSI: Interrupt(%d) level too high. " 1670 "pri=0x%x hilevel=0x%x", 1671 i, intr_pri[i], hilevel_pri); 1672 1673 /* Clean up the interrupts */ 1674 goto init_failed; 1675 } 1676 1677 ret = ddi_intr_get_cap(htable[i], &intr_cap[i]); 1678 1679 if (ret != DDI_SUCCESS) { 1680 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1681 "MSI: ddi_intr_get_cap(%d) failed. " 1682 "handle=%p ret=%d", 1683 i, &htable[i], ret); 1684 1685 /* Clean up the interrupts */ 1686 goto init_failed; 1687 } 1688 1689 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1690 "MSI: %s: %d: cap=0x%x pri=0x%x hilevel=0x%x", s_type, i, 1691 intr_cap[i], intr_pri[i], hilevel_pri); 1692 1693 } 1694 1695 /* Set mode */ 1696 switch (count) { 1697 case 8: 1698 mode = EMLXS_MSI_MODE8; 1699 break; 1700 1701 case 4: 1702 mode = EMLXS_MSI_MODE4; 1703 break; 1704 1705 case 2: 1706 mode = EMLXS_MSI_MODE2; 1707 break; 1708 1709 default: 1710 mode = EMLXS_MSI_MODE1; 1711 } 1712 1713 /* Save the info */ 1714 hba->intr_htable = htable; 1715 hba->intr_count = count; 1716 hba->intr_pri = intr_pri; 1717 hba->intr_cap = intr_cap; 1718 hba->intr_type = type; 1719 hba->intr_arg = (void *)((unsigned long)intr_pri[0]); 1720 hba->intr_mask = emlxs_msi_mask[mode]; 1721 1722 hba->intr_cond = 0; 1723 for (i = 0; i < EMLXS_MSI_MAX_INTRS; i++) { 1724 hba->intr_map[i] = emlxs_msi_map[mode][i]; 1725 hba->intr_cond |= emlxs_msi_map[mode][i]; 1726 1727 (void) sprintf(buf, "%s%d_msi%d mutex", DRIVER_NAME, 1728 hba->ddiinst, i); 1729 mutex_init(&hba->intr_lock[i], buf, MUTEX_DRIVER, 1730 (void *)hba->intr_arg); 1731 } 1732 1733 /* Set flag to indicate support */ 1734 hba->intr_flags |= EMLXS_MSI_INITED; 1735 1736 /* Create the interrupt threads */ 1737 for (i = 0; i < MAX_RINGS; i++) { 1738 (void) sprintf(buf, "%s%d_ring%d mutex", DRIVER_NAME, 1739 hba->ddiinst, i); 1740 mutex_init(&hba->ring[i].rsp_lock, buf, MUTEX_DRIVER, 1741 (void *)hba->intr_arg); 1742 1743 emlxs_thread_create(hba, &hba->ring[i].intr_thread); 1744 } 1745 1746 return (DDI_SUCCESS); 1747 1748 1749 init_failed: 1750 1751 if (intr_cap) { 1752 kmem_free(intr_cap, (count * sizeof (int32_t))); 1753 } 1754 1755 if (intr_pri) { 1756 kmem_free(intr_pri, (count * sizeof (int32_t))); 1757 } 1758 1759 if (htable) { 1760 /* Process the interrupt handlers */ 1761 for (i = 0; i < actual; i++) { 1762 /* Free the handle[i] */ 1763 (void) ddi_intr_free(htable[i]); 1764 } 1765 1766 kmem_free(htable, (count * sizeof (ddi_intr_handle_t))); 1767 } 1768 1769 /* Initialize */ 1770 hba->intr_htable = NULL; 1771 hba->intr_count = 0; 1772 hba->intr_pri = NULL; 1773 hba->intr_cap = NULL; 1774 hba->intr_type = 0; 1775 hba->intr_arg = NULL; 1776 hba->intr_cond = 0; 1777 bzero(hba->intr_map, sizeof (hba->intr_map)); 1778 bzero(hba->intr_lock, sizeof (hba->intr_lock)); 1779 1780 if (type == DDI_INTR_TYPE_MSIX) { 1781 types &= (DDI_INTR_TYPE_MSI | DDI_INTR_TYPE_FIXED); 1782 goto begin; 1783 } else if (type == DDI_INTR_TYPE_MSI) { 1784 types &= DDI_INTR_TYPE_FIXED; 1785 goto begin; 1786 } 1787 1788 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 1789 "MSI: Unable to initialize interrupts"); 1790 1791 return (DDI_FAILURE); 1792 1793 1794 } /* emlxs_msi_init() */ 1795 1796 1797 /* EMLXS_INTR_UNINIT */ 1798 int32_t 1799 emlxs_msi_uninit(emlxs_hba_t *hba) 1800 { 1801 uint32_t count; 1802 int32_t i; 1803 ddi_intr_handle_t *htable; 1804 uint32_t *intr_pri; 1805 int32_t *intr_cap; 1806 int32_t ret; 1807 1808 if (!(hba->intr_flags & EMLXS_MSI_ENABLED)) { 1809 return (emlxs_intx_uninit(hba)); 1810 } 1811 1812 /* 1813 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1814 * "MSI: emlxs_msi_uninit called. flags=%x", 1815 * hba->intr_flags); 1816 */ 1817 1818 /* Make sure interrupts have been removed first */ 1819 if ((hba->intr_flags & EMLXS_MSI_ADDED)) { 1820 ret = emlxs_msi_remove(hba); 1821 1822 if (ret != DDI_SUCCESS) { 1823 return (ret); 1824 } 1825 } 1826 1827 /* Check if the interrupts are still initialized */ 1828 if (!(hba->intr_flags & EMLXS_MSI_INITED)) { 1829 return (DDI_SUCCESS); 1830 } 1831 hba->intr_flags &= ~EMLXS_MSI_INITED; 1832 1833 /* Get handle table parameters */ 1834 htable = hba->intr_htable; 1835 count = hba->intr_count; 1836 intr_pri = hba->intr_pri; 1837 intr_cap = hba->intr_cap; 1838 1839 /* Clean up */ 1840 hba->intr_count = 0; 1841 hba->intr_htable = NULL; 1842 hba->intr_pri = NULL; 1843 hba->intr_cap = NULL; 1844 hba->intr_type = 0; 1845 hba->intr_arg = NULL; 1846 hba->intr_cond = 0; 1847 bzero(hba->intr_map, sizeof (hba->intr_map)); 1848 1849 if (intr_cap) { 1850 kmem_free(intr_cap, (count * sizeof (int32_t))); 1851 } 1852 1853 if (intr_pri) { 1854 kmem_free(intr_pri, (count * sizeof (int32_t))); 1855 } 1856 1857 if (htable) { 1858 /* Process the interrupt handlers */ 1859 for (i = 0; i < count; ++i) { 1860 /* Free the handle[i] */ 1861 ret = ddi_intr_free(htable[i]); 1862 } 1863 1864 kmem_free(htable, (count * sizeof (ddi_intr_handle_t))); 1865 } 1866 1867 /* Destroy the intr locks */ 1868 for (i = 0; i < EMLXS_MSI_MAX_INTRS; i++) { 1869 mutex_destroy(&hba->intr_lock[i]); 1870 } 1871 1872 /* Destroy the interrupt threads */ 1873 for (i = 0; i < MAX_RINGS; i++) { 1874 emlxs_thread_destroy(&hba->ring[i].intr_thread); 1875 mutex_destroy(&hba->ring[i].rsp_lock); 1876 } 1877 1878 /* 1879 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1880 * "MSI: emlxs_msi_uninit done. flags=%x", 1881 * hba->intr_flags); 1882 */ 1883 1884 return (DDI_SUCCESS); 1885 1886 } /* emlxs_msi_uninit() */ 1887 1888 1889 /* EMLXS_INTR_ADD */ 1890 int32_t 1891 emlxs_msi_add(emlxs_hba_t *hba) 1892 { 1893 emlxs_port_t *port = &PPORT; 1894 int32_t count; 1895 int32_t i; 1896 int32_t ret; 1897 ddi_intr_handle_t *htable = NULL; 1898 int32_t *intr_cap = NULL; 1899 1900 if (!(hba->intr_flags & EMLXS_MSI_ENABLED)) { 1901 return (emlxs_intx_add(hba)); 1902 } 1903 1904 /* Check if interrupts have already been added */ 1905 if (hba->intr_flags & EMLXS_MSI_ADDED) { 1906 return (DDI_SUCCESS); 1907 } 1908 1909 /* Check if interrupts have been initialized */ 1910 if (!(hba->intr_flags & EMLXS_MSI_INITED)) { 1911 ret = emlxs_msi_init(hba, 0); 1912 1913 if (ret != DDI_SUCCESS) { 1914 return (ret); 1915 } 1916 } 1917 1918 /* Get handle table parameters */ 1919 htable = hba->intr_htable; 1920 count = hba->intr_count; 1921 intr_cap = hba->intr_cap; 1922 1923 /* Add the interrupt handlers */ 1924 for (i = 0; i < count; ++i) { 1925 /* add handler for handle[i] */ 1926 ret = 1927 ddi_intr_add_handler(htable[i], emlxs_sli_msi_intr, 1928 (char *)hba, (char *)((unsigned long)i)); 1929 1930 if (ret != DDI_SUCCESS) { 1931 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 1932 "MSI: ddi_intr_add_handler(%d) failed. " 1933 "handle=%p ret=%d", 1934 i, &htable[i], ret); 1935 1936 /* Process the remaining interrupt handlers */ 1937 while (i) { 1938 /* Decrement i */ 1939 i--; 1940 1941 /* Remove the handler */ 1942 ret = ddi_intr_remove_handler(htable[i]); 1943 1944 } 1945 1946 return (DDI_FAILURE); 1947 } 1948 } 1949 1950 /* Enable the interrupts */ 1951 if (intr_cap[0] & DDI_INTR_FLAG_BLOCK) { 1952 ret = ddi_intr_block_enable(htable, count); 1953 1954 if (ret != DDI_SUCCESS) { 1955 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1956 "MSI: ddi_intr_block_enable(%d) failed. ret=%d", 1957 count, ret); 1958 1959 for (i = 0; i < count; ++i) { 1960 ret = ddi_intr_enable(htable[i]); 1961 1962 if (ret != DDI_SUCCESS) { 1963 EMLXS_MSGF(EMLXS_CONTEXT, 1964 &emlxs_init_debug_msg, 1965 "MSI: ddi_intr_enable(%d) failed. " 1966 "ret=%d", 1967 i, ret); 1968 } 1969 } 1970 } 1971 } else { 1972 for (i = 0; i < count; ++i) { 1973 ret = ddi_intr_enable(htable[i]); 1974 1975 if (ret != DDI_SUCCESS) { 1976 EMLXS_MSGF(EMLXS_CONTEXT, 1977 &emlxs_init_debug_msg, 1978 "MSI: ddi_intr_enable(%d) failed. ret=%d", 1979 i, ret); 1980 } 1981 } 1982 } 1983 1984 1985 /* Set flag to indicate support */ 1986 hba->intr_flags |= EMLXS_MSI_ADDED; 1987 1988 return (DDI_SUCCESS); 1989 1990 } /* emlxs_msi_add() */ 1991 1992 1993 1994 /* EMLXS_INTR_REMOVE */ 1995 int32_t 1996 emlxs_msi_remove(emlxs_hba_t *hba) 1997 { 1998 emlxs_port_t *port = &PPORT; 1999 uint32_t count; 2000 int32_t i; 2001 ddi_intr_handle_t *htable; 2002 int32_t *intr_cap; 2003 int32_t ret; 2004 2005 if (!(hba->intr_flags & EMLXS_MSI_ENABLED)) { 2006 return (emlxs_intx_remove(hba)); 2007 } 2008 2009 /* 2010 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 2011 * "MSI: emlxs_msi_remove called. flags=%x", 2012 * hba->intr_flags); 2013 */ 2014 2015 /* Check if interrupts have already been removed */ 2016 if (!(hba->intr_flags & EMLXS_MSI_ADDED)) { 2017 return (DDI_SUCCESS); 2018 } 2019 hba->intr_flags &= ~EMLXS_MSI_ADDED; 2020 2021 /* Disable all adapter interrupts */ 2022 emlxs_disable_intr(hba, 0); 2023 2024 /* Get handle table parameters */ 2025 htable = hba->intr_htable; 2026 count = hba->intr_count; 2027 intr_cap = hba->intr_cap; 2028 2029 /* Disable the interrupts */ 2030 if (intr_cap[0] & DDI_INTR_FLAG_BLOCK) { 2031 ret = ddi_intr_block_disable(htable, count); 2032 2033 if (ret != DDI_SUCCESS) { 2034 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 2035 "MSI: ddi_intr_block_disable(%d) failed. ret=%d", 2036 count, ret); 2037 2038 for (i = 0; i < count; i++) { 2039 ret = ddi_intr_disable(htable[i]); 2040 2041 if (ret != DDI_SUCCESS) { 2042 EMLXS_MSGF(EMLXS_CONTEXT, 2043 &emlxs_init_debug_msg, 2044 "MSI: ddi_intr_disable(%d) failed. " 2045 "ret=%d", 2046 i, ret); 2047 } 2048 } 2049 } 2050 } else { 2051 for (i = 0; i < count; i++) { 2052 ret = ddi_intr_disable(htable[i]); 2053 2054 if (ret != DDI_SUCCESS) { 2055 EMLXS_MSGF(EMLXS_CONTEXT, 2056 &emlxs_init_debug_msg, 2057 "MSI: ddi_intr_disable(%d) failed. ret=%d", 2058 i, ret); 2059 } 2060 } 2061 } 2062 2063 /* Process the interrupt handlers */ 2064 for (i = 0; i < count; i++) { 2065 /* Remove the handler */ 2066 ret = ddi_intr_remove_handler(htable[i]); 2067 2068 2069 } 2070 2071 return (DDI_SUCCESS); 2072 2073 } /* emlxs_msi_remove() */ 2074 2075 2076 #endif /* MSI_SUPPORT */ 2077 2078 2079 /* EMLXS_INTR_INIT */ 2080 /* ARGSUSED */ 2081 int32_t 2082 emlxs_intx_init(emlxs_hba_t *hba, uint32_t max) 2083 { 2084 emlxs_port_t *port = &PPORT; 2085 int32_t ret; 2086 uint32_t i; 2087 char buf[64]; 2088 2089 /* Check if interrupts have already been initialized */ 2090 if (hba->intr_flags & EMLXS_INTX_INITED) { 2091 return (DDI_SUCCESS); 2092 } 2093 2094 /* Check if adapter is flagged for INTX support */ 2095 if (!(hba->model_info.flags & EMLXS_INTX_SUPPORTED)) { 2096 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 2097 "INTX: %s does not support INTX. flags=0x%x", 2098 hba->model_info.model, hba->model_info.flags); 2099 2100 return (DDI_FAILURE); 2101 } 2102 2103 /* 2104 * Interrupt number '0' is a high-level interrupt. This driver 2105 * does not support having its interrupts mapped above scheduler 2106 * priority; i.e., we always expect to be able to call general 2107 * kernel routines that may invoke the scheduler. 2108 */ 2109 if (ddi_intr_hilevel(hba->dip, EMLXS_INUMBER) != 0) { 2110 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 2111 "INTX: High-level interrupt not supported."); 2112 2113 return (DDI_FAILURE); 2114 } 2115 2116 /* Get an iblock cookie */ 2117 ret = 2118 ddi_get_iblock_cookie(hba->dip, (uint32_t)EMLXS_INUMBER, 2119 (ddi_iblock_cookie_t *)&hba->intr_arg); 2120 if (ret != DDI_SUCCESS) { 2121 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 2122 "INTX: ddi_get_iblock_cookie failed. ret=%d", ret); 2123 2124 return (ret); 2125 } 2126 2127 hba->intr_flags |= EMLXS_INTX_INITED; 2128 2129 /* Create the interrupt threads */ 2130 for (i = 0; i < MAX_RINGS; i++) { 2131 (void) sprintf(buf, "%s%d_ring%d mutex", DRIVER_NAME, 2132 hba->ddiinst, i); 2133 mutex_init(&hba->ring[i].rsp_lock, buf, MUTEX_DRIVER, 2134 (void *)hba->intr_arg); 2135 2136 emlxs_thread_create(hba, &hba->ring[i].intr_thread); 2137 } 2138 2139 return (DDI_SUCCESS); 2140 2141 } /* emlxs_intx_init() */ 2142 2143 2144 /* EMLXS_INTR_UNINIT */ 2145 int32_t 2146 emlxs_intx_uninit(emlxs_hba_t *hba) 2147 { 2148 int32_t ret; 2149 uint32_t i; 2150 2151 /* Make sure interrupts have been removed */ 2152 if ((hba->intr_flags & EMLXS_INTX_ADDED)) { 2153 ret = emlxs_intx_remove(hba); 2154 2155 if (ret != DDI_SUCCESS) { 2156 return (ret); 2157 } 2158 } 2159 2160 /* Check if the interrupts are still initialized */ 2161 if (!(hba->intr_flags & EMLXS_INTX_INITED)) { 2162 return (DDI_SUCCESS); 2163 } 2164 hba->intr_flags &= ~EMLXS_INTX_INITED; 2165 2166 hba->intr_arg = NULL; 2167 2168 /* Create the interrupt threads */ 2169 for (i = 0; i < MAX_RINGS; i++) { 2170 emlxs_thread_destroy(&hba->ring[i].intr_thread); 2171 mutex_destroy(&hba->ring[i].rsp_lock); 2172 } 2173 2174 return (DDI_SUCCESS); 2175 2176 } /* emlxs_intx_uninit() */ 2177 2178 2179 /* 2180 * This is the legacy method for adding interrupts in Solaris 2181 * EMLXS_INTR_ADD 2182 */ 2183 int32_t 2184 emlxs_intx_add(emlxs_hba_t *hba) 2185 { 2186 emlxs_port_t *port = &PPORT; 2187 int32_t ret; 2188 2189 /* Check if interrupts have already been added */ 2190 if (hba->intr_flags & EMLXS_INTX_ADDED) { 2191 return (DDI_SUCCESS); 2192 } 2193 2194 /* Check if interrupts have been initialized */ 2195 if (!(hba->intr_flags & EMLXS_INTX_INITED)) { 2196 ret = emlxs_intx_init(hba, 0); 2197 2198 if (ret != DDI_SUCCESS) { 2199 return (ret); 2200 } 2201 } 2202 2203 /* add intrrupt handler routine */ 2204 ret = ddi_add_intr((void *)hba->dip, 2205 (uint_t)EMLXS_INUMBER, 2206 (ddi_iblock_cookie_t *)&hba->intr_arg, 2207 (ddi_idevice_cookie_t *)0, 2208 (uint_t(*)())emlxs_sli_intx_intr, (caddr_t)hba); 2209 2210 if (ret != DDI_SUCCESS) { 2211 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_failed_msg, 2212 "INTX: ddi_add_intr failed. ret=%d", ret); 2213 2214 return (ret); 2215 } 2216 2217 hba->intr_flags |= EMLXS_INTX_ADDED; 2218 2219 return (DDI_SUCCESS); 2220 2221 } /* emlxs_intx_add() */ 2222 2223 2224 /* EMLXS_INTR_REMOVE */ 2225 int32_t 2226 emlxs_intx_remove(emlxs_hba_t *hba) 2227 { 2228 /* Check if interrupts have already been removed */ 2229 if (!(hba->intr_flags & EMLXS_INTX_ADDED)) { 2230 return (DDI_SUCCESS); 2231 } 2232 hba->intr_flags &= ~EMLXS_INTX_ADDED; 2233 2234 /* Diable all adapter interrupts */ 2235 emlxs_disable_intr(hba, 0); 2236 2237 /* Remove the interrupt */ 2238 (void) ddi_remove_intr((void *)hba->dip, (uint_t)EMLXS_INUMBER, 2239 hba->intr_arg); 2240 2241 return (DDI_SUCCESS); 2242 2243 } /* emlxs_intx_remove() */ 2244 2245 2246 static void 2247 emlxs_process_link_speed(emlxs_hba_t *hba) 2248 { 2249 emlxs_vpd_t *vpd; 2250 emlxs_config_t *cfg; 2251 char *cptr; 2252 uint32_t hi; 2253 2254 /* 2255 * This routine modifies the link-speed config parameter entry 2256 * based on adapter capabilities 2257 */ 2258 vpd = &VPD; 2259 cfg = &hba->config[CFG_LINK_SPEED]; 2260 2261 cptr = cfg->help; 2262 (void) strcpy(cptr, "Select link speed. [0=Auto"); 2263 cptr += 26; 2264 hi = 0; 2265 2266 if (vpd->link_speed & LMT_1GB_CAPABLE) { 2267 (void) strcpy(cptr, ", 1=1Gb"); 2268 cptr += 7; 2269 hi = 1; 2270 } 2271 2272 if (vpd->link_speed & LMT_2GB_CAPABLE) { 2273 (void) strcpy(cptr, ", 2=2Gb"); 2274 cptr += 7; 2275 hi = 2; 2276 } 2277 2278 if (vpd->link_speed & LMT_4GB_CAPABLE) { 2279 (void) strcpy(cptr, ", 4=4Gb"); 2280 cptr += 7; 2281 hi = 4; 2282 } 2283 2284 if (vpd->link_speed & LMT_8GB_CAPABLE) { 2285 (void) strcpy(cptr, ", 8=8Gb"); 2286 cptr += 7; 2287 hi = 8; 2288 } 2289 2290 if (vpd->link_speed & LMT_10GB_CAPABLE) { 2291 (void) strcpy(cptr, ", 10=10Gb"); 2292 cptr += 9; 2293 hi = 10; 2294 } 2295 2296 (void) strcpy(cptr, "]"); 2297 cfg->hi = hi; 2298 2299 /* Now revalidate the current parameter setting */ 2300 cfg->current = emlxs_check_parm(hba, CFG_LINK_SPEED, cfg->current); 2301 2302 return; 2303 2304 } /* emlxs_process_link_speed() */ 2305 2306 2307 /* 2308 * emlxs_parse_vpd() 2309 * 2310 * This routine will parse the VPD data 2311 */ 2312 extern int 2313 emlxs_parse_vpd(emlxs_hba_t *hba, uint8_t *vpd_buf, uint32_t size) 2314 { 2315 emlxs_port_t *port = &PPORT; 2316 char tag[3]; 2317 uint8_t lenlo, lenhi; 2318 uint32_t n; 2319 uint16_t block_size; 2320 uint32_t block_index = 0; 2321 uint8_t sub_size; 2322 uint32_t sub_index; 2323 int32_t finished = 0; 2324 int32_t index = 0; 2325 char buffer[128]; 2326 emlxs_vpd_t *vpd; 2327 2328 vpd = &VPD; 2329 2330 2331 while (!finished && (block_index < size)) { 2332 /* 2333 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_vpd_msg, 2334 * "block_index = %x", block_index); 2335 */ 2336 2337 switch (vpd_buf[block_index]) { 2338 case 0x82: 2339 index = block_index; 2340 index += 1; 2341 lenlo = vpd_buf[index]; 2342 index += 1; 2343 lenhi = vpd_buf[index]; 2344 index += 1; 2345 block_index = index; 2346 2347 block_size = ((((uint16_t)lenhi) << 8) + lenlo); 2348 block_index += block_size; 2349 2350 /* 2351 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_vpd_msg, 2352 * "block_size = %x", block_size); 2353 */ 2354 2355 n = sizeof (buffer); 2356 bzero(buffer, n); 2357 bcopy(&vpd_buf[index], buffer, 2358 (block_size < (n - 1)) ? block_size : (n - 1)); 2359 2360 (void) strcpy(vpd->id, buffer); 2361 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_vpd_msg, "ID: %s", 2362 vpd->id); 2363 2364 break; 2365 2366 case 0x90: 2367 index = block_index; 2368 index += 1; 2369 lenlo = vpd_buf[index]; 2370 index += 1; 2371 lenhi = vpd_buf[index]; 2372 index += 1; 2373 block_index = index; 2374 sub_index = index; 2375 2376 block_size = ((((uint16_t)lenhi) << 8) + lenlo); 2377 block_index += block_size; 2378 2379 /* 2380 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_vpd_msg, 2381 * "block_size = %x", block_size); 2382 */ 2383 2384 /* Scan for sub-blocks */ 2385 while ((sub_index < block_index) && 2386 (sub_index < size)) { 2387 /* 2388 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_vpd_msg, 2389 * "sub_index = %x", sub_index); 2390 */ 2391 2392 index = sub_index; 2393 tag[0] = vpd_buf[index++]; 2394 tag[1] = vpd_buf[index++]; 2395 tag[2] = 0; 2396 sub_size = vpd_buf[index++]; 2397 2398 /* 2399 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_vpd_msg, 2400 * "sub_size = %x", sub_size); 2401 */ 2402 2403 sub_index = (index + sub_size); 2404 2405 n = sizeof (buffer); 2406 bzero(buffer, n); 2407 bcopy(&vpd_buf[index], buffer, 2408 (sub_size < (n - 1)) ? sub_size : (n - 1)); 2409 2410 /* 2411 * Look for Engineering Change (EC) 2412 */ 2413 if (strcmp(tag, "EC") == 0) { 2414 (void) strcpy(vpd->eng_change, buffer); 2415 EMLXS_MSGF(EMLXS_CONTEXT, 2416 &emlxs_vpd_msg, "EC: %s", 2417 vpd->eng_change); 2418 } 2419 /* 2420 * Look for Manufacturer (MN) 2421 */ 2422 else if (strcmp(tag, "MN") == 0) { 2423 (void) strcpy(vpd->manufacturer, 2424 buffer); 2425 EMLXS_MSGF(EMLXS_CONTEXT, 2426 &emlxs_vpd_msg, "MN: %s", 2427 vpd->manufacturer); 2428 } 2429 /* 2430 * Look for Serial Number (SN) 2431 */ 2432 else if (strcmp(tag, "SN") == 0) { 2433 (void) strcpy(vpd->serial_num, buffer); 2434 EMLXS_MSGF(EMLXS_CONTEXT, 2435 &emlxs_vpd_msg, "SN: %s", 2436 vpd->serial_num); 2437 2438 /* Validate the serial number */ 2439 if (strncmp(buffer, "FFFFFFFFFF", 10) == 2440 0 || 2441 strncmp(buffer, "0000000000", 10) == 2442 0) { 2443 vpd->serial_num[0] = 0; 2444 } 2445 } 2446 /* 2447 * Look for Part Number (PN) 2448 */ 2449 else if (strcmp(tag, "PN") == 0) { 2450 (void) strcpy(vpd->part_num, buffer); 2451 EMLXS_MSGF(EMLXS_CONTEXT, 2452 &emlxs_vpd_msg, "PN: %s", 2453 vpd->part_num); 2454 } 2455 /* 2456 * Look for (V0) 2457 */ 2458 else if (strcmp(tag, "V0") == 0) { 2459 /* Not used */ 2460 EMLXS_MSGF(EMLXS_CONTEXT, 2461 &emlxs_vpd_msg, "V0: %s", buffer); 2462 } 2463 /* 2464 * Look for model description (V1) 2465 */ 2466 else if (strcmp(tag, "V1") == 0) { 2467 (void) strcpy(vpd->model_desc, buffer); 2468 EMLXS_MSGF(EMLXS_CONTEXT, 2469 &emlxs_vpd_msg, "Desc: %s", 2470 vpd->model_desc); 2471 } 2472 /* 2473 * Look for model (V2) 2474 */ 2475 else if (strcmp(tag, "V2") == 0) { 2476 (void) strcpy(vpd->model, buffer); 2477 EMLXS_MSGF(EMLXS_CONTEXT, 2478 &emlxs_vpd_msg, "Model: %s", 2479 vpd->model); 2480 } 2481 /* 2482 * Look for program type (V3) 2483 */ 2484 2485 else if (strcmp(tag, "V3") == 0) { 2486 (void) strcpy(vpd->prog_types, buffer); 2487 EMLXS_MSGF(EMLXS_CONTEXT, 2488 &emlxs_vpd_msg, "Prog Types: %s", 2489 vpd->prog_types); 2490 } 2491 /* 2492 * Look for port number (V4) 2493 */ 2494 else if (strcmp(tag, "V4") == 0) { 2495 (void) strcpy(vpd->port_num, buffer); 2496 vpd->port_index = 2497 emlxs_strtol(vpd->port_num, 10); 2498 2499 EMLXS_MSGF(EMLXS_CONTEXT, 2500 &emlxs_vpd_msg, "Port: %s", 2501 (vpd->port_num[0]) ? vpd-> 2502 port_num : "not applicable"); 2503 } 2504 /* 2505 * Look for checksum (RV) 2506 */ 2507 else if (strcmp(tag, "RV") == 0) { 2508 /* Not used */ 2509 EMLXS_MSGF(EMLXS_CONTEXT, 2510 &emlxs_vpd_msg, "Checksum: 0x%x", 2511 buffer[0]); 2512 } 2513 2514 else { 2515 /* Generic */ 2516 EMLXS_MSGF(EMLXS_CONTEXT, 2517 &emlxs_vpd_msg, "Tag: %s: %s", 2518 tag, buffer); 2519 } 2520 } 2521 2522 break; 2523 2524 case 0x78: 2525 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_vpd_msg, "End Tag."); 2526 finished = 1; 2527 break; 2528 2529 default: 2530 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_vpd_msg, 2531 "Unknown block: %x %x %x %x %x %x %x %x", 2532 vpd_buf[index], vpd_buf[index + 1], 2533 vpd_buf[index + 2], vpd_buf[index + 3], 2534 vpd_buf[index + 4], vpd_buf[index + 5], 2535 vpd_buf[index + 6], vpd_buf[index + 7]); 2536 return (0); 2537 } 2538 } 2539 2540 return (1); 2541 2542 } /* emlxs_parse_vpd */ 2543 2544 2545 2546 static uint32_t 2547 emlxs_decode_biu_rev(uint32_t rev) 2548 { 2549 return (rev & 0xf); 2550 } /* End emlxs_decode_biu_rev */ 2551 2552 2553 static uint32_t 2554 emlxs_decode_endec_rev(uint32_t rev) 2555 { 2556 return ((rev >> 28) & 0xf); 2557 } /* End emlxs_decode_endec_rev */ 2558 2559 2560 extern void 2561 emlxs_decode_firmware_rev(emlxs_hba_t *hba, emlxs_vpd_t *vpd) 2562 { 2563 if (vpd->rBit) { 2564 switch (hba->sli_mode) { 2565 case EMLXS_HBA_SLI4_MODE: 2566 (void) strcpy(vpd->fw_version, vpd->sli4FwName); 2567 (void) strcpy(vpd->fw_label, vpd->sli4FwLabel); 2568 break; 2569 case EMLXS_HBA_SLI3_MODE: 2570 (void) strcpy(vpd->fw_version, vpd->sli3FwName); 2571 (void) strcpy(vpd->fw_label, vpd->sli3FwLabel); 2572 break; 2573 case EMLXS_HBA_SLI2_MODE: 2574 (void) strcpy(vpd->fw_version, vpd->sli2FwName); 2575 (void) strcpy(vpd->fw_label, vpd->sli2FwLabel); 2576 break; 2577 case EMLXS_HBA_SLI1_MODE: 2578 (void) strcpy(vpd->fw_version, vpd->sli1FwName); 2579 (void) strcpy(vpd->fw_label, vpd->sli1FwLabel); 2580 break; 2581 default: 2582 (void) strcpy(vpd->fw_version, "unknown"); 2583 (void) strcpy(vpd->fw_label, vpd->fw_version); 2584 } 2585 } else { 2586 emlxs_decode_version(vpd->smFwRev, vpd->fw_version); 2587 (void) strcpy(vpd->fw_label, vpd->fw_version); 2588 } 2589 2590 return; 2591 2592 } /* emlxs_decode_firmware_rev() */ 2593 2594 2595 2596 extern void 2597 emlxs_decode_version(uint32_t version, char *buffer) 2598 { 2599 uint32_t b1, b2, b3, b4; 2600 char c; 2601 2602 b1 = (version & 0x0000f000) >> 12; 2603 b2 = (version & 0x00000f00) >> 8; 2604 b3 = (version & 0x000000c0) >> 6; 2605 b4 = (version & 0x00000030) >> 4; 2606 2607 if (b1 == 0 && b2 == 0) { 2608 (void) sprintf(buffer, "none"); 2609 return; 2610 } 2611 2612 c = 0; 2613 switch (b4) { 2614 case 0: 2615 c = 'n'; 2616 break; 2617 case 1: 2618 c = 'a'; 2619 break; 2620 case 2: 2621 c = 'b'; 2622 break; 2623 case 3: 2624 if ((version & 0x0000000f)) { 2625 c = 'x'; 2626 } 2627 break; 2628 2629 } 2630 b4 = (version & 0x0000000f); 2631 2632 if (c == 0) { 2633 (void) sprintf(buffer, "%d.%d%d", b1, b2, b3); 2634 } else { 2635 (void) sprintf(buffer, "%d.%d%d%c%d", b1, b2, b3, c, b4); 2636 } 2637 2638 return; 2639 2640 } /* emlxs_decode_version() */ 2641 2642 2643 static void 2644 emlxs_decode_label(char *label, char *buffer) 2645 { 2646 uint32_t i; 2647 char name[16]; 2648 #ifdef EMLXS_LITTLE_ENDIAN 2649 uint32_t *wptr; 2650 uint32_t word; 2651 #endif /* EMLXS_LITTLE_ENDIAN */ 2652 2653 bcopy(label, name, 16); 2654 2655 #ifdef EMLXS_LITTLE_ENDIAN 2656 wptr = (uint32_t *)name; 2657 for (i = 0; i < 3; i++) { 2658 word = *wptr; 2659 word = SWAP_DATA32(word); 2660 *wptr++ = word; 2661 } 2662 #endif /* EMLXS_LITTLE_ENDIAN */ 2663 2664 for (i = 0; i < 16; i++) { 2665 if (name[i] == 0x20) { 2666 name[i] = 0; 2667 } 2668 } 2669 2670 (void) strcpy(buffer, name); 2671 2672 return; 2673 2674 } /* emlxs_decode_label() */ 2675 2676 2677 extern uint32_t 2678 emlxs_strtol(char *str, uint32_t base) 2679 { 2680 uint32_t value = 0; 2681 char *ptr; 2682 uint32_t factor = 1; 2683 uint32_t digits; 2684 2685 if (*str == 0) { 2686 return (0); 2687 } 2688 2689 if (base != 10 && base != 16) { 2690 return (0); 2691 } 2692 2693 /* Get max digits of value */ 2694 digits = (base == 10) ? 9 : 8; 2695 2696 /* Position pointer to end of string */ 2697 ptr = str + strlen(str); 2698 2699 /* Process string backwards */ 2700 while ((ptr-- > str) && digits) { 2701 /* check for base 10 numbers */ 2702 if (*ptr >= '0' && *ptr <= '9') { 2703 value += ((uint32_t)(*ptr - '0')) * factor; 2704 factor *= base; 2705 digits--; 2706 } else if (base == 16) { 2707 /* Check for base 16 numbers */ 2708 if (*ptr >= 'a' && *ptr <= 'f') { 2709 value += 2710 ((uint32_t)(*ptr - 'a') + 10) * factor; 2711 factor *= base; 2712 digits--; 2713 } else if (*ptr >= 'A' && *ptr <= 'F') { 2714 value += 2715 ((uint32_t)(*ptr - 'A') + 10) * factor; 2716 factor *= base; 2717 digits--; 2718 } else if (factor > 1) { 2719 break; 2720 } 2721 } else if (factor > 1) { 2722 break; 2723 } 2724 } 2725 2726 return (value); 2727 2728 } /* emlxs_strtol() */ 2729 2730 2731 extern uint64_t 2732 emlxs_strtoll(char *str, uint32_t base) 2733 { 2734 uint64_t value = 0; 2735 char *ptr; 2736 uint32_t factor = 1; 2737 uint32_t digits; 2738 2739 if (*str == 0) { 2740 return (0); 2741 } 2742 2743 if (base != 10 && base != 16) { 2744 return (0); 2745 } 2746 2747 /* Get max digits of value */ 2748 digits = (base == 10) ? 19 : 16; 2749 2750 /* Position pointer to end of string */ 2751 ptr = str + strlen(str); 2752 2753 /* Process string backwards */ 2754 while ((ptr-- > str) && digits) { 2755 /* check for base 10 numbers */ 2756 if (*ptr >= '0' && *ptr <= '9') { 2757 value += ((uint32_t)(*ptr - '0')) * factor; 2758 factor *= base; 2759 digits--; 2760 } else if (base == 16) { 2761 /* Check for base 16 numbers */ 2762 if (*ptr >= 'a' && *ptr <= 'f') { 2763 value += 2764 ((uint32_t)(*ptr - 'a') + 10) * factor; 2765 factor *= base; 2766 digits--; 2767 } else if (*ptr >= 'A' && *ptr <= 'F') { 2768 value += 2769 ((uint32_t)(*ptr - 'A') + 10) * factor; 2770 factor *= base; 2771 digits--; 2772 } else if (factor > 1) { 2773 break; 2774 } 2775 } else if (factor > 1) { 2776 break; 2777 } 2778 } 2779 2780 return (value); 2781 2782 } /* emlxs_strtoll() */ 2783 2784 static void 2785 emlxs_parse_prog_types(emlxs_hba_t *hba, char *prog_types) 2786 { 2787 emlxs_port_t *port = &PPORT; 2788 uint32_t i; 2789 char *ptr; 2790 emlxs_model_t *model; 2791 char types_buffer[256]; 2792 char *types; 2793 2794 bcopy(prog_types, types_buffer, 256); 2795 types = types_buffer; 2796 2797 model = &hba->model_info; 2798 2799 while (*types) { 2800 if (strncmp(types, "T2:", 3) == 0) { 2801 bzero(model->pt_2, sizeof (model->pt_2)); 2802 types += 3; 2803 2804 i = 0; 2805 while (*types && *types != 'T') { 2806 /* Null terminate the next value */ 2807 ptr = types; 2808 while (*ptr && (*ptr != ',')) 2809 ptr++; 2810 *ptr = 0; 2811 2812 /* Save the value */ 2813 model->pt_2[i++] = 2814 (uint8_t)emlxs_strtol(types, 16); 2815 2816 /* 2817 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_vpd_msg, 2818 * "T2[%d]: 0x%x", i-1, model->pt_2[i-1]); 2819 */ 2820 2821 /* Move the str pointer */ 2822 types = ptr + 1; 2823 } 2824 2825 } else if (strncmp(types, "T3:", 3) == 0) { 2826 bzero(model->pt_3, sizeof (model->pt_3)); 2827 types += 3; 2828 2829 i = 0; 2830 while (*types && *types != 'T') { 2831 /* Null terminate the next value */ 2832 ptr = types; 2833 while (*ptr && (*ptr != ',')) 2834 ptr++; 2835 *ptr = 0; 2836 2837 /* Save the value */ 2838 model->pt_3[i++] = 2839 (uint8_t)emlxs_strtol(types, 16); 2840 2841 /* 2842 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_vpd_msg, 2843 * "T3[%d]: 0x%x", i-1, model->pt_3[i-1]); 2844 */ 2845 2846 /* Move the str pointer */ 2847 types = ptr + 1; 2848 } 2849 } else if (strncmp(types, "T6:", 3) == 0) { 2850 bzero(model->pt_6, sizeof (model->pt_6)); 2851 types += 3; 2852 2853 i = 0; 2854 while (*types && *types != 'T') { 2855 /* Null terminate the next value */ 2856 ptr = types; 2857 while (*ptr && (*ptr != ',')) 2858 ptr++; 2859 *ptr = 0; 2860 2861 /* Save the value */ 2862 model->pt_6[i++] = 2863 (uint8_t)emlxs_strtol(types, 16); 2864 model->pt_6[i] = 0; 2865 2866 /* 2867 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_vpd_msg, 2868 * "T6[%d]: 0x%x", i-1, model->pt_6[i-1]); 2869 */ 2870 2871 /* Move the str pointer */ 2872 types = ptr + 1; 2873 } 2874 } else if (strncmp(types, "T7:", 3) == 0) { 2875 bzero(model->pt_7, sizeof (model->pt_7)); 2876 types += 3; 2877 2878 i = 0; 2879 while (*types && *types != 'T') { 2880 /* Null terminate the next value */ 2881 ptr = types; 2882 while (*ptr && (*ptr != ',')) 2883 ptr++; 2884 *ptr = 0; 2885 2886 /* Save the value */ 2887 model->pt_7[i++] = 2888 (uint8_t)emlxs_strtol(types, 16); 2889 model->pt_7[i] = 0; 2890 2891 /* 2892 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_vpd_msg, 2893 * "T7[%d]: 0x%x", i-1, model->pt_7[i-1]); 2894 */ 2895 2896 /* Move the str pointer */ 2897 types = ptr + 1; 2898 } 2899 } else if (strncmp(types, "TA:", 3) == 0) { 2900 bzero(model->pt_A, sizeof (model->pt_A)); 2901 types += 3; 2902 2903 i = 0; 2904 while (*types && *types != 'T') { 2905 /* Null terminate the next value */ 2906 ptr = types; 2907 while (*ptr && (*ptr != ',')) 2908 ptr++; 2909 *ptr = 0; 2910 2911 /* Save the value */ 2912 model->pt_A[i++] = 2913 (uint8_t)emlxs_strtol(types, 16); 2914 2915 /* 2916 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_vpd_msg, 2917 * "TA[%d]: 0x%x", i-1, model->pt_A[i-1]); 2918 */ 2919 2920 /* Move the str pointer */ 2921 types = ptr + 1; 2922 } 2923 } else if (strncmp(types, "TB:", 3) == 0) { 2924 bzero(model->pt_B, sizeof (model->pt_B)); 2925 types += 3; 2926 2927 i = 0; 2928 while (*types && *types != 'T') { 2929 /* Null terminate the next value */ 2930 ptr = types; 2931 while (*ptr && (*ptr != ',')) 2932 ptr++; 2933 *ptr = 0; 2934 2935 /* Save the value */ 2936 model->pt_B[i++] = 2937 (uint8_t)emlxs_strtol(types, 16); 2938 2939 /* 2940 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_vpd_msg, 2941 * "TB[%d]: 0x%x", i-1, model->pt_B[i-1]); 2942 */ 2943 2944 /* Move the str pointer */ 2945 types = ptr + 1; 2946 } 2947 } else if (strncmp(types, "TFF:", 4) == 0) { 2948 bzero(model->pt_FF, sizeof (model->pt_FF)); 2949 types += 4; 2950 2951 i = 0; 2952 while (*types && *types != 'T') { 2953 /* Null terminate the next value */ 2954 ptr = types; 2955 while (*ptr && (*ptr != ',')) 2956 ptr++; 2957 *ptr = 0; 2958 2959 /* Save the value */ 2960 model->pt_FF[i++] = 2961 (uint8_t)emlxs_strtol(types, 16); 2962 2963 /* 2964 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_vpd_msg, 2965 * "TF[%d]: 0x%x", i-1, model->pt_FF[i-1]); 2966 */ 2967 2968 /* Move the str pointer */ 2969 types = ptr + 1; 2970 } 2971 } else if (strncmp(types, "T20:", 4) == 0) { 2972 bzero(model->pt_20, sizeof (model->pt_20)); 2973 types += 4; 2974 2975 i = 0; 2976 while (*types && *types != 'T') { 2977 /* Null terminate the next value */ 2978 ptr = types; 2979 while (*ptr && (*ptr != ',')) 2980 ptr++; 2981 *ptr = 0; 2982 2983 /* Save the value */ 2984 model->pt_20[i++] = 2985 (uint8_t)emlxs_strtol(types, 16); 2986 model->pt_20[i] = 0; 2987 2988 /* 2989 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_vpd_msg, 2990 * "T20[%d]: 0x%x", i-1, model->pt_20[i-1]); 2991 */ 2992 2993 /* Move the str pointer */ 2994 types = ptr + 1; 2995 } 2996 } else { 2997 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_vpd_msg, 2998 "Unknown prog type string = %s", types); 2999 break; 3000 } 3001 } 3002 3003 return; 3004 3005 } /* emlxs_parse_prog_types() */ 3006 3007 3008 static void 3009 emlxs_build_prog_types(emlxs_hba_t *hba, char *prog_types) 3010 { 3011 uint32_t i; 3012 uint32_t found = 0; 3013 char buffer[256]; 3014 3015 bzero(prog_types, 256); 3016 3017 /* Rebuild the prog type string */ 3018 if (hba->model_info.pt_2[0]) { 3019 (void) strcat(prog_types, "T2:"); 3020 found = 1; 3021 3022 i = 0; 3023 while (hba->model_info.pt_2[i] && i < 8) { 3024 (void) sprintf(buffer, "%X,", hba->model_info.pt_2[i]); 3025 (void) strcat(prog_types, buffer); 3026 i++; 3027 } 3028 } 3029 3030 if (hba->model_info.pt_3[0]) { 3031 (void) strcat(prog_types, "T3:"); 3032 found = 1; 3033 3034 i = 0; 3035 while (hba->model_info.pt_3[i] && i < 8) { 3036 (void) sprintf(buffer, "%X,", hba->model_info.pt_3[i]); 3037 (void) strcat(prog_types, buffer); 3038 i++; 3039 3040 } 3041 } 3042 3043 if (hba->model_info.pt_6[0]) { 3044 (void) strcat(prog_types, "T6:"); 3045 found = 1; 3046 3047 i = 0; 3048 while (hba->model_info.pt_6[i] && i < 8) { 3049 (void) sprintf(buffer, "%X,", hba->model_info.pt_6[i]); 3050 (void) strcat(prog_types, buffer); 3051 i++; 3052 } 3053 } 3054 3055 if (hba->model_info.pt_7[0]) { 3056 (void) strcat(prog_types, "T7:"); 3057 found = 1; 3058 3059 i = 0; 3060 while (hba->model_info.pt_7[i] && i < 8) { 3061 (void) sprintf(buffer, "%X,", hba->model_info.pt_7[i]); 3062 (void) strcat(prog_types, buffer); 3063 i++; 3064 } 3065 } 3066 3067 if (hba->model_info.pt_A[0]) { 3068 (void) strcat(prog_types, "TA:"); 3069 found = 1; 3070 3071 i = 0; 3072 while (hba->model_info.pt_A[i] && i < 8) { 3073 (void) sprintf(buffer, "%X,", hba->model_info.pt_A[i]); 3074 (void) strcat(prog_types, buffer); 3075 i++; 3076 } 3077 } 3078 3079 3080 if (hba->model_info.pt_B[0]) { 3081 (void) strcat(prog_types, "TB:"); 3082 found = 1; 3083 3084 i = 0; 3085 while (hba->model_info.pt_B[i] && i < 8) { 3086 (void) sprintf(buffer, "%X,", hba->model_info.pt_B[i]); 3087 (void) strcat(prog_types, buffer); 3088 i++; 3089 } 3090 } 3091 3092 if (hba->model_info.pt_20[0]) { 3093 (void) strcat(prog_types, "T20:"); 3094 found = 1; 3095 3096 i = 0; 3097 while (hba->model_info.pt_20[i] && i < 8) { 3098 (void) sprintf(buffer, "%X,", hba->model_info.pt_20[i]); 3099 (void) strcat(prog_types, buffer); 3100 i++; 3101 } 3102 } 3103 3104 if (hba->model_info.pt_FF[0]) { 3105 (void) strcat(prog_types, "TFF:"); 3106 found = 1; 3107 3108 i = 0; 3109 while (hba->model_info.pt_FF[i] && i < 8) { 3110 (void) sprintf(buffer, "%X,", hba->model_info.pt_FF[i]); 3111 (void) strcat(prog_types, buffer); 3112 i++; 3113 } 3114 } 3115 3116 if (found) { 3117 /* Terminate at the last comma in string */ 3118 prog_types[(strlen(prog_types) - 1)] = 0; 3119 } 3120 3121 return; 3122 3123 } /* emlxs_build_prog_types() */ 3124 3125 3126 3127 3128 extern uint32_t 3129 emlxs_init_adapter_info(emlxs_hba_t *hba) 3130 { 3131 emlxs_port_t *port = &PPORT; 3132 uint32_t pci_id; 3133 uint32_t cache_line; 3134 uint32_t channels; 3135 uint16_t device_id; 3136 uint16_t ssdid; 3137 uint32_t i; 3138 uint32_t found = 0; 3139 3140 if (hba->bus_type == SBUS_FC) { 3141 if (hba->pci_acc_handle == NULL) { 3142 bcopy(&emlxs_sbus_model[0], &hba->model_info, 3143 sizeof (emlxs_model_t)); 3144 3145 hba->model_info.device_id = 0; 3146 3147 return (0); 3148 } 3149 3150 /* Read the PCI device id */ 3151 pci_id = 3152 ddi_get32(hba->pci_acc_handle, 3153 (uint32_t *)(hba->pci_addr + PCI_VENDOR_ID_REGISTER)); 3154 device_id = (uint16_t)(pci_id >> 16); 3155 3156 /* Find matching adapter model */ 3157 for (i = 1; i < EMLXS_SBUS_MODEL_COUNT; i++) { 3158 if (emlxs_sbus_model[i].device_id == device_id) { 3159 bcopy(&emlxs_sbus_model[i], &hba->model_info, 3160 sizeof (emlxs_model_t)); 3161 found = 1; 3162 break; 3163 } 3164 } 3165 3166 /* If not found then use the unknown model */ 3167 if (!found) { 3168 bcopy(&emlxs_sbus_model[0], &hba->model_info, 3169 sizeof (emlxs_model_t)); 3170 3171 hba->model_info.device_id = device_id; 3172 3173 return (0); 3174 } 3175 } else { /* PCI model */ 3176 3177 if (hba->pci_acc_handle == NULL) { 3178 bcopy(&emlxs_pci_model[0], &hba->model_info, 3179 sizeof (emlxs_model_t)); 3180 3181 hba->model_info.device_id = 0; 3182 3183 return (0); 3184 } 3185 3186 /* Read the PCI device id */ 3187 device_id = 3188 ddi_get16(hba->pci_acc_handle, 3189 (uint16_t *)(hba->pci_addr + PCI_DEVICE_ID_REGISTER)); 3190 3191 /* Read the PCI Subsystem id */ 3192 ssdid = 3193 ddi_get16(hba->pci_acc_handle, 3194 (uint16_t *)(hba->pci_addr + PCI_SSDID_REGISTER)); 3195 3196 if (ssdid == 0 || ssdid == 0xffff) { 3197 ssdid = device_id; 3198 } 3199 3200 /* Read the Cache Line reg */ 3201 cache_line = 3202 ddi_get32(hba->pci_acc_handle, 3203 (uint32_t *)(hba->pci_addr + PCI_CACHE_LINE_REGISTER)); 3204 3205 /* Check for the multifunction bit being set */ 3206 if ((cache_line & 0x00ff0000) == 0x00800000) { 3207 channels = 2; 3208 } else { 3209 channels = 1; 3210 } 3211 3212 /* If device ids are unique, then use them for search */ 3213 if (device_id != ssdid) { 3214 if (channels > 1) { 3215 /* 3216 * Find matching adapter model using 3217 * device_id, ssdid and channels 3218 */ 3219 for (i = 1; i < EMLXS_PCI_MODEL_COUNT; i++) { 3220 if (emlxs_pci_model[i].device_id == 3221 device_id && 3222 emlxs_pci_model[i].ssdid == ssdid && 3223 emlxs_pci_model[i].channels == 3224 channels) { 3225 bcopy(&emlxs_pci_model[i], 3226 &hba->model_info, 3227 sizeof (emlxs_model_t)); 3228 found = 1; 3229 break; 3230 } 3231 } 3232 } else { 3233 /* 3234 * Find matching adapter model using 3235 * device_id and ssdid 3236 */ 3237 for (i = 1; i < EMLXS_PCI_MODEL_COUNT; i++) { 3238 if (emlxs_pci_model[i].device_id == 3239 device_id && 3240 emlxs_pci_model[i].ssdid == ssdid) { 3241 bcopy(&emlxs_pci_model[i], 3242 &hba->model_info, 3243 sizeof (emlxs_model_t)); 3244 found = 1; 3245 break; 3246 } 3247 } 3248 } 3249 } 3250 3251 /* If adapter not found, try again */ 3252 if (!found) { 3253 /* Find matching adapter model */ 3254 for (i = 1; i < EMLXS_PCI_MODEL_COUNT; i++) { 3255 if (emlxs_pci_model[i].device_id == device_id && 3256 emlxs_pci_model[i].channels == channels) { 3257 bcopy(&emlxs_pci_model[i], 3258 &hba->model_info, 3259 sizeof (emlxs_model_t)); 3260 found = 1; 3261 break; 3262 } 3263 } 3264 } 3265 3266 /* If adapter not found, try one last time */ 3267 if (!found) { 3268 /* Find matching adapter model */ 3269 for (i = 1; i < EMLXS_PCI_MODEL_COUNT; i++) { 3270 if (emlxs_pci_model[i].device_id == device_id) { 3271 bcopy(&emlxs_pci_model[i], 3272 &hba->model_info, 3273 sizeof (emlxs_model_t)); 3274 found = 1; 3275 break; 3276 } 3277 } 3278 } 3279 3280 /* If not found, set adapter to unknown */ 3281 if (!found) { 3282 bcopy(&emlxs_pci_model[0], &hba->model_info, 3283 sizeof (emlxs_model_t)); 3284 3285 hba->model_info.device_id = device_id; 3286 hba->model_info.ssdid = ssdid; 3287 3288 return (0); 3289 } 3290 3291 #ifndef SATURN_MSI_SUPPORT 3292 /* 3293 * This will disable MSI support for Saturn adapter's 3294 * due to a PCI bus issue 3295 */ 3296 if (hba->model_info.chip == EMLXS_SATURN_CHIP) { 3297 hba->model_info.flags &= 3298 ~(EMLXS_MSI_SUPPORTED | EMLXS_MSIX_SUPPORTED); 3299 } 3300 #endif /* !SATURN_MSI_SUPPORT */ 3301 3302 3303 #ifdef MSI_SUPPORT 3304 /* Verify MSI support */ 3305 if (hba->model_info.flags & EMLXS_MSI_SUPPORTED) { 3306 uint32_t offset; 3307 uint32_t reg; 3308 3309 /* Scan for MSI capabilities register */ 3310 offset = 3311 ddi_get32(hba->pci_acc_handle, 3312 (uint32_t *)(hba->pci_addr + PCI_CAP_POINTER)); 3313 offset &= 0xff; 3314 3315 while (offset) { 3316 reg = 3317 ddi_get32(hba->pci_acc_handle, 3318 (uint32_t *)(hba->pci_addr + offset)); 3319 3320 if ((reg & 0xff) == MSI_CAP_ID) { 3321 break; 3322 } 3323 offset = (reg >> 8) & 0xff; 3324 } 3325 3326 if (offset) { 3327 hba->msi_cap_offset = offset + 2; 3328 } else { 3329 hba->msi_cap_offset = 0; 3330 hba->model_info.flags &= ~EMLXS_MSI_SUPPORTED; 3331 3332 EMLXS_MSGF(EMLXS_CONTEXT, 3333 &emlxs_init_debug_msg, 3334 "MSI: control_reg capability not found!"); 3335 } 3336 } 3337 3338 /* Verify MSI-X support */ 3339 if (hba->model_info.flags & EMLXS_MSIX_SUPPORTED) { 3340 uint32_t offset; 3341 uint32_t reg; 3342 3343 /* Scan for MSI capabilities register */ 3344 offset = 3345 ddi_get32(hba->pci_acc_handle, 3346 (uint32_t *)(hba->pci_addr + PCI_CAP_POINTER)); 3347 offset &= 0xff; 3348 3349 while (offset) { 3350 reg = 3351 ddi_get32(hba->pci_acc_handle, 3352 (uint32_t *)(hba->pci_addr + offset)); 3353 3354 if ((reg & 0xff) == MSIX_CAP_ID) { 3355 break; 3356 } 3357 offset = (reg >> 8) & 0xff; 3358 } 3359 3360 if (offset) { 3361 hba->msix_cap_offset = offset; 3362 } else { 3363 hba->msix_cap_offset = 0; 3364 hba->model_info.flags &= 3365 ~EMLXS_MSIX_SUPPORTED; 3366 3367 EMLXS_MSGF(EMLXS_CONTEXT, 3368 &emlxs_init_debug_msg, 3369 "MSIX: control_reg capability not found!"); 3370 } 3371 } 3372 #endif /* MSI_SUPPORT */ 3373 3374 } 3375 3376 #ifdef FMA_SUPPORT 3377 if (emlxs_fm_check_acc_handle(hba, hba->pci_acc_handle) 3378 != DDI_FM_OK) { 3379 EMLXS_MSGF(EMLXS_CONTEXT, 3380 &emlxs_invalid_access_handle_msg, NULL); 3381 return (0); 3382 } 3383 #endif /* FMA_SUPPORT */ 3384 3385 if (hba->model_info.sli_mask & EMLXS_SLI4_MASK) { 3386 return (0); 3387 } 3388 3389 /* For now we just support SLI2 and SLI3 */ 3390 hba->emlxs_sli_api_map_hdw = emlxs_sli3_map_hdw; 3391 hba->emlxs_sli_api_unmap_hdw = emlxs_sli3_unmap_hdw; 3392 hba->emlxs_sli_api_online = emlxs_sli3_online; 3393 hba->emlxs_sli_api_offline = emlxs_sli3_offline; 3394 hba->emlxs_sli_api_hba_reset = emlxs_sli3_hba_reset; 3395 hba->emlxs_sli_api_issue_iocb_cmd = emlxs_sli3_issue_iocb_cmd; 3396 hba->emlxs_sli_api_issue_mbox_cmd = emlxs_sli3_issue_mbox_cmd; 3397 #ifdef SFCT_SUPPORT 3398 hba->emlxs_sli_api_prep_fct_iocb = emlxs_sli3_prep_fct_iocb; 3399 #endif /* SFCT_SUPPORT */ 3400 hba->emlxs_sli_api_prep_fcp_iocb = emlxs_sli3_prep_fcp_iocb; 3401 hba->emlxs_sli_api_prep_ip_iocb = emlxs_sli3_prep_ip_iocb; 3402 hba->emlxs_sli_api_prep_els_iocb = emlxs_sli3_prep_els_iocb; 3403 hba->emlxs_sli_api_prep_ct_iocb = emlxs_sli3_prep_ct_iocb; 3404 hba->emlxs_sli_api_poll_intr = emlxs_sli3_poll_intr; 3405 hba->emlxs_sli_api_intx_intr = emlxs_sli3_intx_intr; 3406 hba->emlxs_sli_api_msi_intr = emlxs_sli3_msi_intr; 3407 return (1); 3408 3409 } /* emlxs_init_adapter_info() */ 3410 3411 3412 /* ARGSUSED */ 3413 static void 3414 emlxs_handle_async_event(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq) 3415 { 3416 emlxs_port_t *port = &PPORT; 3417 IOCB *iocb; 3418 uint32_t *w; 3419 int i, j; 3420 3421 iocb = &iocbq->iocb; 3422 3423 if (iocb->ulpStatus != 0) { 3424 return; 3425 } 3426 3427 switch (iocb->un.astat.EventCode) { 3428 case 0x0100: /* Temp Warning */ 3429 3430 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_temp_warning_msg, 3431 "Adapter is very hot (%d �C). Take corrective action.", 3432 iocb->ulpContext); 3433 3434 emlxs_log_temp_event(port, 0x02, iocb->ulpContext); 3435 3436 break; 3437 3438 3439 case 0x0101: /* Temp Safe */ 3440 3441 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_temp_msg, 3442 "Adapter temperature now safe (%d �C).", 3443 iocb->ulpContext); 3444 3445 emlxs_log_temp_event(port, 0x03, iocb->ulpContext); 3446 3447 break; 3448 3449 default: 3450 3451 w = (uint32_t *)iocb; 3452 for (i = 0, j = 0; i < 8; i++, j += 2) { 3453 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_async_msg, 3454 "(Word[%d]=%x Word[%d]=%x)", j, w[j], j + 1, 3455 w[j + 1]); 3456 } 3457 3458 emlxs_log_async_event(port, iocb); 3459 } 3460 3461 return; 3462 3463 } /* emlxs_handle_async_event() */ 3464 3465 3466 /* ARGSUSED */ 3467 extern void 3468 emlxs_reset_link_thread(emlxs_hba_t *hba, void *arg1, void *arg2) 3469 { 3470 emlxs_port_t *port = &PPORT; 3471 3472 /* Attempt a link reset to recover */ 3473 (void) emlxs_reset(port, FC_FCA_LINK_RESET); 3474 3475 return; 3476 3477 } /* emlxs_reset_link_thread() */ 3478 3479 3480 /* ARGSUSED */ 3481 extern void 3482 emlxs_restart_thread(emlxs_hba_t *hba, void *arg1, void *arg2) 3483 { 3484 emlxs_port_t *port = &PPORT; 3485 3486 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_adapter_trans_msg, "Restarting..."); 3487 3488 /* Attempt a full hardware reset to recover */ 3489 if (emlxs_reset(port, FC_FCA_RESET) != FC_SUCCESS) { 3490 emlxs_ffstate_change(hba, FC_ERROR); 3491 3492 (void) thread_create(NULL, 0, emlxs_shutdown_thread, 3493 (char *)hba, 0, &p0, TS_RUN, v.v_maxsyspri - 2); 3494 } 3495 3496 return; 3497 3498 } /* emlxs_restart_thread() */ 3499 3500 3501 /* ARGSUSED */ 3502 extern void 3503 emlxs_shutdown_thread(emlxs_hba_t *hba, void *arg1, void *arg2) 3504 { 3505 emlxs_port_t *port = &PPORT; 3506 3507 mutex_enter(&EMLXS_PORT_LOCK); 3508 if (hba->flag & FC_SHUTDOWN) { 3509 mutex_exit(&EMLXS_PORT_LOCK); 3510 return; 3511 } 3512 hba->flag |= FC_SHUTDOWN; 3513 mutex_exit(&EMLXS_PORT_LOCK); 3514 3515 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_adapter_trans_msg, 3516 "Shutting down..."); 3517 3518 /* Take adapter offline and leave it there */ 3519 (void) emlxs_offline(hba); 3520 3521 /* Log a dump event */ 3522 emlxs_log_dump_event(port, NULL, 0); 3523 3524 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_shutdown_msg, "Reboot required."); 3525 3526 return; 3527 3528 } /* emlxs_shutdown_thread() */ 3529 3530 3531 /* ARGSUSED */ 3532 extern void 3533 emlxs_proc_ring(emlxs_hba_t *hba, RING *rp, void *arg2) 3534 { 3535 IOCBQ *iocbq; 3536 IOCBQ *rsp_head; 3537 3538 /* 3539 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3540 * "emlxs_proc_ring: ringo=%d", rp->ringno); 3541 */ 3542 3543 mutex_enter(&rp->rsp_lock); 3544 3545 while ((rsp_head = rp->rsp_head) != NULL) { 3546 rp->rsp_head = NULL; 3547 rp->rsp_tail = NULL; 3548 3549 mutex_exit(&rp->rsp_lock); 3550 3551 while ((iocbq = rsp_head) != NULL) { 3552 rsp_head = (IOCBQ *) iocbq->next; 3553 3554 emlxs_proc_ring_event(hba, rp, iocbq); 3555 } 3556 3557 mutex_enter(&rp->rsp_lock); 3558 } 3559 3560 mutex_exit(&rp->rsp_lock); 3561 3562 emlxs_sli_issue_iocb_cmd(hba, rp, 0); 3563 3564 return; 3565 3566 } /* emlxs_proc_ring() */ 3567 3568 3569 /* 3570 * Called from SLI ring event routines to process a rsp ring IOCB. 3571 */ 3572 void 3573 emlxs_proc_ring_event(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq) 3574 { 3575 emlxs_port_t *port = &PPORT; 3576 char buffer[MAX_MSG_DATA + 1]; 3577 IOCB *iocb; 3578 3579 iocb = &iocbq->iocb; 3580 3581 /* Check for IOCB local error */ 3582 if (iocb->ulpStatus == IOSTAT_LOCAL_REJECT) { 3583 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_iocb_event_msg, 3584 "Local reject. ringno=%d iocb=%p cmd=%x " 3585 "iotag=%x context=%x info=%x error=%x", 3586 rp->ringno, iocb, (uint8_t)iocb->ulpCommand, 3587 (uint16_t)iocb->ulpIoTag, (uint16_t)iocb->ulpContext, 3588 (uint8_t)iocb->ulpRsvdByte, 3589 (uint8_t)iocb->un.grsp.perr.statLocalError); 3590 } else if (iocb->ulpStatus == IOSTAT_ILLEGAL_FRAME_RCVD) { 3591 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_iocb_event_msg, 3592 "Illegal frame. ringno=%d iocb=%p cmd=%x " 3593 "iotag=%x context=%x info=%x error=%x", 3594 rp->ringno, iocb, (uint8_t)iocb->ulpCommand, 3595 (uint16_t)iocb->ulpIoTag, (uint16_t)iocb->ulpContext, 3596 (uint8_t)iocb->ulpRsvdByte, 3597 (uint8_t)iocb->un.grsp.perr.statLocalError); 3598 } 3599 3600 switch (iocb->ulpCommand) { 3601 /* RING 0 FCP commands */ 3602 case CMD_FCP_ICMND_CR: 3603 case CMD_FCP_ICMND_CX: 3604 case CMD_FCP_IREAD_CR: 3605 case CMD_FCP_IREAD_CX: 3606 case CMD_FCP_IWRITE_CR: 3607 case CMD_FCP_IWRITE_CX: 3608 case CMD_FCP_ICMND64_CR: 3609 case CMD_FCP_ICMND64_CX: 3610 case CMD_FCP_IREAD64_CR: 3611 case CMD_FCP_IREAD64_CX: 3612 case CMD_FCP_IWRITE64_CR: 3613 case CMD_FCP_IWRITE64_CX: 3614 emlxs_handle_fcp_event(hba, rp, iocbq); 3615 break; 3616 3617 #ifdef SFCT_SUPPORT 3618 case CMD_FCP_TSEND_CX: /* FCP_TARGET IOCB command */ 3619 case CMD_FCP_TSEND64_CX: /* FCP_TARGET IOCB command */ 3620 case CMD_FCP_TRECEIVE_CX: /* FCP_TARGET IOCB command */ 3621 case CMD_FCP_TRECEIVE64_CX: /* FCP_TARGET IOCB command */ 3622 case CMD_FCP_TRSP_CX: /* FCP_TARGET IOCB command */ 3623 case CMD_FCP_TRSP64_CX: /* FCP_TARGET IOCB command */ 3624 (void) emlxs_fct_handle_fcp_event(hba, rp, iocbq); 3625 break; 3626 #endif /* SFCT_SUPPORT */ 3627 3628 /* RING 1 IP commands */ 3629 case CMD_XMIT_BCAST_CN: 3630 case CMD_XMIT_BCAST_CX: 3631 case CMD_XMIT_BCAST64_CN: 3632 case CMD_XMIT_BCAST64_CX: 3633 (void) emlxs_ip_handle_event(hba, rp, iocbq); 3634 break; 3635 3636 case CMD_XMIT_SEQUENCE_CX: 3637 case CMD_XMIT_SEQUENCE_CR: 3638 case CMD_XMIT_SEQUENCE64_CX: 3639 case CMD_XMIT_SEQUENCE64_CR: 3640 switch (iocb->un.rcvseq64.w5.hcsw.Type) { 3641 case FC_TYPE_IS8802_SNAP: 3642 (void) emlxs_ip_handle_event(hba, rp, iocbq); 3643 break; 3644 3645 case FC_TYPE_FC_SERVICES: 3646 (void) emlxs_ct_handle_event(hba, rp, iocbq); 3647 break; 3648 3649 default: 3650 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_iocb_invalid_msg, 3651 "cmd=%x type=%x status=%x iotag=%x context=%x ", 3652 iocb->ulpCommand, iocb->un.rcvseq64.w5.hcsw.Type, 3653 iocb->ulpStatus, iocb->ulpIoTag, 3654 iocb->ulpContext); 3655 } 3656 break; 3657 3658 case CMD_RCV_SEQUENCE_CX: 3659 case CMD_RCV_SEQUENCE64_CX: 3660 case CMD_RCV_SEQ64_CX: 3661 case CMD_RCV_ELS_REQ_CX: /* Unsolicited ELS frame */ 3662 case CMD_RCV_ELS_REQ64_CX: /* Unsolicited ELS frame */ 3663 case CMD_RCV_ELS64_CX: /* Unsolicited ELS frame */ 3664 (void) emlxs_handle_rcv_seq(hba, rp, iocbq); 3665 break; 3666 3667 case CMD_RCV_SEQ_LIST64_CX: 3668 (void) emlxs_ip_handle_rcv_seq_list(hba, rp, iocbq); 3669 break; 3670 3671 case CMD_CREATE_XRI_CR: 3672 case CMD_CREATE_XRI_CX: 3673 (void) emlxs_handle_create_xri(hba, rp, iocbq); 3674 break; 3675 3676 /* RING 2 ELS commands */ 3677 case CMD_ELS_REQUEST_CR: 3678 case CMD_ELS_REQUEST_CX: 3679 case CMD_XMIT_ELS_RSP_CX: 3680 case CMD_ELS_REQUEST64_CR: 3681 case CMD_ELS_REQUEST64_CX: 3682 case CMD_XMIT_ELS_RSP64_CX: 3683 (void) emlxs_els_handle_event(hba, rp, iocbq); 3684 break; 3685 3686 /* RING 3 CT commands */ 3687 case CMD_GEN_REQUEST64_CR: 3688 case CMD_GEN_REQUEST64_CX: 3689 switch (iocb->un.rcvseq64.w5.hcsw.Type) { 3690 #ifdef MENLO_SUPPORT 3691 case EMLXS_MENLO_TYPE: 3692 (void) emlxs_menlo_handle_event(hba, rp, iocbq); 3693 break; 3694 #endif /* MENLO_SUPPORT */ 3695 3696 case FC_TYPE_FC_SERVICES: 3697 (void) emlxs_ct_handle_event(hba, rp, iocbq); 3698 break; 3699 3700 default: 3701 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_iocb_invalid_msg, 3702 "cmd=%x type=%x status=%x iotag=%x context=%x ", 3703 iocb->ulpCommand, iocb->un.rcvseq64.w5.hcsw.Type, 3704 iocb->ulpStatus, iocb->ulpIoTag, 3705 iocb->ulpContext); 3706 } 3707 break; 3708 3709 case CMD_ABORT_XRI_CN: /* Abort fcp command */ 3710 3711 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_flushed_msg, 3712 "ABORT_XRI_CN: rpi=%d iotag=%x status=%x parm=%x", 3713 (uint32_t)iocb->un.acxri.abortContextTag, 3714 (uint32_t)iocb->un.acxri.abortIoTag, iocb->ulpStatus, 3715 iocb->un.acxri.parm); 3716 3717 #ifdef SFCT_SUPPORT 3718 if (port->tgt_mode) { 3719 (void) emlxs_fct_handle_abort(hba, rp, iocbq); 3720 } 3721 #endif /* SFCT_SUPPORT */ 3722 break; 3723 3724 case CMD_ABORT_XRI_CX: /* Abort command */ 3725 3726 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_flushed_msg, 3727 "ABORT_XRI_CX: rpi=%d iotag=%x status=%x parm=%x sbp=%p", 3728 (uint32_t)iocb->un.acxri.abortContextTag, 3729 (uint32_t)iocb->un.acxri.abortIoTag, iocb->ulpStatus, 3730 iocb->un.acxri.parm, iocbq->sbp); 3731 3732 #ifdef SFCT_SUPPORT 3733 if (port->tgt_mode) { 3734 (void) emlxs_fct_handle_abort(hba, rp, iocbq); 3735 } 3736 #endif /* SFCT_SUPPORT */ 3737 break; 3738 3739 case CMD_XRI_ABORTED_CX: /* Handle ABORT condition */ 3740 3741 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_flushed_msg, 3742 "XRI_ABORTED_CX: rpi=%d iotag=%x status=%x parm=%x", 3743 (uint32_t)iocb->un.acxri.abortContextTag, 3744 (uint32_t)iocb->un.acxri.abortIoTag, iocb->ulpStatus, 3745 iocb->un.acxri.parm); 3746 3747 #ifdef SFCT_SUPPORT 3748 if (port->tgt_mode) { 3749 (void) emlxs_fct_handle_abort(hba, rp, iocbq); 3750 } 3751 #endif /* SFCT_SUPPORT */ 3752 break; 3753 3754 case CMD_CLOSE_XRI_CN: /* Handle CLOSE condition */ 3755 3756 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_flushed_msg, 3757 "CLOSE_XRI_CR: rpi=%d iotag=%x status=%x parm=%x", 3758 (uint32_t)iocb->un.acxri.abortContextTag, 3759 (uint32_t)iocb->un.acxri.abortIoTag, iocb->ulpStatus, 3760 iocb->un.acxri.parm); 3761 3762 #ifdef SFCT_SUPPORT 3763 if (port->tgt_mode) { 3764 (void) emlxs_fct_handle_abort(hba, rp, iocbq); 3765 } 3766 #endif /* SFCT_SUPPORT */ 3767 break; 3768 3769 case CMD_CLOSE_XRI_CX: /* Handle CLOSE condition */ 3770 3771 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_flushed_msg, 3772 "CLOSE_XRI_CX: rpi=%d iotag=%x status=%x parm=%x sbp=%p", 3773 (uint32_t)iocb->un.acxri.abortContextTag, 3774 (uint32_t)iocb->un.acxri.abortIoTag, iocb->ulpStatus, 3775 iocb->un.acxri.parm, iocbq->sbp); 3776 3777 #ifdef SFCT_SUPPORT 3778 if (port->tgt_mode) { 3779 (void) emlxs_fct_handle_abort(hba, rp, iocbq); 3780 } 3781 #endif /* SFCT_SUPPORT */ 3782 break; 3783 3784 case CMD_ADAPTER_MSG: 3785 /* Allows debug adapter firmware messages to print on host */ 3786 bzero(buffer, sizeof (buffer)); 3787 bcopy((uint8_t *)iocb, buffer, MAX_MSG_DATA); 3788 3789 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_adapter_msg, "%s", buffer); 3790 3791 break; 3792 3793 case CMD_QUE_RING_LIST64_CN: 3794 case CMD_QUE_RING_BUF64_CN: 3795 break; 3796 3797 case CMD_ASYNC_STATUS: 3798 emlxs_handle_async_event(hba, rp, iocbq); 3799 break; 3800 3801 default: 3802 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_iocb_invalid_msg, 3803 "cmd=%x status=%x iotag=%x context=%x", iocb->ulpCommand, 3804 iocb->ulpStatus, iocb->ulpIoTag, iocb->ulpContext); 3805 3806 break; 3807 } /* switch(entry->ulpCommand) */ 3808 3809 return; 3810 3811 } /* emlxs_proc_ring_event() */ 3812 3813 3814 3815 extern char * 3816 emlxs_ffstate_xlate(uint32_t state) 3817 { 3818 static char buffer[32]; 3819 uint32_t i; 3820 uint32_t count; 3821 3822 count = sizeof (emlxs_ffstate_table) / sizeof (emlxs_table_t); 3823 for (i = 0; i < count; i++) { 3824 if (state == emlxs_ffstate_table[i].code) { 3825 return (emlxs_ffstate_table[i].string); 3826 } 3827 } 3828 3829 (void) sprintf(buffer, "state=0x%x", state); 3830 return (buffer); 3831 3832 } /* emlxs_ffstate_xlate() */ 3833 3834 3835 extern char * 3836 emlxs_ring_xlate(uint32_t ringno) 3837 { 3838 static char buffer[32]; 3839 uint32_t i; 3840 uint32_t count; 3841 3842 count = sizeof (emlxs_ring_table) / sizeof (emlxs_table_t); 3843 for (i = 0; i < count; i++) { 3844 if (ringno == emlxs_ring_table[i].code) { 3845 return (emlxs_ring_table[i].string); 3846 } 3847 } 3848 3849 (void) sprintf(buffer, "ring=0x%x", ringno); 3850 return (buffer); 3851 3852 } /* emlxs_ring_xlate() */ 3853 3854 3855 3856 extern void 3857 emlxs_pcix_mxr_update(emlxs_hba_t *hba, uint32_t verbose) 3858 { 3859 emlxs_port_t *port = &PPORT; 3860 MAILBOX *mb; 3861 emlxs_config_t *cfg; 3862 uint32_t value; 3863 3864 cfg = &CFG; 3865 3866 xlate: 3867 3868 switch (cfg[CFG_PCI_MAX_READ].current) { 3869 case 512: 3870 value = 0; 3871 break; 3872 3873 case 1024: 3874 value = 1; 3875 break; 3876 3877 case 2048: 3878 value = 2; 3879 break; 3880 3881 case 4096: 3882 value = 3; 3883 break; 3884 3885 default: 3886 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3887 "PCI_MAX_READ: Invalid parameter value. old=%d new=%d", 3888 cfg[CFG_PCI_MAX_READ].current, cfg[CFG_PCI_MAX_READ].def); 3889 3890 cfg[CFG_PCI_MAX_READ].current = cfg[CFG_PCI_MAX_READ].def; 3891 goto xlate; 3892 } 3893 3894 if ((mb = (MAILBOX *)emlxs_mem_get(hba, MEM_MBOX | MEM_PRI)) == 0) { 3895 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3896 "PCI_MAX_READ: Unable to allocate mailbox buffer."); 3897 return; 3898 } 3899 3900 emlxs_mb_set_var(hba, (MAILBOX *)mb, 0x00100506, value); 3901 3902 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 3903 if (verbose || (mb->mbxStatus != 0x12)) { 3904 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3905 "PCI_MAX_READ: Unable to update. " 3906 "status=%x value=%d (%d bytes)", 3907 mb->mbxStatus, value, 3908 cfg[CFG_PCI_MAX_READ].current); 3909 } 3910 } else { 3911 if (verbose && 3912 (cfg[CFG_PCI_MAX_READ].current != 3913 cfg[CFG_PCI_MAX_READ].def)) { 3914 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3915 "PCI_MAX_READ: Updated. %d bytes", 3916 cfg[CFG_PCI_MAX_READ].current); 3917 } 3918 } 3919 3920 (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mb); 3921 3922 return; 3923 3924 } /* emlxs_pcix_mxr_update */ 3925 3926 3927 3928 extern uint32_t 3929 emlxs_get_key(emlxs_hba_t *hba, MAILBOX *mb) 3930 { 3931 emlxs_port_t *port = &PPORT; 3932 uint32_t npname0, npname1; 3933 uint32_t tmpkey, theKey; 3934 uint16_t key850; 3935 uint32_t t1, t2, t3, t4; 3936 uint32_t ts; 3937 3938 #define SEED 0x876EDC21 3939 3940 /* This key is only used currently for SBUS adapters */ 3941 if (hba->bus_type != SBUS_FC) { 3942 return (0); 3943 } 3944 3945 tmpkey = mb->un.varWords[30]; 3946 emlxs_ffstate_change(hba, FC_INIT_NVPARAMS); 3947 3948 emlxs_mb_read_nv(hba, mb); 3949 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 3950 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3951 "Unable to read nvram. cmd=%x status=%x", mb->mbxCommand, 3952 mb->mbxStatus); 3953 3954 return (0); 3955 } 3956 npname0 = mb->un.varRDnvp.portname[0]; 3957 npname1 = mb->un.varRDnvp.portname[1]; 3958 3959 key850 = (uint16_t)((tmpkey & 0x00FFFF00) >> 8); 3960 ts = (uint16_t)(npname1 + 1); 3961 t1 = ts * key850; 3962 ts = (uint16_t)((npname1 >> 16) + 1); 3963 t2 = ts * key850; 3964 ts = (uint16_t)(npname0 + 1); 3965 t3 = ts * key850; 3966 ts = (uint16_t)((npname0 >> 16) + 1); 3967 t4 = ts * key850; 3968 theKey = SEED + t1 + t2 + t3 + t4; 3969 3970 return (theKey); 3971 3972 } /* emlxs_get_key() */ 3973 3974 3975 extern void 3976 emlxs_fw_show(emlxs_hba_t *hba) 3977 { 3978 emlxs_port_t *port = &PPORT; 3979 uint32_t i; 3980 3981 /* Display firmware library one time */ 3982 for (i = 0; i < EMLXS_FW_COUNT; i++) { 3983 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_library_msg, "%s", 3984 emlxs_fw_table[i].label); 3985 } 3986 3987 return; 3988 3989 } /* emlxs_fw_show() */ 3990 3991 3992 #ifdef MODFW_SUPPORT 3993 static void 3994 emlxs_fw_load(emlxs_hba_t *hba, emlxs_firmware_t *fw) 3995 { 3996 emlxs_port_t *port = &PPORT; 3997 int (*emlxs_fw_get)(emlxs_firmware_t *); 3998 int err; 3999 4000 /* Make sure image is unloaded and image buffer pointer is clear */ 4001 emlxs_fw_unload(hba, fw); 4002 4003 err = 0; 4004 hba->fw_modhandle = 4005 ddi_modopen(EMLXS_FW_MODULE, KRTLD_MODE_FIRST, &err); 4006 if (!hba->fw_modhandle) { 4007 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 4008 "Unable to load firmware module. error=%d", err); 4009 4010 return; 4011 } else { 4012 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 4013 "Firmware module loaded."); 4014 } 4015 4016 err = 0; 4017 emlxs_fw_get = 4018 (int (*)())ddi_modsym(hba->fw_modhandle, "emlxs_fw_get", &err); 4019 if ((void *)emlxs_fw_get == NULL) { 4020 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 4021 "emlxs_fw_get not present. error=%d", err); 4022 4023 emlxs_fw_unload(hba, fw); 4024 return; 4025 } 4026 4027 if (emlxs_fw_get(fw)) { 4028 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 4029 "Invalid firmware image module found. %s", fw->label); 4030 4031 emlxs_fw_unload(hba, fw); 4032 return; 4033 } 4034 4035 return; 4036 4037 } /* emlxs_fw_load() */ 4038 4039 4040 static void 4041 emlxs_fw_unload(emlxs_hba_t *hba, emlxs_firmware_t *fw) 4042 { 4043 emlxs_port_t *port = &PPORT; 4044 4045 /* Clear the firmware image */ 4046 fw->image = NULL; 4047 fw->size = 0; 4048 4049 if (hba->fw_modhandle) { 4050 /* Close the module */ 4051 (void) ddi_modclose(hba->fw_modhandle); 4052 hba->fw_modhandle = NULL; 4053 4054 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 4055 "Firmware module unloaded."); 4056 } 4057 4058 return; 4059 4060 } /* emlxs_fw_unload() */ 4061 #endif /* MODFW_SUPPORT */ 4062