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 2010 Emulex. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 28 #include <emlxs.h> 29 30 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 31 EMLXS_MSG_DEF(EMLXS_DOWNLOAD_C); 32 33 #define MAX_BOOTID 10 34 35 static uint32_t emlxs_erase_fcode_flash(emlxs_hba_t *hba); 36 37 static uint32_t emlxs_write_fcode_flash(emlxs_hba_t *hba, 38 PIMAGE_HDR ImageHdr, caddr_t Buffer); 39 40 static int32_t emlxs_build_parms(caddr_t Buffer, PWAKE_UP_PARMS AbsWakeUpParms, 41 uint32_t BufferSize, PAIF_HDR AifHeader); 42 static uint32_t emlxs_validate_image(emlxs_hba_t *hba, caddr_t Buffer, 43 uint32_t Size, emlxs_fw_image_t *fw_image); 44 static void emlxs_format_dump(emlxs_hba_t *hba, MAILBOXQ *mbq, 45 uint32_t Type, uint32_t RegionId, uint32_t WordCnt, 46 uint32_t BaseAddr); 47 static uint32_t emlxs_start_abs_download(emlxs_hba_t *hba, PAIF_HDR AifHdr, 48 caddr_t Buffer, uint32_t len, 49 PWAKE_UP_PARMS WakeUpParms); 50 static uint32_t emlxs_start_abs_download_2mb(emlxs_hba_t *hba, caddr_t buffer, 51 uint32_t len, uint32_t offline, 52 emlxs_fw_image_t *fw_image); 53 static uint32_t emlxs_proc_abs_2mb(emlxs_hba_t *hba, 54 caddr_t EntireBuffer, uint32_t FileType, 55 uint32_t extType); 56 static void emlxs_format_load_area_cmd(MAILBOXQ *mbq, uint32_t Base, 57 uint32_t DlByteCount, uint32_t Function, 58 uint32_t Complete, uint32_t DataOffset, uint32_t AreaId, 59 uint8_t MbxCmd, uint32_t StepCmd); 60 static uint32_t emlxs_build_parms_2mb_bwc(emlxs_hba_t *hba, PAIF_HDR AifHdr, 61 uint32_t extType, PWAKE_UP_PARMS AbsWakeUpParms); 62 static uint32_t emlxs_update_exp_rom(emlxs_hba_t *hba, 63 PWAKE_UP_PARMS WakeUpParms); 64 extern uint32_t emlxs_get_max_sram(emlxs_hba_t *hba, uint32_t *MaxRbusSize, 65 uint32_t *MaxIbusSize); 66 static void emlxs_format_prog_flash(MAILBOXQ *mbq, uint32_t Base, 67 uint32_t DlByteCount, uint32_t Function, 68 uint32_t Complete, uint32_t BdeAddress, 69 uint32_t BdeSize, PROG_ID *ProgId, uint32_t keep); 70 static void emlxs_format_update_parms(MAILBOXQ *mbq, 71 PWAKE_UP_PARMS WakeUpParms); 72 static void emlxs_format_update_pci_cfg(emlxs_hba_t *hba, MAILBOXQ *mbq, 73 uint32_t region_id, uint32_t size); 74 static uint32_t emlxs_update_wakeup_parms(emlxs_hba_t *hba, 75 PWAKE_UP_PARMS AbsWakeUpParms, 76 PWAKE_UP_PARMS WakeUpParms); 77 static uint32_t emlxs_update_boot_wakeup_parms(emlxs_hba_t *hba, 78 PWAKE_UP_PARMS WakeUpParms, PROG_ID *id, 79 uint32_t proc_erom); 80 static uint32_t emlxs_update_ff_wakeup_parms(emlxs_hba_t *hba, 81 PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 82 static uint32_t emlxs_update_sli1_wakeup_parms(emlxs_hba_t *hba, 83 PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 84 static uint32_t emlxs_update_sli2_wakeup_parms(emlxs_hba_t *hba, 85 PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 86 static uint32_t emlxs_update_sli3_wakeup_parms(emlxs_hba_t *hba, 87 PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 88 static uint32_t emlxs_update_sli4_wakeup_parms(emlxs_hba_t *hba, 89 PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 90 static uint32_t emlxs_start_rel_download(emlxs_hba_t *hba, PIMAGE_HDR ImageHdr, 91 caddr_t Buffer, PWAKE_UP_PARMS WakeUpParms, 92 uint32_t dwc_flag); 93 static uint32_t emlxs_read_load_list(emlxs_hba_t *hba, LOAD_LIST *LoadList); 94 95 static uint32_t emlxs_valid_cksum(uint32_t *StartAddr, uint32_t *EndAddr); 96 97 static void emlxs_disp_aif_header(emlxs_hba_t *hba, PAIF_HDR AifHdr); 98 99 static void emlxs_dump_image_header(emlxs_hba_t *hba, PIMAGE_HDR image); 100 101 102 static uint32_t emlxs_type_check(uint32_t type); 103 104 static uint32_t emlxs_kern_check(emlxs_hba_t *hba, uint32_t version); 105 106 static uint32_t emlxs_stub_check(emlxs_hba_t *hba, uint32_t version); 107 108 static uint32_t emlxs_sli1_check(emlxs_hba_t *hba, uint32_t version); 109 110 static uint32_t emlxs_sli2_check(emlxs_hba_t *hba, uint32_t version); 111 112 static uint32_t emlxs_sli3_check(emlxs_hba_t *hba, uint32_t version); 113 114 static uint32_t emlxs_sli4_check(emlxs_hba_t *hba, uint32_t version); 115 116 static uint32_t emlxs_bios_check(emlxs_hba_t *hba, uint32_t version); 117 118 static uint32_t emlxs_sbus_fcode_check(emlxs_hba_t *hba, uint32_t version); 119 120 static uint32_t emlxs_validate_version(emlxs_hba_t *hba, 121 emlxs_fw_file_t *file, uint32_t id, uint32_t type, 122 char *file_type); 123 static uint32_t emlxs_be2_validate_image(emlxs_hba_t *hba, caddr_t buffer, 124 uint32_t len, emlxs_be_fw_image_t *fw_image); 125 static uint32_t emlxs_be3_validate_image(emlxs_hba_t *hba, caddr_t buffer, 126 uint32_t len, emlxs_be_fw_image_t *fw_image); 127 128 129 static int32_t emlxs_sli4_verify_crc(emlxs_hba_t *hba, 130 emlxs_be_fw_file_t *file, 131 MAILBOXQ *mbq, MATCHMAP *mp); 132 static int32_t emlxs_sli4_flash_image(emlxs_hba_t *hba, caddr_t buffer, 133 emlxs_be_fw_file_t *file, MAILBOXQ *mbq, MATCHMAP *mp); 134 static int32_t emlxs_sli4_fw_download(emlxs_hba_t *hba, caddr_t buffer, 135 uint32_t len, uint32_t offline); 136 static uint32_t emlxs_be_version(caddr_t buffer, uint32_t size, 137 uint32_t *plus_flag); 138 static uint32_t emlxs_proc_rel_2mb(emlxs_hba_t *hba, caddr_t buffer, 139 emlxs_fw_image_t *fw_image); 140 static uint32_t emlxs_delete_load_entry(emlxs_hba_t *hba, PROG_ID *progId); 141 142 static void emlxs_verify_image(emlxs_hba_t *hba, emlxs_fw_image_t *image); 143 144 static uint32_t emlxs_clean_flash(emlxs_hba_t *hba, 145 PWAKE_UP_PARMS OldWakeUpParms, 146 PWAKE_UP_PARMS NewWakeUpParms); 147 148 /* ************************************************************************* */ 149 150 extern int32_t 151 emlxs_fw_download(emlxs_hba_t *hba, caddr_t buffer, uint32_t len, 152 uint32_t offline) 153 { 154 emlxs_port_t *port = &PPORT; 155 uint32_t *Uptr; 156 IMAGE_HDR ImageHdr; 157 AIF_HDR AifHdr; 158 uint32_t ImageType; 159 WAKE_UP_PARMS WakeUpParms; 160 uint32_t rval = 0; 161 emlxs_fw_image_t fw_image; 162 uint32_t i; 163 164 #ifdef EMLXS_LITTLE_ENDIAN 165 caddr_t local_buffer; 166 uint32_t *bptr1; 167 uint32_t *bptr2; 168 #endif /* EMLXS_LITTLE_ENDIAN */ 169 170 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 171 rval = emlxs_sli4_fw_download(hba, buffer, len, offline); 172 return (rval); 173 } 174 175 if (buffer == NULL || len == 0) { 176 return (EMLXS_IMAGE_BAD); 177 } 178 179 #ifdef EMLXS_LITTLE_ENDIAN 180 /* We need to swap the image buffer before we start */ 181 182 /* 183 * Use KM_SLEEP to allocate a temporary buffer 184 */ 185 local_buffer = (caddr_t)kmem_zalloc(len, KM_SLEEP); 186 187 /* Perform a 32 bit swap of the image */ 188 bptr1 = (uint32_t *)local_buffer; 189 bptr2 = (uint32_t *)buffer; 190 for (i = 0; i < (len / 4); i++) { 191 *bptr1 = LE_SWAP32(*bptr2); 192 bptr1++; 193 bptr2++; 194 } 195 196 /* Replace the original buffer */ 197 buffer = local_buffer; 198 #endif /* EMLXS_LITTLE_ENDIAN */ 199 200 bzero(&fw_image, sizeof (emlxs_fw_image_t)); 201 for (i = 0; i < MAX_PROG_TYPES; i++) { 202 (void) strcpy(fw_image.prog[i].label, "none"); 203 } 204 205 /* Validate image */ 206 if ((rval = emlxs_validate_image(hba, buffer, len, &fw_image))) { 207 goto done; 208 } 209 210 /* Verify image */ 211 emlxs_verify_image(hba, &fw_image); 212 213 /* Get image type */ 214 Uptr = (uint32_t *)buffer; 215 ImageType = *Uptr; 216 217 /* 218 * Pegasus and beyond FW download is done differently 219 * for absolute download. 220 */ 221 222 /* Check for absolute image */ 223 if ((ImageType == NOP_IMAGE_TYPE) && 224 !(hba->model_info.chip & 225 (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 226 /* 227 * Because 2Mb flash download file format is different from 228 * 512k, it needs to be handled differently 229 */ 230 if (rval = emlxs_start_abs_download_2mb(hba, buffer, len, 231 offline, &fw_image)) { 232 goto done; 233 } 234 235 /* Offline already handled */ 236 offline = 0; 237 238 goto SLI_DOWNLOAD_EXIT; 239 } 240 241 /* Pre-pegasus adapters only */ 242 243 /* Initialize headers */ 244 if (ImageType == NOP_IMAGE_TYPE) { 245 bcopy(buffer, &AifHdr, sizeof (AIF_HDR)); 246 bzero((void *)&ImageHdr, sizeof (IMAGE_HDR)); 247 } else { /* PRG file */ 248 bzero((void *)&AifHdr, sizeof (AIF_HDR)); 249 bcopy(buffer, &ImageHdr, sizeof (IMAGE_HDR)); 250 } 251 252 /* Everything checks out, now to just do it */ 253 254 if (offline) { 255 if (emlxs_offline(hba) != FC_SUCCESS) { 256 offline = 0; 257 258 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 259 "Unable to take adapter offline."); 260 261 rval = EMLXS_OFFLINE_FAILED; 262 goto SLI_DOWNLOAD_EXIT; 263 } 264 265 if (EMLXS_SLI_HBA_RESET(hba, 1, 1, 0) != FC_SUCCESS) { 266 offline = 0; 267 268 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 269 "Unable to restart adapter."); 270 271 rval = EMLXS_OFFLINE_FAILED; 272 goto SLI_DOWNLOAD_EXIT; 273 } 274 } 275 276 /* Pre-pegasus adapters */ 277 278 if (ImageHdr.Id.Type == SBUS_FCODE) { 279 /* Erase Flash */ 280 if (emlxs_erase_fcode_flash(hba)) { 281 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 282 "Unable to erase flash."); 283 284 rval = EMLXS_IMAGE_FAILED; 285 goto SLI_DOWNLOAD_EXIT; 286 } 287 288 /* Write FCODE */ 289 if (emlxs_write_fcode_flash(hba, &ImageHdr, buffer)) { 290 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 291 "Unable to write flash."); 292 293 rval = EMLXS_IMAGE_FAILED; 294 goto SLI_DOWNLOAD_EXIT; 295 } 296 297 goto SLI_DOWNLOAD_EXIT; 298 } 299 300 /* Pre-pegasus PCI adapters */ 301 302 if (emlxs_read_wakeup_parms(hba, &WakeUpParms, 1)) { 303 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 304 "Unable to get parameters."); 305 306 rval = EMLXS_IMAGE_FAILED; 307 308 goto SLI_DOWNLOAD_EXIT; 309 } 310 311 if (ImageType == NOP_IMAGE_TYPE) { 312 if (emlxs_start_abs_download(hba, &AifHdr, 313 buffer, len, &WakeUpParms)) { 314 EMLXS_MSGF(EMLXS_CONTEXT, 315 &emlxs_download_failed_msg, 316 "Failed to program flash."); 317 318 rval = EMLXS_IMAGE_FAILED; 319 320 goto SLI_DOWNLOAD_EXIT; 321 } 322 323 } else { /* Relative PRG file */ 324 if (emlxs_start_rel_download(hba, &ImageHdr, buffer, 325 &WakeUpParms, 0)) { 326 EMLXS_MSGF(EMLXS_CONTEXT, 327 &emlxs_download_failed_msg, 328 "Failed to program flash."); 329 330 rval = EMLXS_IMAGE_FAILED; 331 332 goto SLI_DOWNLOAD_EXIT; 333 } 334 } 335 336 SLI_DOWNLOAD_EXIT: 337 338 if (offline) { 339 (void) emlxs_online(hba); 340 } 341 342 if (rval == 0) { 343 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_complete_msg, 344 "Status good."); 345 } 346 347 done: 348 349 #ifdef EMLXS_LITTLE_ENDIAN 350 /* Free the local buffer */ 351 kmem_free(local_buffer, len); 352 #endif /* EMLXS_LITTLE_ENDIAN */ 353 354 return (rval); 355 356 } /* emlxs_fw_download */ 357 358 359 extern void 360 emlxs_memset(uint8_t *buffer, uint8_t value, uint32_t size) 361 { 362 while (size--) { 363 *buffer++ = value; 364 } 365 366 } /* emlxs_memset () */ 367 368 369 static int32_t 370 emlxs_sli4_flash_image(emlxs_hba_t *hba, caddr_t buffer, 371 emlxs_be_fw_file_t *file, MAILBOXQ *mbq, MATCHMAP *mp) 372 { 373 emlxs_port_t *port = &PPORT; 374 uint8_t *image_ptr; 375 uint32_t *wptr; 376 uint8_t *payload; 377 MAILBOX4 *mb; 378 IOCTL_COMMON_FLASHROM *flashrom; 379 mbox_req_hdr_t *hdr_req; 380 uint32_t image_size; 381 uint32_t block_size; 382 uint32_t xfer_size; 383 uint32_t block_offset; 384 uint32_t count; 385 uint32_t rval = 0; 386 387 if (file->image_size == 0) { 388 return (0); 389 } 390 391 image_ptr = (uint8_t *)buffer + file->image_offset; 392 image_size = file->image_size; 393 block_size = file->block_size; 394 block_offset = 0; 395 mb = (MAILBOX4*)mbq; 396 397 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 398 "%s: Downloading...", file->label); 399 400 while (block_size) { 401 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 402 bzero((void *) mp->virt, mp->size); 403 404 xfer_size = min(BE_MAX_XFER_SIZE, block_size); 405 406 mb->un.varSLIConfig.be.embedded = 0; 407 mbq->nonembed = (void *)mp; 408 mbq->mbox_cmpl = NULL; 409 410 mb->mbxCommand = MBX_SLI_CONFIG; 411 mb->mbxOwner = OWN_HOST; 412 413 hdr_req = (mbox_req_hdr_t *)mp->virt; 414 hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON; 415 hdr_req->opcode = COMMON_OPCODE_WRITE_FLASHROM; 416 hdr_req->timeout = 0; 417 hdr_req->req_length = sizeof (IOCTL_COMMON_FLASHROM) + 418 xfer_size; 419 420 flashrom = (IOCTL_COMMON_FLASHROM *)(hdr_req + 1); 421 flashrom->params.opcode = ((block_size == xfer_size)? 422 MGMT_FLASHROM_OPCODE_FLASH:MGMT_FLASHROM_OPCODE_SAVE); 423 flashrom->params.optype = file->type; 424 flashrom->params.data_buffer_size = xfer_size; 425 flashrom->params.offset = block_offset; 426 427 /* Build data buffer payload */ 428 payload = (uint8_t *)(&flashrom->params.data_buffer); 429 emlxs_memset(payload, 0xff, xfer_size); 430 431 /* Copy remaining image into payload */ 432 if (image_size) { 433 count = min(image_size, xfer_size); 434 BE_SWAP32_BCOPY(image_ptr, payload, count); 435 image_size -= count; 436 image_ptr += count; 437 } 438 439 if (flashrom->params.opcode == MGMT_FLASHROM_OPCODE_FLASH) { 440 wptr = (uint32_t *)&payload[(xfer_size - 12)]; 441 442 wptr[0] = file->load_address; 443 wptr[1] = file->image_size; 444 wptr[2] = file->block_crc; 445 } 446 447 /* Send write request */ 448 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 449 MBX_SUCCESS) { 450 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 451 "%s: Unable to download image. status=%x", 452 file->label, mb->mbxStatus); 453 rval = EMLXS_IMAGE_FAILED; 454 goto done; 455 } 456 457 block_size -= xfer_size; 458 block_offset += xfer_size; 459 } 460 461 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 462 "%s: Download complete.", file->label); 463 done: 464 465 return (rval); 466 467 } /* emlxs_sli4_flash_image() */ 468 469 470 471 472 static int32_t 473 emlxs_sli4_verify_crc(emlxs_hba_t *hba, 474 emlxs_be_fw_file_t *file, MAILBOXQ *mbq, MATCHMAP *mp) 475 { 476 emlxs_port_t *port = &PPORT; 477 uint32_t *wptr; 478 uint8_t *payload; 479 MAILBOX4 *mb; 480 IOCTL_COMMON_FLASHROM *flashrom; 481 mbox_req_hdr_t *hdr_req; 482 uint32_t xfer_size; 483 uint32_t block_offset; 484 uint32_t rval = 0; 485 uint32_t value; 486 487 xfer_size = 8; 488 block_offset = file->block_size - xfer_size; 489 mb = (MAILBOX4*)mbq; 490 491 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 492 "%s: Verifying CRC...", file->label); 493 494 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 495 bzero((void *) mp->virt, mp->size); 496 497 mb->un.varSLIConfig.be.embedded = 0; 498 mbq->nonembed = (void *)mp; 499 mbq->mbox_cmpl = NULL; 500 501 mb->mbxCommand = MBX_SLI_CONFIG; 502 mb->mbxOwner = OWN_HOST; 503 504 hdr_req = (mbox_req_hdr_t *)mp->virt; 505 hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON; 506 hdr_req->opcode = COMMON_OPCODE_READ_FLASHROM; 507 hdr_req->timeout = 0; 508 hdr_req->req_length = sizeof (IOCTL_COMMON_FLASHROM) + 509 xfer_size; 510 511 flashrom = (IOCTL_COMMON_FLASHROM *)(hdr_req + 1); 512 flashrom->params.opcode = MGMT_FLASHROM_OPCODE_REPORT; 513 flashrom->params.optype = file->type; 514 flashrom->params.data_buffer_size = xfer_size; 515 flashrom->params.offset = block_offset; 516 517 /* Send read request */ 518 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 519 MBX_SUCCESS) { 520 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 521 "%s: Unable to read CRC. status=%x", 522 file->label, mb->mbxStatus); 523 524 rval = 2; 525 goto done; 526 } 527 528 payload = (uint8_t *)(&flashrom->params.data_buffer); 529 wptr = (uint32_t *)(payload + xfer_size - 8); 530 531 /* Verify image size */ 532 value = *wptr++; 533 if (value != file->image_size) { 534 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 535 "%s: Image size mismatch. %08x != %08x", 536 file->label, value, file->image_size); 537 538 rval = 1; 539 goto done; 540 } 541 542 /* Verify block crc */ 543 value = *wptr; 544 if (value != file->block_crc) { 545 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 546 "%s: CRC mismatch. %08x != %08x", 547 file->label, value, file->block_crc); 548 rval = 1; 549 } 550 551 done: 552 553 if (rval == 0) { 554 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 555 "%s: CRC verified.", file->label); 556 } 557 558 return (rval); 559 560 } /* emlxs_sli4_verify_crc() */ 561 562 563 extern int32_t 564 emlxs_sli4_read_fw_version(emlxs_hba_t *hba, emlxs_firmware_t *fw) 565 { 566 emlxs_port_t *port = &PPORT; 567 MAILBOXQ *mbq = NULL; 568 MATCHMAP *mp = NULL; 569 MAILBOX4 *mb; 570 uint32_t *wptr; 571 uint8_t *payload; 572 IOCTL_COMMON_FLASHROM *flashrom; 573 mbox_req_hdr_t *hdr_req; 574 uint32_t xfer_size; 575 uint32_t block_offset; 576 uint32_t rval = 0; 577 578 bzero((void *) fw, sizeof (emlxs_firmware_t)); 579 580 if ((mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 581 KM_SLEEP)) == NULL) { 582 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 583 "read_fw_version: Unable to allocate mailbox buffer."); 584 585 rval = 1; 586 goto done; 587 } 588 589 if ((mp = emlxs_mem_buf_alloc(hba, (sizeof (mbox_req_hdr_t) + 590 sizeof (IOCTL_COMMON_FLASHROM) + 32))) == NULL) { 591 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 592 "read_fw_version: Unable to allocate payload buffer."); 593 594 rval = EMLXS_IMAGE_FAILED; 595 goto done; 596 } 597 598 mb = (MAILBOX4*)mbq; 599 600 /* Read CRC and size */ 601 xfer_size = 8; 602 block_offset = 0x140000 - xfer_size; 603 604 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 605 bzero((void *) mp->virt, mp->size); 606 607 mb->un.varSLIConfig.be.embedded = 0; 608 mbq->nonembed = (void *)mp; 609 mbq->mbox_cmpl = NULL; 610 611 mb->mbxCommand = MBX_SLI_CONFIG; 612 mb->mbxOwner = OWN_HOST; 613 614 hdr_req = (mbox_req_hdr_t *)mp->virt; 615 hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON; 616 hdr_req->opcode = COMMON_OPCODE_READ_FLASHROM; 617 hdr_req->timeout = 0; 618 hdr_req->req_length = sizeof (IOCTL_COMMON_FLASHROM) + 619 xfer_size; 620 621 flashrom = (IOCTL_COMMON_FLASHROM *)(hdr_req + 1); 622 flashrom->params.opcode = MGMT_FLASHROM_OPCODE_REPORT; 623 flashrom->params.optype = MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE; 624 flashrom->params.data_buffer_size = xfer_size; 625 flashrom->params.offset = block_offset; 626 627 /* Send read request */ 628 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 629 MBX_SUCCESS) { 630 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 631 "read_fw_version: Unable to read CRC. status=%x", 632 mb->mbxStatus); 633 634 rval = 1; 635 goto done; 636 } 637 638 payload = (uint8_t *)(&flashrom->params.data_buffer); 639 640 wptr = (uint32_t *)payload; 641 fw->size = *wptr++; /* image size */ 642 fw->sli4 = *wptr; /* block crc */ 643 fw->kern = *wptr; 644 fw->stub = *wptr; 645 646 /* Read version label */ 647 xfer_size = 32; 648 block_offset = 0x30; 649 650 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 651 bzero((void *) mp->virt, mp->size); 652 653 mb->un.varSLIConfig.be.embedded = 0; 654 mbq->nonembed = (void *)mp; 655 mbq->mbox_cmpl = NULL; 656 657 mb->mbxCommand = MBX_SLI_CONFIG; 658 mb->mbxOwner = OWN_HOST; 659 660 hdr_req = (mbox_req_hdr_t *)mp->virt; 661 hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON; 662 hdr_req->opcode = COMMON_OPCODE_READ_FLASHROM; 663 hdr_req->timeout = 0; 664 hdr_req->req_length = sizeof (IOCTL_COMMON_FLASHROM) + 665 xfer_size; 666 667 flashrom = (IOCTL_COMMON_FLASHROM *)(hdr_req + 1); 668 flashrom->params.opcode = MGMT_FLASHROM_OPCODE_REPORT; 669 flashrom->params.optype = MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE; 670 flashrom->params.data_buffer_size = xfer_size; 671 flashrom->params.offset = block_offset; 672 673 /* Send read request */ 674 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 675 MBX_SUCCESS) { 676 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 677 "read_fw_version: Unable to read version string. status=%x", 678 mb->mbxStatus); 679 680 rval = 1; 681 goto done; 682 } 683 684 payload = (uint8_t *)(&flashrom->params.data_buffer); 685 BE_SWAP32_BCOPY(payload, (uint8_t *)fw->label, 32); 686 687 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 688 "FCOE FIRMWARE: size=%x version=%s (0x%08x)", 689 fw->size, fw->label, fw->sli4); 690 691 done: 692 693 if (mbq) { 694 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 695 } 696 697 if (mp) { 698 emlxs_mem_buf_free(hba, mp); 699 } 700 701 return (rval); 702 703 } /* emlxs_sli4_read_fw_version() */ 704 705 706 static uint32_t 707 emlxs_be_version(caddr_t buffer, uint32_t size, uint32_t *plus_flag) 708 { 709 emlxs_be2_ufi_header_t *ufi_hdr; 710 char signature[BE2_SIGNATURE_SIZE]; 711 uint32_t be_version = 0; 712 713 if (size < sizeof (emlxs_be2_ufi_header_t)) { 714 return (0); 715 } 716 ufi_hdr = (emlxs_be2_ufi_header_t *)buffer; 717 718 (void) sprintf(signature, "%s+", BE_SIGNATURE); 719 720 /* Check if this is a UFI image */ 721 if (strncmp(signature, (char *)ufi_hdr->signature, 722 strlen(BE_SIGNATURE)) != 0) { 723 return (0); 724 } 725 726 /* Check if this is a UFI plus image */ 727 if (plus_flag) { 728 /* Check if this is a UFI plus image */ 729 if (strncmp(signature, (char *)ufi_hdr->signature, 730 strlen(BE_SIGNATURE)+1) == 0) { 731 *plus_flag = 1; 732 } else { 733 *plus_flag = 0; 734 } 735 } 736 737 if ((ufi_hdr->build[0] >= '1') && (ufi_hdr->build[0] <= '9')) { 738 be_version = ufi_hdr->build[0] - '0'; 739 } 740 741 return (be_version); 742 743 } /* emlxs_be_version() */ 744 745 746 static uint32_t 747 emlxs_be2_validate_image(emlxs_hba_t *hba, caddr_t buffer, 748 uint32_t len, emlxs_be_fw_image_t *fw_image) 749 { 750 emlxs_port_t *port = &PPORT; 751 emlxs_be2_ufi_header_t *ufi_hdr; 752 emlxs_be2_flash_dir_t *flash_dir; 753 emlxs_be2_flash_entry_t *entry; 754 uint8_t *bptr; 755 uint32_t *wptr; 756 uint32_t i; 757 uint32_t k; 758 uint32_t mask; 759 uint32_t value; 760 uint32_t image_size; 761 emlxs_be_fw_file_t *file; 762 emlxs_be_fw_file_t *file2; 763 uint32_t ufi_plus = 0; 764 uint32_t be_version = 0; 765 uint32_t found; 766 767 bzero(fw_image, sizeof (emlxs_be_fw_image_t)); 768 769 if (hba->model_info.chip != EMLXS_BE2_CHIP) { 770 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 771 "Invalid adapter model."); 772 return (EMLXS_IMAGE_INCOMPATIBLE); 773 } 774 775 if (len < (sizeof (emlxs_be2_ufi_header_t) + 776 sizeof (emlxs_be2_flash_dir_t))) { 777 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 778 "Image too small. (%d < %d)", 779 len, (sizeof (emlxs_be2_ufi_header_t) + 780 sizeof (emlxs_be2_flash_dir_t))); 781 return (EMLXS_IMAGE_BAD); 782 } 783 784 be_version = emlxs_be_version(buffer, len, &ufi_plus); 785 786 /* Check if this is a standard BE2 image */ 787 if (be_version != 2) { 788 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 789 "Invalid image provided."); 790 return (EMLXS_IMAGE_INCOMPATIBLE); 791 } 792 793 ufi_hdr = (emlxs_be2_ufi_header_t *)buffer; 794 795 #ifdef EMLXS_BIG_ENDIAN 796 /* Big Endian Swapping */ 797 /* Swap ufi header */ 798 ufi_hdr->checksum = 799 SWAP32(ufi_hdr->checksum); 800 ufi_hdr->antidote = 801 SWAP32(ufi_hdr->antidote); 802 ufi_hdr->controller.vendor_id = 803 SWAP32(ufi_hdr->controller.vendor_id); 804 ufi_hdr->controller.device_id = 805 SWAP32(ufi_hdr->controller.device_id); 806 ufi_hdr->controller.sub_vendor_id = 807 SWAP32(ufi_hdr->controller.sub_vendor_id); 808 ufi_hdr->controller.sub_device_id = 809 SWAP32(ufi_hdr->controller.sub_device_id); 810 ufi_hdr->file_length = 811 SWAP32(ufi_hdr->file_length); 812 ufi_hdr->chunk_num = 813 SWAP32(ufi_hdr->chunk_num); 814 ufi_hdr->chunk_cnt = 815 SWAP32(ufi_hdr->chunk_cnt); 816 ufi_hdr->image_cnt = 817 SWAP32(ufi_hdr->image_cnt); 818 #endif /* EMLXS_BIG_ENDIAN */ 819 820 if (len != ufi_hdr->file_length) { 821 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 822 "Invalid image size (%d != %d)", 823 len, ufi_hdr->file_length); 824 825 return (EMLXS_IMAGE_BAD); 826 } 827 828 /* Scan for flash dir signature */ 829 bptr = (uint8_t *)buffer; 830 flash_dir = NULL; 831 for (i = 0; i < len; i++, bptr++) { 832 if (strncmp((char *)bptr, BE_DIR_SIGNATURE, 833 sizeof (BE_DIR_SIGNATURE)) == 0) { 834 flash_dir = (emlxs_be2_flash_dir_t *)bptr; 835 break; 836 } 837 } 838 839 if (!flash_dir) { 840 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 841 "Unable to find flash directory."); 842 843 return (EMLXS_IMAGE_BAD); 844 } 845 846 #ifdef EMLXS_BIG_ENDIAN 847 /* Big Endian Swapping */ 848 /* Swap flash dir */ 849 flash_dir->header.format_rev = 850 SWAP32(flash_dir->header.format_rev); 851 flash_dir->header.checksum = 852 SWAP32(flash_dir->header.checksum); 853 flash_dir->header.antidote = 854 SWAP32(flash_dir->header.antidote); 855 flash_dir->header.build_num = 856 SWAP32(flash_dir->header.build_num); 857 flash_dir->header.active_entry_mask = 858 SWAP32(flash_dir->header.active_entry_mask); 859 flash_dir->header.valid_entry_mask = 860 SWAP32(flash_dir->header.valid_entry_mask); 861 flash_dir->header.orig_content_mask = 862 SWAP32(flash_dir->header.orig_content_mask); 863 flash_dir->header.resv0 = SWAP32(flash_dir->header.resv0); 864 flash_dir->header.resv1 = SWAP32(flash_dir->header.resv1); 865 flash_dir->header.resv2 = SWAP32(flash_dir->header.resv2); 866 flash_dir->header.resv3 = SWAP32(flash_dir->header.resv3); 867 flash_dir->header.resv4 = SWAP32(flash_dir->header.resv4); 868 869 for (i = 0; i < BE_CONTROLLER_SIZE; i++) { 870 flash_dir->header.controller[i].vendor_id = 871 SWAP32(flash_dir->header.controller[i].vendor_id); 872 flash_dir->header.controller[i].device_id = 873 SWAP32(flash_dir->header.controller[i].device_id); 874 flash_dir->header.controller[i].sub_vendor_id = 875 SWAP32(flash_dir->header.controller[i].sub_vendor_id); 876 flash_dir->header.controller[i].sub_device_id = 877 SWAP32(flash_dir->header.controller[i].sub_device_id); 878 } 879 880 for (i = 0, mask = 1; i < BE_FLASH_ENTRIES; i++, mask <<= 1) { 881 882 if (!(flash_dir->header.valid_entry_mask & mask)) { 883 continue; 884 } 885 886 entry = &flash_dir->entry[i]; 887 888 if ((entry->type == 0) || 889 (entry->type == (uint32_t)-1) || 890 (entry->image_size == 0)) { 891 continue; 892 } 893 894 flash_dir->entry[i].type = 895 SWAP32(flash_dir->entry[i].type); 896 flash_dir->entry[i].offset = 897 SWAP32(flash_dir->entry[i].offset); 898 flash_dir->entry[i].pad_size = 899 SWAP32(flash_dir->entry[i].pad_size); 900 flash_dir->entry[i].image_size = 901 SWAP32(flash_dir->entry[i].image_size); 902 flash_dir->entry[i].checksum = 903 SWAP32(flash_dir->entry[i].checksum); 904 flash_dir->entry[i].entry_point = 905 SWAP32(flash_dir->entry[i].entry_point); 906 flash_dir->entry[i].resv0 = 907 SWAP32(flash_dir->entry[i].resv0); 908 flash_dir->entry[i].resv1 = 909 SWAP32(flash_dir->entry[i].resv1); 910 } 911 #endif /* EMLXS_BIG_ENDIAN */ 912 913 /* Verify adapter model */ 914 found = 0; 915 for (i = 0; i < BE_CONTROLLER_SIZE; i++) { 916 if (flash_dir->header.controller[i].device_id == 917 hba->model_info.device_id) { 918 found = 1; 919 } 920 } 921 922 if (!found) { 923 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 924 "Invalid adapter device id=0x%x.", 925 hba->model_info.device_id); 926 return (EMLXS_IMAGE_INCOMPATIBLE); 927 } 928 929 /* Build fw_image table */ 930 fw_image->be_version = 2; 931 fw_image->ufi_plus = ufi_plus; 932 for (i = 0, mask = 1; i < BE_FLASH_ENTRIES; i++, mask <<= 1) { 933 934 if (!(flash_dir->header.valid_entry_mask & mask)) { 935 continue; 936 } 937 938 entry = &flash_dir->entry[i]; 939 940 if ((entry->type == 0) || 941 (entry->type == (uint32_t)-1) || 942 (entry->image_size == 0)) { 943 continue; 944 } 945 946 switch (entry->type) { 947 case BE_FLASHTYPE_REDBOOT: 948 file = &fw_image->file[REDBOOT_FLASHTYPE]; 949 (void) strcpy(file->label, "REDBOOT"); 950 file->type = MGMT_FLASHROM_OPTYPE_REDBOOT; 951 break; 952 case BE_FLASHTYPE_ISCSI_BIOS: 953 file = &fw_image->file[ISCSI_BIOS_FLASHTYPE]; 954 (void) strcpy(file->label, "ISCSI BIOS"); 955 file->type = MGMT_FLASHROM_OPTYPE_ISCSI_BIOS; 956 break; 957 case BE_FLASHTYPE_PXE_BIOS: 958 file = &fw_image->file[PXE_BIOS_FLASHTYPE]; 959 (void) strcpy(file->label, "PXE BIOS"); 960 file->type = MGMT_FLASHROM_OPTYPE_PXE_BIOS; 961 break; 962 case BE_FLASHTYPE_FCOE_BIOS: 963 file = &fw_image->file[FCOE_BIOS_FLASHTYPE]; 964 (void) strcpy(file->label, "FCOE BIOS"); 965 file->type = MGMT_FLASHROM_OPTYPE_FCOE_BIOS; 966 break; 967 case BE_FLASHTYPE_ISCSI_FIRMWARE: 968 file = &fw_image->file[ISCSI_FIRMWARE_FLASHTYPE]; 969 (void) strcpy(file->label, "ISCSI FIRMWARE"); 970 file->type = MGMT_FLASHROM_OPTYPE_ISCSI_FIRMWARE; 971 break; 972 case BE_FLASHTYPE_FCOE_FIRMWARE: 973 file = &fw_image->file[FCOE_FIRMWARE_FLASHTYPE]; 974 (void) strcpy(file->label, "FCOE FIRMWARE"); 975 file->type = MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE; 976 break; 977 case BE_FLASHTYPE_FCOE_BACKUP: 978 case BE_FLASHTYPE_ISCSI_BACKUP: 979 continue; 980 981 default: 982 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 983 "Unknown image type found. type=%x", 984 entry->type); 985 continue; 986 } 987 988 file->be_version = fw_image->be_version; 989 file->ufi_plus = fw_image->ufi_plus; 990 file->image_size = entry->image_size; 991 image_size = BE_SWAP32(entry->image_size); 992 993 if (ufi_plus) { 994 file->image_offset = entry->offset; 995 file->block_size = entry->pad_size; 996 file->block_crc = entry->checksum; 997 file->load_address = entry->entry_point; 998 999 } else { 1000 file->image_offset = entry->offset + 1001 sizeof (emlxs_be2_ufi_header_t); 1002 1003 /* Get entry block size and crc */ 1004 k = file->image_offset + file->image_size; 1005 k &= 0xFFFFFFFC; 1006 1007 wptr = (uint32_t *)(buffer + k); 1008 for (; k < len; k += 4) { 1009 if (*wptr++ == image_size) { 1010 /* Calculate block_size */ 1011 file->block_size = (k + 8) - 1012 file->image_offset; 1013 1014 /* Read load_address */ 1015 value = *(wptr - 2); 1016 file->load_address = BE_SWAP32(value); 1017 1018 /* Read block_crc */ 1019 value = *wptr; 1020 file->block_crc = BE_SWAP32(value); 1021 1022 break; 1023 } 1024 } 1025 1026 if (k >= len) { 1027 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1028 "%s: End of block not found. offset=%x", 1029 file->label, file->image_offset); 1030 1031 bzero(fw_image, sizeof (emlxs_be_fw_image_t)); 1032 return (EMLXS_IMAGE_BAD); 1033 } 1034 } 1035 1036 /* Make sure image will fit in block specified */ 1037 if (file->image_size + 12 > file->block_size) { 1038 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1039 "%s: Image too large for block. image=%x block=%x", 1040 file->label, file->image_size, file->block_size); 1041 1042 bzero(fw_image, sizeof (emlxs_be_fw_image_t)); 1043 return (EMLXS_IMAGE_BAD); 1044 } 1045 1046 /* Automatically create a backup file entry for firmware */ 1047 if (file->type == MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE) { 1048 file2 = &fw_image->file[FCOE_BACKUP_FLASHTYPE]; 1049 1050 bcopy((uint8_t *)file, (uint8_t *)file2, 1051 sizeof (emlxs_be_fw_file_t)); 1052 file2->type = MGMT_FLASHROM_OPTYPE_FCOE_BACKUP; 1053 (void) strcpy(file2->label, "FCOE BACKUP"); 1054 1055 /* Save FCOE version info */ 1056 bptr = (uint8_t *)buffer + file->image_offset + 0x30; 1057 (void) strncpy(fw_image->fcoe_label, (char *)bptr, 1058 BE_VERSION_SIZE); 1059 fw_image->fcoe_version = file->block_crc; 1060 1061 } else if (file->type == 1062 MGMT_FLASHROM_OPTYPE_ISCSI_FIRMWARE) { 1063 file2 = &fw_image->file[ISCSI_BACKUP_FLASHTYPE]; 1064 1065 bcopy((uint8_t *)file, (uint8_t *)file2, 1066 sizeof (emlxs_be_fw_file_t)); 1067 file2->type = MGMT_FLASHROM_OPTYPE_ISCSI_BACKUP; 1068 (void) strcpy(file2->label, "ISCSI BACKUP"); 1069 1070 /* Save ISCSI version info */ 1071 bptr = (uint8_t *)buffer + file->image_offset + 0x30; 1072 (void) strncpy(fw_image->iscsi_label, (char *)bptr, 1073 BE_VERSION_SIZE); 1074 fw_image->iscsi_version = file->block_crc; 1075 } 1076 } 1077 1078 if (fw_image->fcoe_version == 0) { 1079 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1080 "Unable to find FCOE firmware component."); 1081 1082 bzero(fw_image, sizeof (emlxs_be_fw_image_t)); 1083 return (EMLXS_IMAGE_BAD); 1084 } 1085 1086 /* Display contents */ 1087 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1088 "BE2 UFI Image: %08x, %s", fw_image->fcoe_version, 1089 fw_image->fcoe_label); 1090 1091 for (i = 0; i < BE_MAX_FLASHTYPES; i++) { 1092 file = &fw_image->file[i]; 1093 1094 if (file->image_size == 0) { 1095 continue; 1096 } 1097 1098 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1099 "%s: be=%x%s type=%x block=%x image=%x offset=%x crc=%x " 1100 "load=%x", 1101 file->label, file->be_version, (file->ufi_plus)?"+":"", 1102 file->type, file->block_size, file->image_size, 1103 file->image_offset, file->block_crc, file->load_address); 1104 } 1105 1106 return (0); 1107 1108 } /* emlxs_be2_validate_image() */ 1109 1110 1111 static uint32_t 1112 emlxs_be3_validate_image(emlxs_hba_t *hba, caddr_t buffer, 1113 uint32_t len, emlxs_be_fw_image_t *fw_image) 1114 { 1115 emlxs_port_t *port = &PPORT; 1116 emlxs_be3_ufi_header_t *ufi_hdr; 1117 emlxs_be3_flash_dir_t *flash_dir; 1118 emlxs_be3_flash_entry_t *entry; 1119 emlxs_be3_image_header_t *flash_image_hdr; 1120 emlxs_be3_image_header_t *image_hdr; 1121 uint8_t *bptr; 1122 uint32_t *wptr; 1123 uint32_t i; 1124 uint32_t value; 1125 emlxs_be_fw_file_t *file; 1126 emlxs_be_fw_file_t *file2; 1127 uint32_t ufi_plus = 0; 1128 uint32_t be_version = 0; 1129 uint32_t found; 1130 1131 bzero(fw_image, sizeof (emlxs_be_fw_image_t)); 1132 1133 if (hba->model_info.chip != EMLXS_BE3_CHIP) { 1134 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 1135 "Invalid adapter model."); 1136 return (EMLXS_IMAGE_INCOMPATIBLE); 1137 } 1138 1139 if (len < (sizeof (emlxs_be3_ufi_header_t) + 1140 sizeof (emlxs_be3_flash_dir_t))) { 1141 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1142 "Image too small. (%d < %d)", 1143 len, (sizeof (emlxs_be3_ufi_header_t) + 1144 sizeof (emlxs_be3_flash_dir_t))); 1145 return (EMLXS_IMAGE_BAD); 1146 } 1147 1148 be_version = emlxs_be_version(buffer, len, &ufi_plus); 1149 1150 /* Check if this is a standard BE3 image */ 1151 if (be_version != 3) { 1152 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 1153 "Invalid image provided."); 1154 return (EMLXS_IMAGE_INCOMPATIBLE); 1155 } 1156 1157 ufi_hdr = (emlxs_be3_ufi_header_t *)buffer; 1158 1159 #ifdef EMLXS_BIG_ENDIAN 1160 /* Big Endian Swapping */ 1161 /* Swap ufi header */ 1162 ufi_hdr->ufi_version = 1163 SWAP32(ufi_hdr->ufi_version); 1164 ufi_hdr->file_length = 1165 SWAP32(ufi_hdr->file_length); 1166 ufi_hdr->checksum = 1167 SWAP32(ufi_hdr->checksum); 1168 ufi_hdr->antidote = 1169 SWAP32(ufi_hdr->antidote); 1170 ufi_hdr->image_cnt = 1171 SWAP32(ufi_hdr->image_cnt); 1172 #endif /* EMLXS_BIG_ENDIAN */ 1173 1174 if (len != ufi_hdr->file_length) { 1175 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1176 "Invalid image size (%d != %d)", 1177 len, ufi_hdr->file_length); 1178 1179 return (EMLXS_IMAGE_BAD); 1180 } 1181 1182 flash_image_hdr = NULL; 1183 image_hdr = (emlxs_be3_image_header_t *)(buffer + 1184 sizeof (emlxs_be3_ufi_header_t)); 1185 for (i = 0; i < ufi_hdr->image_cnt; i++, image_hdr++) { 1186 #ifdef EMLXS_BIG_ENDIAN 1187 image_hdr->id = SWAP32(image_hdr->id); 1188 image_hdr->offset = SWAP32(image_hdr->offset); 1189 image_hdr->length = SWAP32(image_hdr->length); 1190 image_hdr->checksum = SWAP32(image_hdr->checksum); 1191 #endif /* EMLXS_BIG_ENDIAN */ 1192 1193 if (image_hdr->id == UFI_BE3_FLASH_ID) { 1194 flash_image_hdr = image_hdr; 1195 } 1196 } 1197 1198 if (!flash_image_hdr) { 1199 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1200 "No flash image found."); 1201 1202 return (EMLXS_IMAGE_BAD); 1203 } 1204 1205 /* Scan for flash dir signature */ 1206 bptr = (uint8_t *)buffer + flash_image_hdr->offset; 1207 flash_dir = NULL; 1208 for (i = 0; i < flash_image_hdr->length; i++, bptr++) { 1209 if (strncmp((char *)bptr, BE_DIR_SIGNATURE, 1210 sizeof (BE_DIR_SIGNATURE)) == 0) { 1211 flash_dir = (emlxs_be3_flash_dir_t *)bptr; 1212 break; 1213 } 1214 } 1215 1216 if (!flash_dir) { 1217 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1218 "Unable to find flash directory."); 1219 1220 return (EMLXS_IMAGE_BAD); 1221 } 1222 1223 #ifdef EMLXS_BIG_ENDIAN 1224 /* Big Endian Swapping */ 1225 /* Swap flash dir */ 1226 flash_dir->header.format_rev = 1227 SWAP32(flash_dir->header.format_rev); 1228 flash_dir->header.checksum = 1229 SWAP32(flash_dir->header.checksum); 1230 flash_dir->header.antidote = 1231 SWAP32(flash_dir->header.antidote); 1232 flash_dir->header.entry_count = 1233 SWAP32(flash_dir->header.entry_count); 1234 flash_dir->header.resv0 = SWAP32(flash_dir->header.resv0); 1235 flash_dir->header.resv1 = SWAP32(flash_dir->header.resv1); 1236 flash_dir->header.resv2 = SWAP32(flash_dir->header.resv2); 1237 flash_dir->header.resv3 = SWAP32(flash_dir->header.resv3); 1238 1239 for (i = 0; i < BE_CONTROLLER_SIZE; i++) { 1240 flash_dir->header.controller[i].vendor_id = 1241 SWAP32(flash_dir->header.controller[i].vendor_id); 1242 flash_dir->header.controller[i].device_id = 1243 SWAP32(flash_dir->header.controller[i].device_id); 1244 flash_dir->header.controller[i].sub_vendor_id = 1245 SWAP32(flash_dir->header.controller[i].sub_vendor_id); 1246 flash_dir->header.controller[i].sub_device_id = 1247 SWAP32(flash_dir->header.controller[i].sub_device_id); 1248 } 1249 1250 for (i = 0; i < flash_dir->header.entry_count; i++) { 1251 entry = &flash_dir->entry[i]; 1252 1253 if ((entry->type == 0) || 1254 (entry->type == (uint32_t)-1) || 1255 (entry->image_size == 0)) { 1256 continue; 1257 } 1258 1259 flash_dir->entry[i].type = 1260 SWAP32(flash_dir->entry[i].type); 1261 flash_dir->entry[i].offset = 1262 SWAP32(flash_dir->entry[i].offset); 1263 flash_dir->entry[i].block_size = 1264 SWAP32(flash_dir->entry[i].block_size); 1265 flash_dir->entry[i].image_size = 1266 SWAP32(flash_dir->entry[i].image_size); 1267 flash_dir->entry[i].checksum = 1268 SWAP32(flash_dir->entry[i].checksum); 1269 flash_dir->entry[i].entry_point = 1270 SWAP32(flash_dir->entry[i].entry_point); 1271 flash_dir->entry[i].resv0 = 1272 SWAP32(flash_dir->entry[i].resv0); 1273 flash_dir->entry[i].resv1 = 1274 SWAP32(flash_dir->entry[i].resv1); 1275 } 1276 #endif /* EMLXS_BIG_ENDIAN */ 1277 1278 /* Verify image checksum */ 1279 if (flash_dir->header.checksum != flash_image_hdr->checksum) { 1280 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1281 "Invalid flash directory checksum. (%x != %x)\n", 1282 flash_dir->header.checksum, flash_image_hdr->checksum); 1283 return (EMLXS_IMAGE_BAD); 1284 } 1285 1286 /* Verify adapter model */ 1287 found = 0; 1288 for (i = 0; i < BE_CONTROLLER_SIZE; i++) { 1289 if (flash_dir->header.controller[i].device_id == 1290 hba->model_info.device_id) { 1291 found = 1; 1292 } 1293 } 1294 1295 if (!found) { 1296 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 1297 "Invalid adapter device id=0x%x.", 1298 hba->model_info.device_id); 1299 return (EMLXS_IMAGE_INCOMPATIBLE); 1300 } 1301 1302 /* Build fw_image table */ 1303 fw_image->be_version = 3; 1304 fw_image->ufi_plus = ufi_plus; 1305 for (i = 0; i < flash_dir->header.entry_count; i++) { 1306 entry = &flash_dir->entry[i]; 1307 1308 if ((entry->type == 0) || 1309 (entry->type == (uint32_t)-1) || 1310 (entry->image_size == 0)) { 1311 continue; 1312 } 1313 1314 switch (entry->type) { 1315 case BE_FLASHTYPE_REDBOOT: 1316 file = &fw_image->file[REDBOOT_FLASHTYPE]; 1317 (void) strcpy(file->label, "REDBOOT"); 1318 file->type = MGMT_FLASHROM_OPTYPE_REDBOOT; 1319 break; 1320 case BE_FLASHTYPE_ISCSI_BIOS: 1321 file = &fw_image->file[ISCSI_BIOS_FLASHTYPE]; 1322 (void) strcpy(file->label, "ISCSI BIOS"); 1323 file->type = MGMT_FLASHROM_OPTYPE_ISCSI_BIOS; 1324 break; 1325 case BE_FLASHTYPE_PXE_BIOS: 1326 file = &fw_image->file[PXE_BIOS_FLASHTYPE]; 1327 (void) strcpy(file->label, "PXE BIOS"); 1328 file->type = MGMT_FLASHROM_OPTYPE_PXE_BIOS; 1329 break; 1330 case BE_FLASHTYPE_FCOE_BIOS: 1331 file = &fw_image->file[FCOE_BIOS_FLASHTYPE]; 1332 (void) strcpy(file->label, "FCOE BIOS"); 1333 file->type = MGMT_FLASHROM_OPTYPE_FCOE_BIOS; 1334 break; 1335 case BE_FLASHTYPE_ISCSI_FIRMWARE: 1336 file = &fw_image->file[ISCSI_FIRMWARE_FLASHTYPE]; 1337 (void) strcpy(file->label, "ISCSI FIRMWARE"); 1338 file->type = MGMT_FLASHROM_OPTYPE_ISCSI_FIRMWARE; 1339 break; 1340 case BE_FLASHTYPE_FCOE_FIRMWARE: 1341 file = &fw_image->file[FCOE_FIRMWARE_FLASHTYPE]; 1342 (void) strcpy(file->label, "FCOE FIRMWARE"); 1343 file->type = MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE; 1344 break; 1345 case BE_FLASHTYPE_NCSI_FIRMWARE: 1346 file = &fw_image->file[NCSI_FIRMWARE_FLASHTYPE]; 1347 (void) strcpy(file->label, "NCSI FIRMWARE"); 1348 file->type = MGMT_FLASHROM_OPTYPE_NCSI_FIRMWARE; 1349 break; 1350 case BE_FLASHTYPE_FLASH_ISM: 1351 case BE_FLASHTYPE_FCOE_BACKUP: 1352 case BE_FLASHTYPE_ISCSI_BACKUP: 1353 continue; 1354 1355 default: 1356 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1357 "Unknown image type found. type=%x", 1358 entry->type); 1359 continue; 1360 } 1361 1362 file->be_version = fw_image->be_version; 1363 file->ufi_plus = fw_image->ufi_plus; 1364 file->image_size = entry->image_size; 1365 1366 if (ufi_plus) { 1367 file->image_offset = entry->offset; 1368 file->block_size = entry->block_size; 1369 file->block_crc = entry->checksum; 1370 file->load_address = entry->entry_point; 1371 } else { 1372 file->image_offset = entry->offset + 1373 flash_image_hdr->offset; 1374 file->block_size = entry->block_size; 1375 1376 wptr = (uint32_t *)(buffer + file->image_offset + 1377 file->block_size); 1378 1379 /* Read load address */ 1380 value = *(wptr - 3); 1381 file->load_address = BE_SWAP32(value); 1382 1383 /* Read block_crc */ 1384 value = *(wptr - 1); 1385 file->block_crc = BE_SWAP32(value); 1386 } 1387 1388 /* Make sure image will fit in block specified */ 1389 if (file->image_size + 12 > file->block_size) { 1390 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1391 "%s: Image too large for block. image=%x block=%x", 1392 file->label, file->image_size, file->block_size); 1393 1394 bzero(fw_image, sizeof (emlxs_be_fw_image_t)); 1395 return (EMLXS_IMAGE_BAD); 1396 } 1397 1398 /* Automatically create a backup file entry for firmware */ 1399 if (file->type == MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE) { 1400 file2 = &fw_image->file[FCOE_BACKUP_FLASHTYPE]; 1401 1402 bcopy((uint8_t *)file, (uint8_t *)file2, 1403 sizeof (emlxs_be_fw_file_t)); 1404 file2->type = MGMT_FLASHROM_OPTYPE_FCOE_BACKUP; 1405 (void) strcpy(file2->label, "FCOE BACKUP"); 1406 1407 /* Save FCOE version info */ 1408 bptr = (uint8_t *)buffer + file->image_offset + 0x30; 1409 (void) strncpy(fw_image->fcoe_label, (char *)bptr, 1410 BE_VERSION_SIZE); 1411 fw_image->fcoe_version = file->block_crc; 1412 1413 } else if (file->type == 1414 MGMT_FLASHROM_OPTYPE_ISCSI_FIRMWARE) { 1415 file2 = &fw_image->file[ISCSI_BACKUP_FLASHTYPE]; 1416 1417 bcopy((uint8_t *)file, (uint8_t *)file2, 1418 sizeof (emlxs_be_fw_file_t)); 1419 file2->type = MGMT_FLASHROM_OPTYPE_ISCSI_BACKUP; 1420 (void) strcpy(file2->label, "ISCSI BACKUP"); 1421 1422 /* Save ISCSI version info */ 1423 bptr = (uint8_t *)buffer + file->image_offset + 0x30; 1424 (void) strncpy(fw_image->iscsi_label, (char *)bptr, 1425 BE_VERSION_SIZE); 1426 fw_image->iscsi_version = file->block_crc; 1427 } 1428 } 1429 1430 if (fw_image->fcoe_version == 0) { 1431 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1432 "Unable to find FCOE firmware component."); 1433 1434 bzero(fw_image, sizeof (emlxs_be_fw_image_t)); 1435 return (EMLXS_IMAGE_BAD); 1436 } 1437 1438 /* Display contents */ 1439 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1440 "BE3 UFI Image: %08x, %s", fw_image->fcoe_version, 1441 fw_image->fcoe_label); 1442 1443 for (i = 0; i < BE_MAX_FLASHTYPES; i++) { 1444 file = &fw_image->file[i]; 1445 1446 if (file->image_size == 0) { 1447 continue; 1448 } 1449 1450 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1451 "%s: be=%x%s type=%x block=%x image=%x offset=%x crc=%x " 1452 "load=%x", 1453 file->label, file->be_version, (file->ufi_plus)? "+":"", 1454 file->type, file->block_size, file->image_size, 1455 file->image_offset, file->block_crc, file->load_address); 1456 } 1457 1458 return (0); 1459 1460 } /* emlxs_be3_validate_image() */ 1461 1462 1463 static int32_t 1464 emlxs_sli4_fw_download(emlxs_hba_t *hba, caddr_t buffer, uint32_t len, 1465 uint32_t offline) 1466 { 1467 emlxs_port_t *port = &PPORT; 1468 uint32_t i; 1469 uint32_t update = 0; 1470 uint32_t rval = 0; 1471 MAILBOXQ *mbq = NULL; 1472 MATCHMAP *mp = NULL; 1473 emlxs_be_fw_image_t fw_image; 1474 emlxs_be_fw_file_t *file; 1475 uint32_t be_version; 1476 1477 /* For now we will not take the driver offline during a download */ 1478 offline = 0; 1479 1480 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) { 1481 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 1482 "Invalid sli_mode. mode=%d", hba->sli_mode); 1483 return (EMLXS_IMAGE_INCOMPATIBLE); 1484 } 1485 1486 if (buffer == NULL || len == 0) { 1487 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1488 "Empty buffer provided. buf=%p size=%d", buffer, len); 1489 return (EMLXS_IMAGE_BAD); 1490 } 1491 1492 be_version = emlxs_be_version(buffer, len, 0); 1493 1494 switch (be_version) { 1495 case 0: 1496 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 1497 "Invalid image provided. Non-UFI format."); 1498 return (EMLXS_IMAGE_INCOMPATIBLE); 1499 case 2: 1500 rval = emlxs_be2_validate_image(hba, buffer, len, &fw_image); 1501 if (rval) { 1502 return (rval); 1503 } 1504 break; 1505 case 3: 1506 rval = emlxs_be3_validate_image(hba, buffer, len, &fw_image); 1507 if (rval) { 1508 return (rval); 1509 } 1510 break; 1511 default: 1512 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 1513 "Invalid image provided. Unknown BE version. (%x)", 1514 be_version); 1515 return (EMLXS_IMAGE_INCOMPATIBLE); 1516 } 1517 1518 /* Allocate resources */ 1519 1520 if ((mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1521 KM_SLEEP)) == NULL) { 1522 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1523 "Unable to allocate mailbox buffer."); 1524 1525 offline = 0; 1526 rval = EMLXS_IMAGE_FAILED; 1527 goto done; 1528 } 1529 1530 if ((mp = emlxs_mem_buf_alloc(hba, (sizeof (mbox_req_hdr_t) + 1531 sizeof (IOCTL_COMMON_FLASHROM) + BE_MAX_XFER_SIZE))) == NULL) { 1532 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1533 "Unable to allocate flash buffer."); 1534 1535 offline = 0; 1536 rval = EMLXS_IMAGE_FAILED; 1537 goto done; 1538 } 1539 1540 /* Check if update is required */ 1541 for (i = 0; i < BE_MAX_FLASHTYPES; i++) { 1542 file = &fw_image.file[i]; 1543 1544 if (file->image_size == 0) { 1545 continue; 1546 } 1547 1548 rval = emlxs_sli4_verify_crc(hba, file, mbq, mp); 1549 1550 if (rval == 0) { 1551 /* Do not update */ 1552 file->image_size = 0; 1553 continue; 1554 } 1555 1556 update++; 1557 } 1558 1559 if (!update) { 1560 offline = 0; 1561 rval = 0; 1562 goto done; 1563 } 1564 1565 /* 1566 * Everything checks out, now to just do it 1567 */ 1568 if (offline) { 1569 if (emlxs_offline(hba) != FC_SUCCESS) { 1570 1571 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1572 "Unable to take adapter offline."); 1573 1574 offline = 0; 1575 rval = EMLXS_OFFLINE_FAILED; 1576 goto done; 1577 } 1578 } 1579 1580 /* Download entries which require update */ 1581 for (i = 0; i < BE_MAX_FLASHTYPES; i++) { 1582 file = &fw_image.file[i]; 1583 1584 if (file->image_size == 0) { 1585 continue; 1586 } 1587 1588 rval = emlxs_sli4_flash_image(hba, buffer, file, mbq, mp); 1589 1590 if (rval != 0) { 1591 goto done; 1592 } 1593 } 1594 1595 done: 1596 if (mbq) { 1597 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 1598 } 1599 1600 if (mp) { 1601 emlxs_mem_buf_free(hba, mp); 1602 } 1603 1604 if (offline) { 1605 (void) emlxs_online(hba); 1606 } 1607 1608 if (rval == 0) { 1609 if (update) { 1610 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_complete_msg, 1611 "Status good."); 1612 1613 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_updated_msg, 1614 "Please reboot system or power cycle adapter " 1615 "to activate new firmware: %s", 1616 fw_image.fcoe_label); 1617 1618 } else { 1619 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1620 "No firmware update required."); 1621 } 1622 } 1623 1624 return (rval); 1625 1626 } /* emlxs_sli4_fw_download() */ 1627 1628 1629 extern int32_t 1630 emlxs_cfl_download(emlxs_hba_t *hba, uint32_t region, caddr_t buffer, 1631 uint32_t len) 1632 { 1633 emlxs_port_t *port = &PPORT; 1634 MAILBOXQ *mbox = NULL; 1635 MAILBOX *mb; 1636 uint32_t rval = 0; 1637 uint32_t region_id; 1638 uint32_t id; 1639 #ifdef EMLXS_BIG_ENDIAN 1640 caddr_t local_buffer; 1641 uint32_t *bptr1; 1642 uint32_t *bptr2; 1643 uint32_t i; 1644 #endif /* EMLXS_BIG_ENDIAN */ 1645 1646 if (buffer == NULL || len == 0) { 1647 return (EMLXS_IMAGE_BAD); 1648 } 1649 1650 #ifdef EMLXS_BIG_ENDIAN 1651 /* We need to swap the image buffer before we start */ 1652 1653 /* 1654 * Use KM_SLEEP to allocate a temporary buffer 1655 */ 1656 local_buffer = (caddr_t)kmem_zalloc(len, KM_SLEEP); 1657 1658 /* Perform a 32 bit swap of the image */ 1659 bptr1 = (uint32_t *)local_buffer; 1660 bptr2 = (uint32_t *)buffer; 1661 1662 for (i = 0; i < (len / 4); i++) { 1663 *bptr1 = SWAP32(*bptr2); 1664 bptr1++; 1665 bptr2++; 1666 } 1667 1668 /* Replace the original buffer */ 1669 buffer = local_buffer; 1670 1671 #endif /* EMLXS_BIG_ENDIAN */ 1672 1673 if (len > 128) { 1674 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1675 "Invalid image length: 0x%x > 128", len); 1676 1677 return (EMLXS_IMAGE_BAD); 1678 } 1679 1680 /* Check the region number */ 1681 if ((region > 2) && (region != 0xff)) { 1682 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1683 "Invalid region id: 0x%x", region); 1684 1685 return (EMLXS_IMAGE_BAD); 1686 1687 } 1688 1689 /* Check the image vendor id */ 1690 id = *(int32_t *)buffer; 1691 if ((id & 0xffff) != 0x10df) { 1692 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1693 "Invalid image id: 0x%x", id); 1694 1695 return (EMLXS_IMAGE_BAD); 1696 } 1697 1698 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1699 KM_NOSLEEP)) == NULL) { 1700 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1701 "Unable to allocate mailbox buffer."); 1702 1703 rval = 1; 1704 1705 goto done; 1706 } 1707 1708 mb = (MAILBOX *)mbox; 1709 1710 /* 1711 * Everything checks out, now to just do it 1712 */ 1713 if (emlxs_offline(hba) != FC_SUCCESS) { 1714 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1715 "Unable to take HBA offline."); 1716 1717 rval = EMLXS_OFFLINE_FAILED; 1718 1719 goto done; 1720 } 1721 1722 if (EMLXS_SLI_HBA_RESET(hba, 1, 1, 0) != FC_SUCCESS) { 1723 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1724 "Unable to restart adapter."); 1725 1726 rval = EMLXS_OFFLINE_FAILED; 1727 1728 goto done; 1729 } 1730 1731 /* Check if default region is requested */ 1732 if (region == 0xff) { 1733 /* 1734 * Sun-branded Helios and Zypher have different 1735 * default PCI region 1736 */ 1737 if ((hba->model_info.flags & EMLXS_SUN_BRANDED) && 1738 (hba->model_info.chip & 1739 (EMLXS_HELIOS_CHIP | EMLXS_ZEPHYR_CHIP))) { 1740 region = 2; 1741 } else { 1742 region = 0; 1743 } 1744 } 1745 1746 /* Set region id based on PCI region requested */ 1747 region_id = DEF_PCI_CFG_REGION_ID + region; 1748 1749 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1750 "PCI configuration: PCI%d region=%d id=0x%x size=%d", region, 1751 region_id, id, len); 1752 1753 /* Copy the data buffer to SLIM */ 1754 WRITE_SLIM_COPY(hba, (uint32_t *)buffer, 1755 (volatile uint32_t *)((volatile char *)hba->sli.sli3.slim_addr + 1756 sizeof (MAILBOX)), (len / sizeof (uint32_t))); 1757 1758 #ifdef FMA_SUPPORT 1759 if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle) 1760 != DDI_FM_OK) { 1761 EMLXS_MSGF(EMLXS_CONTEXT, 1762 &emlxs_invalid_access_handle_msg, NULL); 1763 rval = 1; 1764 } 1765 #endif /* FMA_SUPPORT */ 1766 1767 emlxs_format_update_pci_cfg(hba, mbox, region_id, len); 1768 1769 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 1770 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1771 "Unable to update PCI configuration: Mailbox cmd=%x " 1772 "status=%x info=%d", mb->mbxCommand, mb->mbxStatus, 1773 mb->un.varUpdateCfg.rsp_info); 1774 1775 rval = 1; 1776 } 1777 1778 (void) emlxs_online(hba); 1779 1780 if (rval == 0) { 1781 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_complete_msg, 1782 "Status good."); 1783 } 1784 1785 done: 1786 1787 if (mbox) { 1788 kmem_free(mbox, sizeof (MAILBOXQ)); 1789 } 1790 1791 #ifdef EMLXS_BIG_ENDIAN 1792 /* Free the local buffer */ 1793 kmem_free(local_buffer, len); 1794 #endif /* EMLXS_BIG_ENDIAN */ 1795 1796 return (rval); 1797 1798 } /* emlxs_cfl_download */ 1799 1800 1801 static uint32_t 1802 emlxs_valid_cksum(uint32_t *StartAddr, uint32_t *EndAddr) 1803 { 1804 uint32_t Temp; 1805 uint32_t CkSum; 1806 1807 EndAddr++; 1808 CkSum = SLI_CKSUM_SEED; 1809 1810 CkSum = (CkSum >> 1) | (CkSum << 31); 1811 while (StartAddr != EndAddr) { 1812 CkSum = (CkSum << 1) | (CkSum >> 31); 1813 Temp = *StartAddr; 1814 1815 CkSum ^= Temp; 1816 StartAddr++; 1817 } 1818 1819 return (CkSum << 1) | (CkSum >> 31); 1820 1821 } /* emlxs_valid_cksum() */ 1822 1823 1824 static void 1825 emlxs_disp_aif_header(emlxs_hba_t *hba, PAIF_HDR AifHdr) 1826 { 1827 emlxs_port_t *port = &PPORT; 1828 1829 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "AIF Header: "); 1830 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1831 "AIF Header: compress_br = 0x%x", AifHdr->CompressBr); 1832 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1833 "AIF Header: reloc_br = 0x%x", AifHdr->RelocBr); 1834 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1835 "AIF Header: zinit_br = 0x%x", AifHdr->ZinitBr); 1836 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1837 "AIF Header: entry_br = 0x%x", AifHdr->EntryBr); 1838 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1839 "AIF Header: area_id = 0x%x", AifHdr->Area_ID); 1840 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1841 "AIF Header: rosize = 0x%x", AifHdr->RoSize); 1842 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1843 "AIF Header: dbgsize = 0x%x", AifHdr->DbgSize); 1844 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1845 "AIF Header: zinitsize = 0x%x", AifHdr->ZinitSize); 1846 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1847 "AIF Header: dbgtype = 0x%x", AifHdr->DbgType); 1848 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1849 "AIF Header: imagebase = 0x%x", AifHdr->ImageBase); 1850 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1851 "AIF Header: area_size = 0x%x", AifHdr->Area_Size); 1852 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1853 "AIF Header: address_mode = 0x%x", AifHdr->AddressMode); 1854 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1855 "AIF Header: database = 0x%x", AifHdr->DataBase); 1856 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1857 "AIF Header: aversion = 0x%x", AifHdr->AVersion); 1858 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1859 "AIF Header: spare2 = 0x%x", AifHdr->Spare2); 1860 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1861 "AIF Header: debug_swi = 0x%x", AifHdr->DebugSwi); 1862 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1863 "AIF Header: zinitcode[0] = 0x%x", AifHdr->ZinitCode[0]); 1864 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1865 "AIF Header: zinitcode[1] = 0x%x", AifHdr->ZinitCode[1]); 1866 1867 } /* emlxs_disp_aif_header() */ 1868 1869 1870 1871 static void 1872 emlxs_dump_image_header(emlxs_hba_t *hba, PIMAGE_HDR image) 1873 { 1874 emlxs_port_t *port = &PPORT; 1875 1876 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "Img Header: "); 1877 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1878 "Img Header: BlockSize = 0x%x", image->BlockSize); 1879 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1880 "Img Header: PROG_ID Type = 0x%x", image->Id.Type); 1881 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1882 "Img Header: PROG_ID Id = 0x%x", image->Id.Id); 1883 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1884 "Img Header: PROG_ID Ver = 0x%x", image->Id.Ver); 1885 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1886 "Img Header: PROG_ID Rev = 0x%x", image->Id.Rev); 1887 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1888 "Img Header: PROG_ID revcomp = 0x%x", image->Id.un.revcomp); 1889 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1890 "Img Header: Flags = 0x%x", image->Flags); 1891 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1892 "Img Header: EntryAdr = 0x%x", image->EntryAdr); 1893 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1894 "Img Header: InitAdr = 0x%x", image->InitAdr); 1895 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1896 "Img Header: ExitAdr = 0x%x", image->ExitAdr); 1897 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1898 "Img Header: ImageBase = 0x%x", image->ImageBase); 1899 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1900 "Img Header: ImageSize = 0x%x", image->ImageSize); 1901 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1902 "Img Header: ZinitSize = 0x%x", image->ZinitSize); 1903 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1904 "Img Header: RelocSize = 0x%x", image->RelocSize); 1905 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1906 "Img Header: HdrCks = 0x%x", image->HdrCks); 1907 1908 } /* emlxs_dump_image_header() */ 1909 1910 1911 static void 1912 emlxs_format_dump(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t Type, 1913 uint32_t RegionId, uint32_t WordCount, uint32_t BaseAddr) 1914 { 1915 1916 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 1917 MAILBOX4 *mb = (MAILBOX4 *)mbq; 1918 1919 /* Clear the local dump_region */ 1920 bzero(hba->sli.sli4.dump_region.virt, 1921 hba->sli.sli4.dump_region.size); 1922 1923 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 1924 1925 mb->mbxCommand = MBX_DUMP_MEMORY; 1926 mb->un.varDmp4.type = Type; 1927 mb->un.varDmp4.entry_index = BaseAddr; 1928 mb->un.varDmp4.region_id = RegionId; 1929 1930 mb->un.varDmp4.available_cnt = min((WordCount*4), 1931 hba->sli.sli4.dump_region.size); 1932 mb->un.varDmp4.addrHigh = 1933 PADDR_HI(hba->sli.sli4.dump_region.phys); 1934 mb->un.varDmp4.addrLow = 1935 PADDR_LO(hba->sli.sli4.dump_region.phys); 1936 mb->un.varDmp4.rsp_cnt = 0; 1937 1938 mb->mbxOwner = OWN_HOST; 1939 1940 } else { 1941 MAILBOX *mb = (MAILBOX *)mbq; 1942 1943 bzero((void *)mb, MAILBOX_CMD_BSIZE); 1944 1945 mb->mbxCommand = MBX_DUMP_MEMORY; 1946 mb->un.varDmp.type = Type; 1947 mb->un.varDmp.region_id = RegionId; 1948 mb->un.varDmp.word_cnt = WordCount; 1949 mb->un.varDmp.base_adr = BaseAddr; 1950 mb->mbxOwner = OWN_HOST; 1951 } 1952 1953 mbq->mbox_cmpl = NULL; /* no cmpl needed */ 1954 1955 return; 1956 1957 } /* emlxs_format_dump() */ 1958 1959 1960 /* ARGSUSED */ 1961 static uint32_t 1962 emlxs_start_abs_download(emlxs_hba_t *hba, 1963 PAIF_HDR AifHdr, 1964 caddr_t Buffer, 1965 uint32_t len, 1966 PWAKE_UP_PARMS WakeUpParms) 1967 { 1968 emlxs_port_t *port = &PPORT; 1969 uint32_t DlByteCount = AifHdr->RoSize + AifHdr->RwSize; 1970 uint32_t *Src; 1971 uint32_t *Dst; 1972 caddr_t DataBuffer = NULL; 1973 MAILBOXQ *mbox; 1974 MAILBOX *mb; 1975 uint32_t rval = 1; 1976 uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT; 1977 uint32_t DlToAddr = AifHdr->ImageBase; 1978 uint32_t DlCount; 1979 uint32_t i; 1980 WAKE_UP_PARMS AbsWakeUpParms; 1981 int32_t AbsChangeParams; 1982 1983 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1984 "Performing absolute download..."); 1985 1986 if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT, 1987 KM_NOSLEEP)) == NULL) { 1988 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1989 "Unable to allocate data buffer."); 1990 1991 return (rval); 1992 } 1993 1994 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1995 KM_NOSLEEP)) == NULL) { 1996 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1997 "Unable to allocate mailbox buffer."); 1998 1999 kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 2000 2001 return (rval); 2002 } 2003 mb = (MAILBOX *)mbox; 2004 2005 AbsChangeParams = emlxs_build_parms(Buffer, 2006 &AbsWakeUpParms, len, AifHdr); 2007 2008 Buffer += sizeof (AIF_HDR); 2009 2010 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "Erasing flash..."); 2011 2012 if (AifHdr->ImageBase == 0x20000) { 2013 /* DWC File */ 2014 emlxs_format_prog_flash(mbox, 0x20000, 0x50000, ERASE_FLASH, 0, 2015 0, 0, NULL, 0); 2016 } else { 2017 emlxs_format_prog_flash(mbox, DlToAddr, DlByteCount, 2018 ERASE_FLASH, 0, 0, 0, NULL, 0); 2019 } 2020 2021 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2022 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2023 "Unable to erase Flash: Mailbox cmd=%x status=%x", 2024 mb->mbxCommand, mb->mbxStatus); 2025 2026 rval = 1; 2027 2028 goto EXIT_ABS_DOWNLOAD; 2029 } 2030 2031 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 2032 "Programming flash..."); 2033 2034 while (DlByteCount) { 2035 2036 if (DlByteCount > SegSize) { 2037 DlCount = SegSize; 2038 } else { 2039 DlCount = DlByteCount; 2040 } 2041 DlByteCount -= DlCount; 2042 2043 Dst = (uint32_t *)DataBuffer; 2044 Src = (uint32_t *)Buffer; 2045 2046 for (i = 0; i < (DlCount / 4); i++) { 2047 *Dst = *Src; 2048 Dst++; 2049 Src++; 2050 } 2051 2052 WRITE_SLIM_COPY(hba, (uint32_t *)DataBuffer, 2053 (volatile uint32_t *) 2054 ((volatile char *)hba->sli.sli3.slim_addr + 2055 sizeof (MAILBOX)), (DlCount / sizeof (uint32_t))); 2056 2057 emlxs_format_prog_flash(mbox, DlToAddr, DlCount, 2058 PROGRAM_FLASH, (DlByteCount) ? 0 : 1, 0, DlCount, NULL, 0); 2059 2060 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 2061 MBX_SUCCESS) { 2062 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2063 "Unable to program Flash: Mailbox cmd=%x status=%x", 2064 mb->mbxCommand, mb->mbxStatus); 2065 2066 rval = 1; 2067 2068 goto EXIT_ABS_DOWNLOAD; 2069 } 2070 2071 Buffer += DlCount; 2072 DlToAddr += DlCount; 2073 } 2074 2075 #ifdef FMA_SUPPORT 2076 if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle) 2077 != DDI_FM_OK) { 2078 EMLXS_MSGF(EMLXS_CONTEXT, 2079 &emlxs_invalid_access_handle_msg, NULL); 2080 2081 rval = 1; 2082 2083 goto EXIT_ABS_DOWNLOAD; 2084 } 2085 #endif /* FMA_SUPPORT */ 2086 2087 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, "Updating params..."); 2088 2089 if (AbsChangeParams) { 2090 rval = 2091 emlxs_update_wakeup_parms(hba, &AbsWakeUpParms, 2092 WakeUpParms); 2093 } 2094 2095 EXIT_ABS_DOWNLOAD: 2096 if (DataBuffer) { 2097 kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 2098 } 2099 2100 if (mbox) { 2101 kmem_free(mbox, sizeof (MAILBOXQ)); 2102 } 2103 2104 return (rval); 2105 2106 } /* emlxs_start_abs_download() */ 2107 2108 2109 /* ARGSUSED */ 2110 static void 2111 emlxs_format_prog_flash(MAILBOXQ *mbq, 2112 uint32_t Base, 2113 uint32_t DlByteCount, 2114 uint32_t Function, 2115 uint32_t Complete, 2116 uint32_t BdeAddress, 2117 uint32_t BdeSize, 2118 PROG_ID *ProgId, 2119 uint32_t keep) 2120 { 2121 MAILBOX *mb = (MAILBOX *)mbq; 2122 2123 bzero((void *)mb, MAILBOX_CMD_BSIZE); 2124 2125 if (ProgId) { 2126 mb->mbxCommand = MBX_DOWN_LOAD; 2127 } else { 2128 mb->mbxCommand = MBX_LOAD_SM; 2129 } 2130 2131 mb->un.varLdSM.load_cmplt = Complete; 2132 mb->un.varLdSM.method = DL_FROM_SLIM; 2133 mb->un.varLdSM.update_flash = 1; 2134 mb->un.varLdSM.erase_or_prog = Function; 2135 mb->un.varLdSM.dl_to_adr = Base; 2136 mb->un.varLdSM.dl_len = DlByteCount; 2137 mb->un.varLdSM.keep = keep; 2138 2139 if (BdeSize) { 2140 mb->un.varLdSM.un.dl_from_slim_offset = DL_FROM_SLIM_OFFSET; 2141 } else if (ProgId) { 2142 mb->un.varLdSM.un.prog_id = *ProgId; 2143 } else { 2144 mb->un.varLdSM.un.dl_from_slim_offset = 0; 2145 } 2146 2147 mb->mbxOwner = OWN_HOST; 2148 mbq->mbox_cmpl = NULL; 2149 2150 } /* emlxs_format_prog_flash() */ 2151 2152 2153 static void 2154 emlxs_format_update_parms(MAILBOXQ *mbq, PWAKE_UP_PARMS WakeUpParms) 2155 { 2156 MAILBOX *mb = (MAILBOX *)mbq; 2157 2158 bzero((void *)mb, MAILBOX_CMD_BSIZE); 2159 2160 mb->mbxCommand = MBX_UPDATE_CFG; 2161 mb->un.varUpdateCfg.req_type = UPDATE_DATA; 2162 mb->un.varUpdateCfg.region_id = WAKE_UP_PARMS_REGION_ID; 2163 mb->un.varUpdateCfg.entry_len = sizeof (WAKE_UP_PARMS); 2164 mb->un.varUpdateCfg.byte_len = sizeof (WAKE_UP_PARMS); 2165 2166 bcopy((caddr_t)WakeUpParms, 2167 (caddr_t)&(mb->un.varUpdateCfg.cfg_data), 2168 sizeof (WAKE_UP_PARMS)); 2169 mbq->mbox_cmpl = NULL; 2170 2171 } /* emlxs_format_update_parms () */ 2172 2173 2174 /* ARGSUSED */ 2175 static void 2176 emlxs_format_update_pci_cfg(emlxs_hba_t *hba, MAILBOXQ *mbq, 2177 uint32_t region_id, uint32_t size) 2178 { 2179 MAILBOX *mb = (MAILBOX *)mbq; 2180 2181 bzero((void *)mb, MAILBOX_CMD_BSIZE); 2182 2183 mb->mbxCommand = MBX_UPDATE_CFG; 2184 mb->un.varUpdateCfg.Vbit = 1; 2185 mb->un.varUpdateCfg.Obit = 1; 2186 mb->un.varUpdateCfg.cfg_data = DL_FROM_SLIM_OFFSET; 2187 mb->un.varUpdateCfg.req_type = UPDATE_DATA; 2188 mb->un.varUpdateCfg.region_id = region_id; 2189 mb->un.varUpdateCfg.entry_len = size; 2190 mb->un.varUpdateCfg.byte_len = size; 2191 mbq->mbox_cmpl = NULL; 2192 2193 } /* emlxs_format_update_pci_cfg() */ 2194 2195 2196 2197 static uint32_t 2198 emlxs_update_boot_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 2199 PROG_ID * prog_id, uint32_t proc_erom) 2200 { 2201 emlxs_port_t *port = &PPORT; 2202 MAILBOX *mb; 2203 MAILBOXQ *mbox; 2204 uint32_t rval = 0; 2205 PROG_ID old_prog_id; 2206 2207 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2208 KM_NOSLEEP)) == NULL) { 2209 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2210 "Unable to allocate mailbox buffer."); 2211 2212 return (1); 2213 } 2214 2215 mb = (MAILBOX *)mbox; 2216 2217 if (proc_erom && !(hba->model_info.chip & 2218 (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 2219 WakeUpParms->u1.EROM_prog_id = *prog_id; 2220 (void) emlxs_update_exp_rom(hba, WakeUpParms); 2221 } 2222 2223 old_prog_id = WakeUpParms->u0.boot_bios_id; 2224 WakeUpParms->u0.boot_bios_id = *prog_id; 2225 2226 emlxs_format_update_parms(mbox, WakeUpParms); 2227 2228 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2229 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2230 "Unable to update boot wakeup parms: Mailbox cmd=%x " 2231 "status=%x", mb->mbxCommand, mb->mbxStatus); 2232 2233 WakeUpParms->u0.boot_bios_id = old_prog_id; 2234 rval = 1; 2235 } 2236 2237 if (mbox) { 2238 kmem_free(mbox, sizeof (MAILBOXQ)); 2239 } 2240 2241 return (rval); 2242 2243 } /* emlxs_update_boot_wakeup_parms() */ 2244 2245 2246 2247 static uint32_t 2248 emlxs_update_ff_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 2249 PROG_ID *prog_id) 2250 { 2251 emlxs_port_t *port = &PPORT; 2252 uint32_t rval = 0; 2253 MAILBOXQ *mbox; 2254 MAILBOX *mb; 2255 PROG_ID old_prog_id; 2256 2257 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2258 KM_NOSLEEP)) == NULL) { 2259 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2260 "Unable to allocate mailbox buffer."); 2261 2262 return (1); 2263 } 2264 2265 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2266 "FF: Updating parms..."); 2267 2268 mb = (MAILBOX *)mbox; 2269 2270 old_prog_id = WakeUpParms->prog_id; 2271 WakeUpParms->prog_id = *prog_id; 2272 2273 emlxs_format_update_parms(mbox, WakeUpParms); 2274 2275 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2276 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2277 "Unable to update wakeup parameters: Mailbox cmd=%x " 2278 "status=%x", mb->mbxCommand, mb->mbxStatus); 2279 2280 WakeUpParms->prog_id = old_prog_id; 2281 rval = 1; 2282 } 2283 2284 if (mbox) { 2285 kmem_free(mbox, sizeof (MAILBOXQ)); 2286 } 2287 2288 return (rval); 2289 2290 } /* emlxs_update_ff_wakeup_parms() */ 2291 2292 2293 static uint32_t 2294 emlxs_update_sli1_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 2295 PROG_ID * prog_id) 2296 { 2297 emlxs_port_t *port = &PPORT; 2298 uint32_t rval = 0; 2299 MAILBOXQ *mbox; 2300 MAILBOX *mb; 2301 PROG_ID old_prog_id; 2302 2303 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2304 KM_NOSLEEP)) == NULL) { 2305 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2306 "Unable to allocate mailbox buffer."); 2307 2308 return (1); 2309 } 2310 2311 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2312 "SLI1: Updating parms..."); 2313 2314 mb = (MAILBOX *)mbox; 2315 2316 old_prog_id = WakeUpParms->sli1_prog_id; 2317 WakeUpParms->sli1_prog_id = *prog_id; 2318 2319 emlxs_format_update_parms(mbox, WakeUpParms); 2320 2321 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2322 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2323 "Unable to update wakeup parameters. Mailbox cmd=%x " 2324 "status=%x", mb->mbxCommand, mb->mbxStatus); 2325 2326 WakeUpParms->sli1_prog_id = old_prog_id; 2327 rval = 1; 2328 } 2329 2330 if (mbox) { 2331 kmem_free(mbox, sizeof (MAILBOXQ)); 2332 } 2333 2334 return (rval); 2335 2336 } /* emlxs_update_sli1_wakeup_parms() */ 2337 2338 2339 static uint32_t 2340 emlxs_update_sli2_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 2341 PROG_ID * prog_id) 2342 { 2343 emlxs_port_t *port = &PPORT; 2344 uint32_t rval = 0; 2345 MAILBOXQ *mbox; 2346 MAILBOX *mb; 2347 PROG_ID old_prog_id; 2348 2349 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2350 KM_NOSLEEP)) == NULL) { 2351 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2352 "Unable to allocate mailbox buffer."); 2353 2354 return (1); 2355 } 2356 2357 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2358 "SLI2: Updating parms..."); 2359 2360 mb = (MAILBOX *)mbox; 2361 2362 old_prog_id = WakeUpParms->sli2_prog_id; 2363 WakeUpParms->sli2_prog_id = *prog_id; 2364 2365 emlxs_format_update_parms(mbox, WakeUpParms); 2366 2367 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2368 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2369 "Unable to update wakeup parameters. Mailbox cmd=%x " 2370 "status=%x", mb->mbxCommand, mb->mbxStatus); 2371 2372 WakeUpParms->sli2_prog_id = old_prog_id; 2373 rval = 1; 2374 } 2375 2376 if (mbox) { 2377 kmem_free(mbox, sizeof (MAILBOXQ)); 2378 } 2379 2380 return (rval); 2381 2382 } /* emlxs_update_sli2_wakeup_parms() */ 2383 2384 2385 static uint32_t 2386 emlxs_update_sli3_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 2387 PROG_ID *prog_id) 2388 { 2389 emlxs_port_t *port = &PPORT; 2390 uint32_t rval = 0; 2391 MAILBOXQ *mbox; 2392 MAILBOX *mb; 2393 PROG_ID old_prog_id; 2394 2395 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2396 KM_NOSLEEP)) == NULL) { 2397 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2398 "Unable to allocate mailbox buffer."); 2399 2400 return (1); 2401 } 2402 2403 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2404 "SLI3: Updating parms..."); 2405 2406 mb = (MAILBOX *)mbox; 2407 2408 old_prog_id = WakeUpParms->sli3_prog_id; 2409 WakeUpParms->sli3_prog_id = *prog_id; 2410 2411 emlxs_format_update_parms(mbox, WakeUpParms); 2412 2413 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2414 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2415 "Unable to update wakeup parameters. Mailbox cmd=%x " 2416 "status=%x", mb->mbxCommand, mb->mbxStatus); 2417 2418 WakeUpParms->sli3_prog_id = old_prog_id; 2419 rval = 1; 2420 } 2421 2422 if (mbox) { 2423 kmem_free(mbox, sizeof (MAILBOXQ)); 2424 } 2425 2426 return (rval); 2427 2428 } /* emlxs_update_sli3_wakeup_parms() */ 2429 2430 2431 static uint32_t 2432 emlxs_update_sli4_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 2433 PROG_ID *prog_id) 2434 { 2435 emlxs_port_t *port = &PPORT; 2436 uint32_t rval = 0; 2437 MAILBOXQ *mbox; 2438 MAILBOX *mb; 2439 PROG_ID old_prog_id; 2440 2441 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2442 KM_NOSLEEP)) == NULL) { 2443 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2444 "Unable to allocate mailbox buffer."); 2445 2446 return (1); 2447 } 2448 2449 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2450 "SLI4: Updating parms..."); 2451 2452 mb = (MAILBOX *)mbox; 2453 2454 old_prog_id = WakeUpParms->sli4_prog_id; 2455 WakeUpParms->sli4_prog_id = *prog_id; 2456 2457 emlxs_format_update_parms(mbox, WakeUpParms); 2458 2459 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2460 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2461 "Unable to update wakeup parameters. Mailbox cmd=%x " 2462 "status=%x", mb->mbxCommand, mb->mbxStatus); 2463 2464 WakeUpParms->sli4_prog_id = old_prog_id; 2465 rval = 1; 2466 } 2467 2468 if (mbox) { 2469 kmem_free(mbox, sizeof (MAILBOXQ)); 2470 } 2471 2472 return (rval); 2473 2474 } /* emlxs_update_sli4_wakeup_parms() */ 2475 2476 2477 static uint32_t 2478 emlxs_clean_flash(emlxs_hba_t *hba, 2479 PWAKE_UP_PARMS OldWakeUpParms, PWAKE_UP_PARMS NewWakeUpParms) 2480 { 2481 emlxs_port_t *port = &PPORT; 2482 PROG_ID load_list[MAX_LOAD_ENTRY]; 2483 PROG_ID *wakeup_list[MAX_LOAD_ENTRY]; 2484 uint32_t count; 2485 uint32_t i; 2486 uint32_t j; 2487 uint32_t k = 0; 2488 uint32_t *wptr; 2489 2490 if (!NewWakeUpParms) { 2491 return (1); 2492 } 2493 2494 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2495 "Cleaning flash..."); 2496 2497 /* If old wakeup parameter list is available, */ 2498 /* then cleanup old entries */ 2499 if (OldWakeUpParms) { 2500 if (bcmp(&OldWakeUpParms->prog_id, &NewWakeUpParms->prog_id, 2501 sizeof (PROG_ID))) { 2502 2503 wptr = (uint32_t *)&OldWakeUpParms->prog_id; 2504 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2505 "OLD: prog_id: 0x%08x 0x%08x Removing.", 2506 wptr[0], wptr[1]); 2507 2508 (void) emlxs_delete_load_entry(hba, 2509 &OldWakeUpParms->prog_id); 2510 } 2511 2512 if (bcmp(&OldWakeUpParms->u0.boot_bios_id, 2513 &NewWakeUpParms->u0.boot_bios_id, sizeof (PROG_ID))) { 2514 2515 wptr = (uint32_t *)&OldWakeUpParms->u0.boot_bios_id; 2516 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2517 "OLD: boot_bios_id: 0x%08x 0x%08x Removing.", 2518 wptr[0], wptr[1]); 2519 2520 (void) emlxs_delete_load_entry(hba, 2521 &OldWakeUpParms->u0.boot_bios_id); 2522 } 2523 2524 if (bcmp(&OldWakeUpParms->sli1_prog_id, 2525 &NewWakeUpParms->sli1_prog_id, sizeof (PROG_ID))) { 2526 2527 wptr = (uint32_t *)&OldWakeUpParms->sli1_prog_id; 2528 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2529 "OLD: sli1_prog_id: 0x%08x 0x%08x Removing.", 2530 wptr[0], wptr[1]); 2531 2532 (void) emlxs_delete_load_entry(hba, 2533 &OldWakeUpParms->sli1_prog_id); 2534 } 2535 2536 if (bcmp(&OldWakeUpParms->sli2_prog_id, 2537 &NewWakeUpParms->sli2_prog_id, sizeof (PROG_ID))) { 2538 2539 wptr = (uint32_t *)&OldWakeUpParms->sli2_prog_id; 2540 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2541 "OLD: sli2_prog_id: 0x%08x 0x%08x Removing.", 2542 wptr[0], wptr[1]); 2543 2544 (void) emlxs_delete_load_entry(hba, 2545 &OldWakeUpParms->sli2_prog_id); 2546 } 2547 2548 if (bcmp(&OldWakeUpParms->sli3_prog_id, 2549 &NewWakeUpParms->sli3_prog_id, sizeof (PROG_ID))) { 2550 2551 wptr = (uint32_t *)&OldWakeUpParms->sli3_prog_id; 2552 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2553 "OLD: sli3_prog_id: 0x%08x 0x%08x Removing.", 2554 wptr[0], wptr[1]); 2555 2556 (void) emlxs_delete_load_entry(hba, 2557 &OldWakeUpParms->sli3_prog_id); 2558 } 2559 2560 if (bcmp(&OldWakeUpParms->sli4_prog_id, 2561 &NewWakeUpParms->sli4_prog_id, sizeof (PROG_ID))) { 2562 2563 wptr = (uint32_t *)&OldWakeUpParms->sli4_prog_id; 2564 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2565 "OLD: sli4_prog_id: 0x%08x 0x%08x Removing.", 2566 wptr[0], wptr[1]); 2567 2568 (void) emlxs_delete_load_entry(hba, 2569 &OldWakeUpParms->sli4_prog_id); 2570 } 2571 2572 return (0); 2573 } 2574 2575 /* Otherwise use the current load list */ 2576 count = emlxs_get_load_list(hba, load_list); 2577 2578 if (!count) { 2579 return (1); 2580 } 2581 2582 /* Init the wakeup list */ 2583 wptr = (uint32_t *)&NewWakeUpParms->prog_id; 2584 if (*wptr) { 2585 wakeup_list[k++] = &NewWakeUpParms->prog_id; 2586 } 2587 2588 wptr = (uint32_t *)&NewWakeUpParms->u0.boot_bios_id; 2589 if (*wptr) { 2590 wakeup_list[k++] = &NewWakeUpParms->u0.boot_bios_id; 2591 } 2592 2593 wptr = (uint32_t *)&NewWakeUpParms->sli1_prog_id; 2594 if (*wptr) { 2595 wakeup_list[k++] = &NewWakeUpParms->sli1_prog_id; 2596 } 2597 2598 wptr = (uint32_t *)&NewWakeUpParms->sli2_prog_id; 2599 if (*wptr) { 2600 wakeup_list[k++] = &NewWakeUpParms->sli2_prog_id; 2601 } 2602 2603 wptr = (uint32_t *)&NewWakeUpParms->sli3_prog_id; 2604 if (*wptr) { 2605 wakeup_list[k++] = &NewWakeUpParms->sli3_prog_id; 2606 } 2607 2608 wptr = (uint32_t *)&NewWakeUpParms->sli4_prog_id; 2609 if (*wptr) { 2610 wakeup_list[k++] = &NewWakeUpParms->sli4_prog_id; 2611 } 2612 2613 if (k == 0) { 2614 return (0); 2615 } 2616 2617 /* Match load list to wakeup list */ 2618 for (i = 0; i < count; i++) { 2619 2620 wptr = (uint32_t *)&load_list[i]; 2621 2622 for (j = 0; j < k; j++) { 2623 if (bcmp((uint8_t *)wakeup_list[j], 2624 (uint8_t *)&load_list[i], sizeof (PROG_ID)) == 0) { 2625 break; 2626 } 2627 } 2628 2629 /* No match */ 2630 if (j == k) { 2631 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2632 "Load List[%d]: %08x %08x Removing.", 2633 i, wptr[0], wptr[1]); 2634 2635 (void) emlxs_delete_load_entry(hba, &load_list[i]); 2636 } else { 2637 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2638 "Load List[%d]: %08x %08x Preserving.", 2639 i, wptr[0], wptr[1]); 2640 } 2641 } 2642 2643 return (0); 2644 2645 } /* emlxs_clean_flash() */ 2646 2647 2648 /* ARGSUSED */ 2649 static uint32_t 2650 emlxs_start_rel_download(emlxs_hba_t *hba, 2651 PIMAGE_HDR ImageHdr, 2652 caddr_t Buffer, 2653 PWAKE_UP_PARMS WakeUpParms, 2654 uint32_t dwc_flag) 2655 { 2656 emlxs_port_t *port = &PPORT; 2657 MAILBOXQ *mbox; 2658 MAILBOX *mb; 2659 uint32_t *Src; 2660 uint32_t *Dst; 2661 caddr_t DataBuffer = NULL; 2662 uint32_t rval = 0; 2663 uint32_t DlByteCount; 2664 uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT; 2665 uint32_t DlCount; 2666 uint32_t i; 2667 uint32_t *wptr; 2668 2669 wptr = (uint32_t *)&ImageHdr->Id; 2670 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 2671 "Relative download: %08x %08x", wptr[0], wptr[1]); 2672 2673 if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT, 2674 KM_NOSLEEP)) == NULL) { 2675 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2676 "Unable to allocate data buffer."); 2677 2678 return (1); 2679 } 2680 2681 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2682 KM_NOSLEEP)) == NULL) { 2683 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2684 "Unable to allocate mailbox buffer."); 2685 2686 kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 2687 2688 return (1); 2689 } 2690 2691 mb = (MAILBOX *)mbox; 2692 2693 DlByteCount = ImageHdr->BlockSize; 2694 2695 emlxs_format_prog_flash(mbox, 0, DlByteCount, ERASE_FLASH, 0, 0, 0, 2696 &ImageHdr->Id, 0); 2697 2698 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 2699 " Erasing flash..."); 2700 2701 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0); 2702 2703 if (rval) { 2704 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2705 "Unable to erase flash. Mailbox cmd=%x status=%x", 2706 mb->mbxCommand, mb->mbxStatus); 2707 2708 goto EXIT_REL_DOWNLOAD; 2709 } 2710 2711 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 2712 " Programming flash..."); 2713 2714 while (DlByteCount) { 2715 if (DlByteCount > SegSize) { 2716 DlCount = SegSize; 2717 } else { 2718 DlCount = DlByteCount; 2719 } 2720 DlByteCount -= DlCount; 2721 2722 Dst = (uint32_t *)DataBuffer; 2723 Src = (uint32_t *)Buffer; 2724 2725 for (i = 0; i < (DlCount / 4); i++) { 2726 *Dst = *Src; 2727 Dst++; 2728 Src++; 2729 } 2730 2731 WRITE_SLIM_COPY(hba, (uint32_t *)DataBuffer, 2732 (volatile uint32_t *) 2733 ((volatile char *)hba->sli.sli3.slim_addr + 2734 sizeof (MAILBOX)), (DlCount / sizeof (uint32_t))); 2735 2736 emlxs_format_prog_flash(mbox, 2737 0, 2738 DlCount, 2739 PROGRAM_FLASH, 2740 (DlByteCount) ? 0 : 1, 2741 0, DlCount, &ImageHdr->Id, dwc_flag); 2742 2743 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0); 2744 2745 if (rval) { 2746 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2747 "Unable to program flash. Mailbox cmd=%x status=%x", 2748 mb->mbxCommand, mb->mbxStatus); 2749 2750 goto EXIT_REL_DOWNLOAD; 2751 } 2752 2753 Buffer += DlCount; 2754 } 2755 2756 #ifdef FMA_SUPPORT 2757 if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle) 2758 != DDI_FM_OK) { 2759 EMLXS_MSGF(EMLXS_CONTEXT, 2760 &emlxs_invalid_access_handle_msg, NULL); 2761 2762 rval = 1; 2763 2764 goto EXIT_REL_DOWNLOAD; 2765 } 2766 #endif /* FMA_SUPPORT */ 2767 2768 /* Update wakeup parameters */ 2769 switch (ImageHdr->Id.Type) { 2770 case TEST_PROGRAM: 2771 break; 2772 2773 case FUNC_FIRMWARE: 2774 if (!dwc_flag) { 2775 rval = emlxs_update_ff_wakeup_parms(hba, WakeUpParms, 2776 &ImageHdr->Id); 2777 } else { 2778 WakeUpParms->prog_id = ImageHdr->Id; 2779 } 2780 break; 2781 2782 case BOOT_BIOS: 2783 if (!dwc_flag) { 2784 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2785 "BOOT: Updating parms..."); 2786 2787 rval = emlxs_update_boot_wakeup_parms(hba, WakeUpParms, 2788 &ImageHdr->Id, 1); 2789 } else { 2790 if (hba->wakeup_parms.u0.boot_bios_wd[0]) { 2791 WakeUpParms->u0.boot_bios_id = ImageHdr->Id; 2792 } 2793 2794 if (!(hba->model_info.chip & 2795 (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 2796 WakeUpParms->u1.EROM_prog_id = ImageHdr->Id; 2797 } 2798 } 2799 break; 2800 2801 case SLI1_OVERLAY: 2802 if (!dwc_flag) { 2803 rval = emlxs_update_sli1_wakeup_parms(hba, WakeUpParms, 2804 &ImageHdr->Id); 2805 } else { 2806 WakeUpParms->sli1_prog_id = ImageHdr->Id; 2807 } 2808 break; 2809 2810 case SLI2_OVERLAY: 2811 if (!dwc_flag) { 2812 rval = emlxs_update_sli2_wakeup_parms(hba, WakeUpParms, 2813 &ImageHdr->Id); 2814 } else { 2815 WakeUpParms->sli2_prog_id = ImageHdr->Id; 2816 } 2817 break; 2818 2819 case SLI3_OVERLAY: 2820 if (!dwc_flag) { 2821 rval = emlxs_update_sli3_wakeup_parms(hba, WakeUpParms, 2822 &ImageHdr->Id); 2823 } else { 2824 WakeUpParms->sli3_prog_id = ImageHdr->Id; 2825 } 2826 break; 2827 2828 case SLI4_OVERLAY: 2829 if (!dwc_flag) { 2830 rval = emlxs_update_sli4_wakeup_parms(hba, WakeUpParms, 2831 &ImageHdr->Id); 2832 } else { 2833 WakeUpParms->sli4_prog_id = ImageHdr->Id; 2834 } 2835 break; 2836 2837 default: 2838 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2839 "Image type not supported. Type=%x", ImageHdr->Id.Type); 2840 2841 break; 2842 } 2843 2844 EXIT_REL_DOWNLOAD: 2845 if (DataBuffer) { 2846 kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 2847 } 2848 2849 if (mbox) { 2850 kmem_free(mbox, sizeof (MAILBOXQ)); 2851 } 2852 2853 return (rval); 2854 2855 } /* emlxs_start_rel_download() */ 2856 2857 2858 static uint32_t 2859 emlxs_proc_rel_2mb(emlxs_hba_t *hba, caddr_t buffer, emlxs_fw_image_t *fw_image) 2860 { 2861 emlxs_port_t *port = &PPORT; 2862 uint32_t rval = 0; 2863 WAKE_UP_PARMS RelWakeUpParms; 2864 WAKE_UP_PARMS WakeUpParms; 2865 uint32_t i; 2866 IMAGE_HDR ImageHdr; 2867 caddr_t bptr; 2868 uint32_t flash_cleaned = 0; 2869 2870 if (emlxs_read_wakeup_parms(hba, &WakeUpParms, 0)) { 2871 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2872 "Unable to get wakeup parameters."); 2873 2874 return (EMLXS_IMAGE_FAILED); 2875 } 2876 2877 download: 2878 2879 bcopy(&WakeUpParms, &RelWakeUpParms, sizeof (WAKE_UP_PARMS)); 2880 2881 for (i = 0; i < MAX_PROG_TYPES; i++) { 2882 if (!fw_image->prog[i].version) { 2883 continue; 2884 } 2885 2886 bptr = buffer + fw_image->prog[i].offset; 2887 2888 bcopy(bptr, &ImageHdr, sizeof (IMAGE_HDR)); 2889 2890 rval = emlxs_start_rel_download(hba, &ImageHdr, bptr, 2891 &RelWakeUpParms, 1); 2892 2893 if (rval) { 2894 EMLXS_MSGF(EMLXS_CONTEXT, 2895 &emlxs_download_failed_msg, 2896 "Failed to program flash."); 2897 2898 if ((rval == NO_FLASH_MEM_AVAIL) && !flash_cleaned) { 2899 /* Cleanup using current load list */ 2900 (void) emlxs_clean_flash(hba, 0, &WakeUpParms); 2901 2902 flash_cleaned = 1; 2903 goto download; 2904 } 2905 2906 return (EMLXS_IMAGE_FAILED); 2907 } 2908 } 2909 2910 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 2911 "Updating wakeup parameters."); 2912 2913 if (emlxs_update_wakeup_parms(hba, &RelWakeUpParms, 2914 &RelWakeUpParms)) { 2915 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2916 "Unable to update parameters."); 2917 2918 return (EMLXS_IMAGE_FAILED); 2919 } 2920 2921 /* Cleanup using old wakeup paramters */ 2922 (void) emlxs_clean_flash(hba, &WakeUpParms, &RelWakeUpParms); 2923 2924 return (0); 2925 2926 } /* emlxs_proc_rel_2mb() */ 2927 2928 2929 #define FLASH_POLLING_BIT 0x80 2930 #define FLASH_ERROR_BIT 0x20 2931 2932 typedef struct _flash_t 2933 { 2934 uint32_t offset; 2935 uint8_t val; 2936 } flash_t; 2937 2938 2939 2940 static uint32_t 2941 emlxs_write_fcode_flash(emlxs_hba_t *hba, 2942 PIMAGE_HDR ImageHdr, caddr_t Buffer) 2943 { 2944 emlxs_port_t *port = &PPORT; 2945 uint8_t bb; 2946 uint8_t cc; 2947 uint8_t *src; 2948 uint32_t DlByteCount = ImageHdr->BlockSize; 2949 uint32_t i; 2950 uint32_t j; 2951 uint32_t k; 2952 2953 flash_t wr[3] = { 2954 {0x555, 0xaa}, 2955 {0x2aa, 0x55}, 2956 {0x555, 0xa0} 2957 }; 2958 2959 /* Load Fcode */ 2960 src = (uint8_t *)Buffer + sizeof (IMAGE_HDR); 2961 for (i = 0; i < DlByteCount; i++) { 2962 for (k = 0; k < 3; k++) { 2963 SBUS_WRITE_FLASH_COPY(hba, wr[k].offset, wr[k].val); 2964 } 2965 2966 /* Reverse Endian word alignment */ 2967 j = (i & 3) ^ 3; 2968 2969 bb = src[j]; 2970 2971 if (j == 0) { 2972 src += 4; 2973 } 2974 2975 SBUS_WRITE_FLASH_COPY(hba, i, bb); 2976 2977 /* check for complete */ 2978 for (;;) { 2979 DELAYUS(20); 2980 2981 cc = SBUS_READ_FLASH_COPY(hba, i); 2982 2983 /* If data matches then continue */ 2984 if (cc == bb) { 2985 break; 2986 } 2987 2988 /* Polling bit will be inverse final value */ 2989 /* while active */ 2990 if ((cc ^ bb) & FLASH_POLLING_BIT) { 2991 /* Still busy */ 2992 2993 /* Check for error bit */ 2994 if (cc & FLASH_ERROR_BIT) { 2995 /* Read data one more time */ 2996 cc = SBUS_READ_FLASH_COPY(hba, i); 2997 2998 /* Check if data matches */ 2999 if (cc == bb) { 3000 break; 3001 } 3002 3003 EMLXS_MSGF(EMLXS_CONTEXT, 3004 &emlxs_download_failed_msg, 3005 "FCode write error: offset:%x " 3006 "wrote:%x read:%x\n", i, bb, cc); 3007 3008 return (1); 3009 } 3010 } 3011 } 3012 } 3013 3014 /* Load Header */ 3015 src = (uint8_t *)ImageHdr; 3016 3017 for (i = (0xFFFF - sizeof (IMAGE_HDR)); i < 0xFFFF; i++) { 3018 for (k = 0; k < 3; k++) { 3019 SBUS_WRITE_FLASH_COPY(hba, wr[k].offset, wr[k].val); 3020 } 3021 3022 /* Reverse Endian word alignment */ 3023 j = (i & 3) ^ 3; 3024 3025 bb = src[j]; 3026 3027 if (j == 0) { 3028 src += 4; 3029 } 3030 3031 SBUS_WRITE_FLASH_COPY(hba, i, bb); 3032 3033 /* check for complete */ 3034 for (;;) { 3035 DELAYUS(20); 3036 3037 cc = SBUS_READ_FLASH_COPY(hba, i); 3038 3039 /* If data matches then continue */ 3040 if (cc == bb) { 3041 break; 3042 } 3043 3044 /* Polling bit will be inverse final value */ 3045 /* while active */ 3046 if ((cc ^ bb) & FLASH_POLLING_BIT) { 3047 /* Still busy */ 3048 3049 /* Check for error bit */ 3050 if (cc & FLASH_ERROR_BIT) { 3051 /* Read data one more time */ 3052 cc = SBUS_READ_FLASH_COPY(hba, i); 3053 3054 /* Check if data matches */ 3055 if (cc == bb) { 3056 break; 3057 } 3058 3059 EMLXS_MSGF(EMLXS_CONTEXT, 3060 &emlxs_download_failed_msg, 3061 "FCode write error: offset:%x " 3062 "wrote:%x read:%x\n", i, bb, cc); 3063 3064 return (1); 3065 } 3066 } 3067 } 3068 } 3069 3070 #ifdef FMA_SUPPORT 3071 if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.sbus_flash_acc_handle) 3072 != DDI_FM_OK) { 3073 EMLXS_MSGF(EMLXS_CONTEXT, 3074 &emlxs_invalid_access_handle_msg, NULL); 3075 return (1); 3076 } 3077 #endif /* FMA_SUPPORT */ 3078 3079 return (0); 3080 3081 } /* emlxs_write_fcode_flash() */ 3082 3083 3084 3085 static uint32_t 3086 emlxs_erase_fcode_flash(emlxs_hba_t *hba) 3087 { 3088 emlxs_port_t *port = &PPORT; 3089 int32_t i, j; 3090 uint8_t cc; 3091 uint32_t offset; 3092 3093 flash_t ef[6] = { 3094 {0x555, 0xaa}, 3095 {0x2aa, 0x55}, 3096 {0x555, 0x80}, 3097 {0x555, 0xaa}, 3098 {0x2aa, 0x55}, 3099 {0x555, 0x10} 3100 }; 3101 3102 /* Auto select */ 3103 flash_t as[3] = { 3104 {0x555, 0xaa}, 3105 {0x2aa, 0x55}, 3106 {0x555, 0x90} 3107 }; 3108 3109 3110 /* Check Manufacturers Code */ 3111 for (i = 0; i < 3; i++) { 3112 SBUS_WRITE_FLASH_COPY(hba, as[i].offset, as[i].val); 3113 } 3114 3115 cc = SBUS_READ_FLASH_COPY(hba, 0); 3116 3117 /* Check Device Code */ 3118 for (i = 0; i < 3; i++) { 3119 SBUS_WRITE_FLASH_COPY(hba, as[i].offset, as[i].val); 3120 } 3121 3122 cc = SBUS_READ_FLASH_COPY(hba, 1); 3123 3124 3125 /* Check block protections (up to 4 16K blocks = 64K) */ 3126 for (j = 0; j < 4; j++) { 3127 for (i = 0; i < 3; i++) { 3128 SBUS_WRITE_FLASH_COPY(hba, as[i].offset, as[i].val); 3129 } 3130 3131 offset = (j << 14) | 0x2; 3132 3133 cc = SBUS_READ_FLASH_COPY(hba, offset); 3134 3135 if (cc == 0x01) { 3136 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3137 "Block %d is protected and can't be erased.", j); 3138 } 3139 } 3140 3141 /* Write erase flash sequence */ 3142 for (i = 0; i < 6; i++) { 3143 SBUS_WRITE_FLASH_COPY(hba, ef[i].offset, ef[i].val); 3144 } 3145 3146 /* check for complete */ 3147 for (;;) { 3148 /* Delay 3 seconds */ 3149 DELAYMS(3000); 3150 3151 cc = SBUS_READ_FLASH_COPY(hba, 0); 3152 3153 3154 /* If data matches then continue; */ 3155 if (cc == 0xff) { 3156 break; 3157 } 3158 3159 /* Polling bit will be inverse final value while active */ 3160 if ((cc ^ 0xff) & FLASH_POLLING_BIT) { 3161 /* Still busy */ 3162 3163 /* Check for error bit */ 3164 if (cc & FLASH_ERROR_BIT) { 3165 /* Read data one more time */ 3166 cc = SBUS_READ_FLASH_COPY(hba, 0); 3167 3168 /* Check if data matches */ 3169 if (cc == 0xff) { 3170 break; 3171 } 3172 3173 EMLXS_MSGF(EMLXS_CONTEXT, 3174 &emlxs_download_failed_msg, 3175 "FCode write error: offset:%x wrote:%x " 3176 "read:%x\n", i, 0xff, cc); 3177 3178 return (1); 3179 } 3180 } 3181 } 3182 3183 #ifdef FMA_SUPPORT 3184 if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.sbus_flash_acc_handle) 3185 != DDI_FM_OK) { 3186 EMLXS_MSGF(EMLXS_CONTEXT, 3187 &emlxs_invalid_access_handle_msg, NULL); 3188 return (1); 3189 } 3190 #endif /* FMA_SUPPORT */ 3191 3192 return (0); 3193 3194 } /* emlxs_erase_fcode_flash() */ 3195 3196 3197 static uint32_t 3198 emlxs_delete_load_entry(emlxs_hba_t *hba, PROG_ID *progId) 3199 { 3200 emlxs_port_t *port = &PPORT; 3201 MAILBOXQ *mbox = NULL; 3202 MAILBOX *mb; 3203 uint32_t rval = 0; 3204 3205 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 3206 KM_NOSLEEP)) == NULL) { 3207 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3208 "Unable to allocate mailbox buffer."); 3209 3210 return (1); 3211 } 3212 3213 mb = (MAILBOX *)mbox; 3214 mb->mbxCommand = MBX_DEL_LD_ENTRY; 3215 mb->un.varDelLdEntry.list_req = FLASH_LOAD_LIST; 3216 mb->un.varDelLdEntry.prog_id = *progId; 3217 3218 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 3219 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3220 "Unable to delete load entry: Mailbox cmd=%x status=%x", 3221 mb->mbxCommand, mb->mbxStatus); 3222 3223 rval = 1; 3224 } 3225 3226 done: 3227 3228 if (mbox) { 3229 kmem_free(mbox, sizeof (MAILBOXQ)); 3230 } 3231 3232 return (rval); 3233 3234 } /* emlxs_delete_load_entry() */ 3235 3236 3237 extern uint32_t 3238 emlxs_get_load_list(emlxs_hba_t *hba, PROG_ID *load_list) 3239 { 3240 emlxs_port_t *port = &PPORT; 3241 LOAD_ENTRY *LoadEntry; 3242 LOAD_LIST *LoadList = NULL; 3243 uint32_t i; 3244 uint32_t count = 0; 3245 3246 bzero(load_list, (sizeof (PROG_ID) * MAX_LOAD_ENTRY)); 3247 3248 if ((LoadList = (LOAD_LIST *)kmem_zalloc(sizeof (LOAD_LIST), 3249 KM_NOSLEEP)) == NULL) { 3250 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3251 "Unable to allocate LOADLIST buffer."); 3252 3253 goto done; 3254 } 3255 3256 if (emlxs_read_load_list(hba, LoadList)) { 3257 goto done; 3258 } 3259 3260 for (i = 0; i < LoadList->entry_cnt; i++) { 3261 LoadEntry = &LoadList->load_entry[i]; 3262 if ((LoadEntry->un.wd[0] != 0) && 3263 (LoadEntry->un.wd[0] != 0xffffffff)) { 3264 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3265 "Load List[%d]: %08x %08x", count, 3266 LoadEntry->un.wd[0], LoadEntry->un.wd[1]); 3267 3268 load_list[count++] = LoadEntry->un.id; 3269 } 3270 } 3271 3272 done: 3273 3274 if (LoadList) { 3275 kmem_free(LoadList, sizeof (LOAD_LIST)); 3276 } 3277 3278 return (count); 3279 3280 } /* emlxs_get_load_list() */ 3281 3282 3283 extern uint32_t 3284 emlxs_read_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 3285 uint32_t verbose) 3286 { 3287 emlxs_port_t *port = &PPORT; 3288 MAILBOXQ *mbox; 3289 MAILBOX *mb; 3290 uint32_t rval = 0; 3291 uint32_t *wd; 3292 3293 bzero(WakeUpParms, sizeof (WAKE_UP_PARMS)); 3294 3295 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 3296 KM_NOSLEEP)) == NULL) { 3297 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3298 "Unable to allocate mailbox buffer."); 3299 3300 return (1); 3301 } 3302 3303 mb = (MAILBOX *)mbox; 3304 3305 emlxs_format_dump(hba, mbox, 3306 DMP_NV_PARAMS, 3307 WAKE_UP_PARMS_REGION_ID, 3308 sizeof (WAKE_UP_PARMS) / sizeof (uint32_t), 0); 3309 3310 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 3311 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3312 "Unable to get parameters: Mailbox cmd=%x status=%x", 3313 mb->mbxCommand, mb->mbxStatus); 3314 3315 if (mb->un.varDmp.word_cnt == (uint32_t)CFG_DATA_NO_REGION) { 3316 rval = (uint32_t)CFG_DATA_NO_REGION; 3317 } else { 3318 rval = 1; 3319 } 3320 } else { 3321 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 3322 EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle, 3323 0, hba->sli.sli4.dump_region.size, 3324 DDI_DMA_SYNC_FORKERNEL); 3325 3326 bcopy((caddr_t)hba->sli.sli4.dump_region.virt, 3327 (caddr_t)WakeUpParms, sizeof (WAKE_UP_PARMS)); 3328 } else { 3329 bcopy((caddr_t)&mb->un.varDmp.resp_offset, 3330 (caddr_t)WakeUpParms, sizeof (WAKE_UP_PARMS)); 3331 } 3332 3333 if (verbose) { 3334 wd = (uint32_t *)&WakeUpParms->prog_id; 3335 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3336 "Wakeup: prog_id=%08x %08x", wd[0], wd[1]); 3337 3338 wd = (uint32_t *)&WakeUpParms->u0.boot_bios_id; 3339 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3340 "Wakeup: boot_bios_id=%08x %08x", wd[0], wd[1]); 3341 3342 wd = (uint32_t *)&WakeUpParms->sli1_prog_id; 3343 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3344 "Wakeup: sli1_prog_id=%08x %08x", wd[0], wd[1]); 3345 3346 wd = (uint32_t *)&WakeUpParms->sli2_prog_id; 3347 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3348 "Wakeup: sli2_prog_id=%08x %08x", wd[0], wd[1]); 3349 3350 wd = (uint32_t *)&WakeUpParms->sli3_prog_id; 3351 if (wd[0] || wd[1]) { 3352 EMLXS_MSGF(EMLXS_CONTEXT, 3353 &emlxs_init_debug_msg, 3354 "Wakeup: sli3_prog_id=%08x %08x", wd[0], 3355 wd[1]); 3356 } 3357 3358 wd = (uint32_t *)&WakeUpParms->sli4_prog_id; 3359 if (wd[0] || wd[1]) { 3360 EMLXS_MSGF(EMLXS_CONTEXT, 3361 &emlxs_init_debug_msg, 3362 "Wakeup: sli4_prog_id=%08x %08x", wd[0], 3363 wd[1]); 3364 } 3365 3366 wd = (uint32_t *)&WakeUpParms->u1.EROM_prog_id; 3367 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3368 "Wakeup: EROM_prog_id=%08x %08x", wd[0], wd[1]); 3369 3370 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3371 "Wakeup: pci_cfg_rsvd=%x", 3372 WakeUpParms->pci_cfg_rsvd); 3373 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3374 "Wakeup: use_hdw_def=%x", 3375 WakeUpParms->use_hdw_def); 3376 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3377 "Wakeup: pci_cfg_sel=%x", 3378 WakeUpParms->pci_cfg_sel); 3379 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3380 "Wakeup: cfg_lookup=%x", 3381 WakeUpParms->pci_cfg_lookup_sel); 3382 } 3383 } 3384 3385 done: 3386 3387 if (mbox) { 3388 kmem_free(mbox, sizeof (MAILBOXQ)); 3389 } 3390 3391 #ifdef FMA_SUPPORT 3392 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 3393 if (emlxs_fm_check_dma_handle(hba, 3394 hba->sli.sli4.dump_region.dma_handle) != DDI_FM_OK) { 3395 EMLXS_MSGF(EMLXS_CONTEXT, 3396 &emlxs_invalid_dma_handle_msg, 3397 "emlxs_read_wakeup_parms: hdl=%p", 3398 hba->sli.sli4.dump_region.dma_handle); 3399 rval = 1; 3400 } 3401 } 3402 #endif /* FMA_SUPPORT */ 3403 3404 return (rval); 3405 3406 } /* emlxs_read_wakeup_parms() */ 3407 3408 3409 static uint32_t 3410 emlxs_read_load_list(emlxs_hba_t *hba, LOAD_LIST *LoadList) 3411 { 3412 emlxs_port_t *port = &PPORT; 3413 LOAD_ENTRY *LoadEntry; 3414 uint32_t *Uptr; 3415 uint32_t CurEntryAddr; 3416 MAILBOXQ *mbox = NULL; 3417 MAILBOX *mb; 3418 3419 bzero((caddr_t)LoadList, sizeof (LOAD_LIST)); 3420 3421 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 3422 KM_NOSLEEP)) == NULL) { 3423 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3424 "Unable to allocate mailbox buffer."); 3425 3426 return (1); 3427 } 3428 3429 mb = (MAILBOX *)mbox; 3430 3431 emlxs_format_dump(hba, mbox, DMP_MEM_REG, 0, 2, FLASH_LOAD_LIST_ADR); 3432 3433 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 3434 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3435 "Unable to get load list: Mailbox cmd=%x status=%x", 3436 mb->mbxCommand, mb->mbxStatus); 3437 3438 goto done; 3439 } 3440 3441 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 3442 EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle, 0, 3443 hba->sli.sli4.dump_region.size, DDI_DMA_SYNC_FORKERNEL); 3444 Uptr = (uint32_t *)hba->sli.sli4.dump_region.virt; 3445 } else { 3446 Uptr = (uint32_t *)&mb->un.varDmp.resp_offset; 3447 } 3448 3449 LoadList->head = Uptr[0]; 3450 LoadList->tail = Uptr[1]; 3451 3452 CurEntryAddr = LoadList->head; 3453 3454 while ((CurEntryAddr != FLASH_LOAD_LIST_ADR) && 3455 (LoadList->entry_cnt < MAX_LOAD_ENTRY)) { 3456 LoadEntry = &LoadList->load_entry[LoadList->entry_cnt]; 3457 LoadList->entry_cnt++; 3458 3459 emlxs_format_dump(hba, mbox, 3460 DMP_MEM_REG, 0, FLASH_LOAD_ENTRY_SIZE, CurEntryAddr); 3461 3462 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 3463 MBX_SUCCESS) { 3464 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3465 "Unable to get load list (%d): Mailbox cmd=%x " 3466 "status=%x", LoadList->entry_cnt, mb->mbxCommand, 3467 mb->mbxStatus); 3468 3469 goto done; 3470 } 3471 3472 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 3473 EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle, 3474 0, hba->sli.sli4.dump_region.size, 3475 DDI_DMA_SYNC_FORKERNEL); 3476 Uptr = (uint32_t *)hba->sli.sli4.dump_region.virt; 3477 } else { 3478 Uptr = (uint32_t *)&mb->un.varDmp.resp_offset; 3479 } 3480 3481 LoadEntry->next = Uptr[0]; 3482 LoadEntry->prev = Uptr[1]; 3483 LoadEntry->start_adr = Uptr[2]; 3484 LoadEntry->len = Uptr[3]; 3485 LoadEntry->un.wd[0] = Uptr[4]; 3486 LoadEntry->un.wd[1] = Uptr[5]; 3487 3488 /* update next current load entry address */ 3489 CurEntryAddr = LoadEntry->next; 3490 3491 } /* end of while (not end of list) */ 3492 3493 done: 3494 3495 if (mbox) { 3496 kmem_free(mbox, sizeof (MAILBOXQ)); 3497 } 3498 3499 #ifdef FMA_SUPPORT 3500 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 3501 if (emlxs_fm_check_dma_handle(hba, 3502 hba->sli.sli4.dump_region.dma_handle) != DDI_FM_OK) { 3503 EMLXS_MSGF(EMLXS_CONTEXT, 3504 &emlxs_invalid_dma_handle_msg, 3505 "emlxs_read_load_list: hdl=%p", 3506 hba->sli.sli4.dump_region.dma_handle); 3507 return (1); 3508 } 3509 } 3510 #endif /* FMA_SUPPORT */ 3511 3512 return (0); 3513 3514 } /* emlxs_read_load_list() */ 3515 3516 3517 3518 3519 static int 3520 emlxs_build_parms(caddr_t Buffer, 3521 PWAKE_UP_PARMS AbsWakeUpParms, 3522 uint32_t BufferSize, PAIF_HDR AifHeader) 3523 { 3524 IMAGE_HDR ImageHdr; 3525 uint32_t NextImage; 3526 uint32_t i; 3527 int32_t ChangeParams = FALSE; 3528 caddr_t Sptr; 3529 caddr_t Dptr; 3530 3531 bzero((caddr_t)AbsWakeUpParms, sizeof (WAKE_UP_PARMS)); 3532 3533 if ((AifHeader->ImageBase != 0x20000) && 3534 ((AifHeader->RoSize + AifHeader->RwSize) <= 0x20000)) { 3535 return (FALSE); 3536 } 3537 3538 NextImage = SLI_IMAGE_START - AifHeader->ImageBase; 3539 3540 while (BufferSize > NextImage) { 3541 Sptr = &Buffer[NextImage]; 3542 Dptr = (caddr_t)&ImageHdr; 3543 for (i = 0; i < sizeof (IMAGE_HDR); i++) { 3544 Dptr[i] = Sptr[i]; 3545 } 3546 3547 if (ImageHdr.BlockSize == 0xffffffff) 3548 break; 3549 3550 switch (ImageHdr.Id.Type) { 3551 case TEST_PROGRAM: 3552 break; 3553 case FUNC_FIRMWARE: 3554 AbsWakeUpParms->prog_id = ImageHdr.Id; 3555 ChangeParams = TRUE; 3556 break; 3557 case BOOT_BIOS: 3558 AbsWakeUpParms->u0.boot_bios_id = ImageHdr.Id; 3559 ChangeParams = TRUE; 3560 break; 3561 case SLI1_OVERLAY: 3562 AbsWakeUpParms->sli1_prog_id = ImageHdr.Id; 3563 ChangeParams = TRUE; 3564 break; 3565 case SLI2_OVERLAY: 3566 AbsWakeUpParms->sli2_prog_id = ImageHdr.Id; 3567 ChangeParams = TRUE; 3568 break; 3569 case SLI3_OVERLAY: 3570 AbsWakeUpParms->sli3_prog_id = ImageHdr.Id; 3571 ChangeParams = TRUE; 3572 break; 3573 case SLI4_OVERLAY: 3574 AbsWakeUpParms->sli4_prog_id = ImageHdr.Id; 3575 ChangeParams = TRUE; 3576 break; 3577 default: 3578 break; 3579 } 3580 3581 NextImage += ImageHdr.BlockSize; 3582 } 3583 3584 return (ChangeParams); 3585 3586 } /* emlxs_build_parms() */ 3587 3588 3589 static uint32_t 3590 emlxs_update_wakeup_parms(emlxs_hba_t *hba, 3591 PWAKE_UP_PARMS AbsWakeUpParms, PWAKE_UP_PARMS WakeUpParms) 3592 { 3593 emlxs_port_t *port = &PPORT; 3594 MAILBOX *mb; 3595 MAILBOXQ *mbox; 3596 uint32_t rval = 0; 3597 3598 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 3599 KM_NOSLEEP)) == NULL) { 3600 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3601 "Unable to allocate mailbox buffer."); 3602 3603 return (1); 3604 } 3605 3606 mb = (MAILBOX *)mbox; 3607 3608 WakeUpParms->prog_id = AbsWakeUpParms->prog_id; 3609 WakeUpParms->u0.boot_bios_id = AbsWakeUpParms->u0.boot_bios_id; 3610 WakeUpParms->sli1_prog_id = AbsWakeUpParms->sli1_prog_id; 3611 WakeUpParms->sli2_prog_id = AbsWakeUpParms->sli2_prog_id; 3612 WakeUpParms->sli3_prog_id = AbsWakeUpParms->sli3_prog_id; 3613 WakeUpParms->sli4_prog_id = AbsWakeUpParms->sli4_prog_id; 3614 3615 emlxs_format_update_parms(mbox, WakeUpParms); 3616 3617 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 3618 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3619 "Unable to update wakeup parameters: Mailbox cmd=%x " 3620 "status=%x", mb->mbxCommand, mb->mbxStatus); 3621 3622 rval = 1; 3623 } 3624 3625 if (mbox) { 3626 kmem_free(mbox, sizeof (MAILBOXQ)); 3627 } 3628 3629 return (rval); 3630 3631 } /* emlxs_update_wakeup_parms() */ 3632 3633 3634 static uint32_t 3635 emlxs_validate_version(emlxs_hba_t *hba, emlxs_fw_file_t *file, uint32_t id, 3636 uint32_t type, char *file_type) 3637 { 3638 emlxs_port_t *port = &PPORT; 3639 3640 /* Create the version label */ 3641 emlxs_decode_version(file->version, file->label); 3642 3643 /* Process the DWC type */ 3644 switch (type) { 3645 case TEST_PROGRAM: 3646 3647 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3648 "%s: TEST: offset=%08x version=%08x, %s", file_type, 3649 file->offset, file->version, file->label); 3650 3651 break; 3652 3653 case BOOT_BIOS: 3654 3655 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3656 "%s: BOOT: offset=%08x version=%08x, %s", file_type, 3657 file->offset, file->version, file->label); 3658 3659 if (!emlxs_bios_check(hba, id)) { 3660 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3661 "BOOT Check: Image not compatible with %s. id=%02x", 3662 hba->model_info.model, id); 3663 3664 return (EMLXS_IMAGE_INCOMPATIBLE); 3665 } 3666 3667 break; 3668 3669 case FUNC_FIRMWARE: /* Stub */ 3670 3671 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3672 "%s: STUB: offset=%08x version=%08x, %s", file_type, 3673 file->offset, file->version, file->label); 3674 3675 if (!emlxs_stub_check(hba, id)) { 3676 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3677 "STUB Check: Image not compatible with %s. id=%02x", 3678 hba->model_info.model, id); 3679 3680 return (EMLXS_IMAGE_INCOMPATIBLE); 3681 } 3682 3683 break; 3684 3685 case SLI1_OVERLAY: 3686 3687 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3688 "%s: SLI1: offset=%08x version=%08x, %s", file_type, 3689 file->offset, file->version, file->label); 3690 3691 if (!emlxs_sli1_check(hba, id)) { 3692 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3693 "SLI1 Check: Image not compatible with %s. id=%02x", 3694 hba->model_info.model, id); 3695 3696 return (EMLXS_IMAGE_INCOMPATIBLE); 3697 } 3698 3699 break; 3700 3701 case SLI2_OVERLAY: 3702 3703 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3704 "%s: SLI2: offset=%08x version=%08x, %s", file_type, 3705 file->offset, file->version, file->label); 3706 3707 if (!emlxs_sli2_check(hba, id)) { 3708 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3709 "SLI2 Check: Image not compatible with %s. id=%02x", 3710 hba->model_info.model, id); 3711 3712 return (EMLXS_IMAGE_INCOMPATIBLE); 3713 } 3714 3715 break; 3716 3717 case SLI3_OVERLAY: 3718 3719 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3720 "%s: SLI3: offset=%08x version=%08x, %s", file_type, 3721 file->offset, file->version, file->label); 3722 3723 if (!emlxs_sli3_check(hba, id)) { 3724 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3725 "SLI3 Check: Image not compatible with %s. id=%02x", 3726 hba->model_info.model, id); 3727 3728 return (EMLXS_IMAGE_INCOMPATIBLE); 3729 } 3730 3731 break; 3732 3733 case SLI4_OVERLAY: 3734 3735 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3736 "%s: SLI4: offset=%08x version=%08x, %s", file_type, 3737 file->offset, file->version, file->label); 3738 3739 if (!emlxs_sli4_check(hba, id)) { 3740 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3741 "SLI4 Check: Image not compatible with %s. id=%02x", 3742 hba->model_info.model, id); 3743 3744 return (EMLXS_IMAGE_INCOMPATIBLE); 3745 } 3746 3747 break; 3748 3749 case SBUS_FCODE: 3750 3751 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3752 "%s: SBUS FCODE: offset=%08x version=%08x, %s", 3753 file_type, file->offset, file->version, file->label); 3754 3755 if (!emlxs_sbus_fcode_check(hba, id)) { 3756 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3757 "SBUS FCODE Check: Image not compatible with %s. " 3758 "id=%02x", hba->model_info.model, id); 3759 3760 return (EMLXS_IMAGE_INCOMPATIBLE); 3761 } 3762 3763 break; 3764 3765 case KERNEL_CODE: 3766 3767 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3768 "%s: KERN: offset=%08x version=%08x, %s", file_type, 3769 file->offset, file->version, file->label); 3770 3771 if (!emlxs_kern_check(hba, id)) { 3772 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3773 "KERN Check: Image not compatible with %s. id=%02x", 3774 hba->model_info.model, id); 3775 3776 return (EMLXS_IMAGE_INCOMPATIBLE); 3777 } 3778 3779 break; 3780 3781 default: 3782 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 3783 "%s: Image type not supported. type=%x", file_type, type); 3784 3785 return (EMLXS_IMAGE_BAD); 3786 } 3787 3788 return (0); 3789 3790 } /* emlxs_validate_version() */ 3791 3792 3793 static void 3794 emlxs_verify_image(emlxs_hba_t *hba, emlxs_fw_image_t *fw_image) 3795 { 3796 emlxs_port_t *port = &PPORT; 3797 emlxs_vpd_t *vpd = &VPD; 3798 uint32_t i; 3799 uint32_t count; 3800 3801 /* Check for AWC file */ 3802 if (fw_image->awc.version) { 3803 if (fw_image->awc.version == vpd->postKernRev) { 3804 fw_image->awc.version = 0; 3805 } 3806 3807 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 3808 "AWC file: KERN: old=%s new=%s %s.", 3809 vpd->postKernName, 3810 fw_image->awc.label, 3811 (fw_image->awc.version)? "Update":"Skip"); 3812 } 3813 3814 /* Check for BWC file */ 3815 if (fw_image->bwc.version) { 3816 if (strcmp(vpd->fcode_version, fw_image->bwc.label) == 0) { 3817 fw_image->bwc.version = 0; 3818 } 3819 3820 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 3821 "BWC file: BOOT: old=%s new=%s %s.", 3822 vpd->fcode_version, 3823 fw_image->bwc.label, 3824 (fw_image->bwc.version)? "Update":"Skip"); 3825 } 3826 3827 /* Check for DWC file */ 3828 if (fw_image->dwc.version) { 3829 /* Check for program files */ 3830 count = 0; 3831 for (i = 0; i < MAX_PROG_TYPES; i++) { 3832 if (!fw_image->prog[i].version) { 3833 continue; 3834 } 3835 3836 /* Skip components that don't need updating */ 3837 switch (i) { 3838 case TEST_PROGRAM: 3839 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 3840 "DWC file: TEST: new=%s " 3841 "Update.", 3842 fw_image->prog[i].label); 3843 break; 3844 3845 case BOOT_BIOS: 3846 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 3847 "DWC file: BOOT: new=%s " 3848 "Update.", 3849 fw_image->prog[i].label); 3850 break; 3851 3852 case FUNC_FIRMWARE: 3853 if (vpd->opFwRev && 3854 (fw_image->prog[i].version == 3855 vpd->opFwRev)) { 3856 fw_image->prog[i].version = 0; 3857 } 3858 3859 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 3860 "DWC file: STUB: old=%s new=%s %s.", 3861 vpd->opFwName, 3862 fw_image->prog[i].label, 3863 (fw_image->prog[i].version)? 3864 "Update":"Skip"); 3865 break; 3866 3867 case SLI1_OVERLAY: 3868 if (vpd->sli1FwRev && 3869 (fw_image->prog[i].version == 3870 vpd->sli1FwRev)) { 3871 fw_image->prog[i].version = 0; 3872 } 3873 3874 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 3875 "DWC file: SLI1: old=%s new=%s %s.", 3876 vpd->sli1FwName, 3877 fw_image->prog[i].label, 3878 (fw_image->prog[i].version)? 3879 "Update":"Skip"); 3880 break; 3881 3882 case SLI2_OVERLAY: 3883 if (vpd->sli2FwRev && 3884 (fw_image->prog[i].version == 3885 vpd->sli2FwRev)) { 3886 fw_image->prog[i].version = 0; 3887 } 3888 3889 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 3890 "DWC file: SLI2: old=%s new=%s %s.", 3891 vpd->sli2FwName, 3892 fw_image->prog[i].label, 3893 (fw_image->prog[i].version)? 3894 "Update":"Skip"); 3895 break; 3896 3897 case SLI3_OVERLAY: 3898 if (vpd->sli3FwRev && 3899 (fw_image->prog[i].version == 3900 vpd->sli3FwRev)) { 3901 fw_image->prog[i].version = 0; 3902 } 3903 3904 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 3905 "DWC file: SLI3: old=%s new=%s %s.", 3906 vpd->sli3FwName, 3907 fw_image->prog[i].label, 3908 (fw_image->prog[i].version)? 3909 "Update":"Skip"); 3910 break; 3911 3912 case SLI4_OVERLAY: 3913 if (vpd->sli4FwRev && 3914 (fw_image->prog[i].version == 3915 vpd->sli4FwRev)) { 3916 fw_image->prog[i].version = 0; 3917 } 3918 3919 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 3920 "DWC file: SLI4: old=%s new=%s %s.", 3921 vpd->sli4FwRev, 3922 fw_image->prog[i].label, 3923 (fw_image->prog[i].version)? 3924 "Update":"Skip"); 3925 break; 3926 3927 default: 3928 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 3929 "DWC file: type=%x version=%x label=%s " 3930 "Update.", 3931 i, 3932 fw_image->prog[i].version, 3933 fw_image->prog[i].label); 3934 } 3935 3936 if (fw_image->prog[i].version) { 3937 count++; 3938 } 3939 } 3940 3941 if (!count) { 3942 fw_image->dwc.version = 0; 3943 } 3944 } 3945 3946 return; 3947 3948 } /* emlxs_verify_image() */ 3949 3950 3951 static uint32_t 3952 emlxs_validate_image(emlxs_hba_t *hba, caddr_t Buffer, uint32_t Size, 3953 emlxs_fw_image_t *image) 3954 { 3955 emlxs_port_t *port = &PPORT; 3956 uint32_t ImageType; 3957 AIF_HDR AifHdr; 3958 IMAGE_HDR ImageHdr; 3959 uint32_t NextImage; 3960 uint32_t count; 3961 uint32_t FileType; 3962 uint32_t FileLen = 0; 3963 uint32_t TotalLen = 0; 3964 uint32_t *CkSumEnd; 3965 uint32_t id; 3966 uint32_t type; 3967 uint32_t ver; 3968 uint32_t ImageLength; 3969 uint32_t BufferSize; 3970 uint32_t rval = 0; 3971 caddr_t bptr; 3972 emlxs_vpd_t *vpd; 3973 3974 vpd = &VPD; 3975 3976 /* Get image type */ 3977 ImageType = *((uint32_t *)Buffer); 3978 3979 /* Pegasus and beyond adapters */ 3980 if ((ImageType == NOP_IMAGE_TYPE) && 3981 !(hba->model_info.chip & 3982 (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 3983 bptr = Buffer; 3984 TotalLen = sizeof (uint32_t); 3985 3986 while (TotalLen < Size) { 3987 if (Size < sizeof (AIF_HDR)) { 3988 EMLXS_MSGF(EMLXS_CONTEXT, 3989 &emlxs_image_bad_msg, 3990 "Invalid image header length: 0x%x < 0x%x", 3991 Size, sizeof (AIF_HDR)); 3992 3993 return (EMLXS_IMAGE_BAD); 3994 } 3995 3996 bcopy(bptr, &AifHdr, sizeof (AIF_HDR)); 3997 emlxs_disp_aif_header(hba, &AifHdr); 3998 3999 ImageLength = AifHdr.RoSize; 4000 4001 /* Validate checksum */ 4002 CkSumEnd = 4003 (uint32_t *)(bptr + ImageLength + 4004 sizeof (AIF_HDR)); 4005 if (emlxs_valid_cksum((uint32_t *)bptr, CkSumEnd)) { 4006 EMLXS_MSGF(EMLXS_CONTEXT, 4007 &emlxs_image_bad_msg, 4008 "Invalid checksum found."); 4009 4010 return (EMLXS_IMAGE_BAD); 4011 } 4012 4013 FileType = AifHdr.ZinitBr; 4014 switch (FileType) { 4015 case FILE_TYPE_AWC: 4016 image->awc.offset = 4017 (uint32_t)((uintptr_t)bptr - 4018 (uintptr_t)Buffer); 4019 image->awc.version = AifHdr.AVersion; 4020 image->awc.revcomp = 0; 4021 4022 id = (AifHdr.AVersion & 0x00ff0000) >> 16; 4023 type = emlxs_type_check( 4024 (AifHdr.AVersion & 0xff000000) >> 24); 4025 4026 /* Validate the file version */ 4027 if ((rval = emlxs_validate_version(hba, 4028 &image->awc, id, type, "AWC file"))) { 4029 return (rval); 4030 } 4031 4032 break; 4033 4034 case FILE_TYPE_BWC: 4035 image->bwc.offset = 4036 (uint32_t)((uintptr_t)bptr - 4037 (uintptr_t)Buffer); 4038 image->bwc.version = AifHdr.AVersion; 4039 image->bwc.revcomp = 0; 4040 4041 id = (AifHdr.AVersion & 0x00ff0000) >> 16; 4042 type = emlxs_type_check( 4043 (AifHdr.AVersion & 0xff000000) >> 24); 4044 4045 /* Validate the file version */ 4046 if ((rval = emlxs_validate_version(hba, 4047 &image->bwc, id, type, "BWC file"))) { 4048 return (rval); 4049 } 4050 4051 break; 4052 4053 case FILE_TYPE_DWC: 4054 image->dwc.offset = 4055 (uint32_t)((uintptr_t)bptr - 4056 (uintptr_t)Buffer); 4057 image->dwc.version = AifHdr.AVersion; 4058 image->dwc.revcomp = 0; 4059 4060 id = (AifHdr.AVersion & 0x00ff0000) >> 16; 4061 type = emlxs_type_check( 4062 (AifHdr.AVersion & 0xff000000) >> 24); 4063 4064 /* Validate the file version */ 4065 if ((rval = emlxs_validate_version(hba, 4066 &image->dwc, id, type, "DWC file"))) { 4067 return (rval); 4068 } 4069 4070 /* Scan for program types */ 4071 NextImage = sizeof (AIF_HDR) + 4; 4072 BufferSize = AifHdr.RoSize + AifHdr.RwSize; 4073 4074 count = 0; 4075 while (BufferSize > NextImage) { 4076 bcopy(&bptr[NextImage], &ImageHdr, 4077 sizeof (IMAGE_HDR)); 4078 emlxs_dump_image_header(hba, 4079 &ImageHdr); 4080 4081 /* Validate block size */ 4082 if (ImageHdr.BlockSize == 0xffffffff) { 4083 break; 4084 } 4085 4086 type = emlxs_type_check( 4087 ImageHdr.Id.Type); 4088 4089 /* Calculate the program offset */ 4090 image->prog[type].offset = 4091 (uint32_t)((uintptr_t) 4092 &bptr[NextImage] - 4093 (uintptr_t)Buffer); 4094 4095 /* Acquire the versions */ 4096 image->prog[type].version = 4097 (ImageHdr.Id.Type << 24) | 4098 (ImageHdr.Id.Id << 16) | 4099 (ImageHdr.Id.Ver << 8) | 4100 ImageHdr.Id.Rev; 4101 4102 image->prog[type].revcomp = 4103 ImageHdr.Id.un.revcomp; 4104 4105 /* Validate the file version */ 4106 if ((rval = emlxs_validate_version(hba, 4107 &image->prog[type], ImageHdr.Id.Id, 4108 type, "DWC prog"))) { 4109 return (rval); 4110 } 4111 4112 count++; 4113 NextImage += ImageHdr.BlockSize; 4114 4115 } /* while () */ 4116 4117 if (count == 0) { 4118 EMLXS_MSGF(EMLXS_CONTEXT, 4119 &emlxs_image_bad_msg, 4120 "DWC file has no PRG images."); 4121 4122 return (EMLXS_IMAGE_BAD); 4123 } 4124 4125 break; 4126 } 4127 4128 FileLen = 4129 sizeof (AIF_HDR) + ImageLength + 4130 sizeof (uint32_t); 4131 TotalLen += FileLen; 4132 bptr += FileLen; 4133 } 4134 } 4135 4136 /* Pre-pegasus adapters */ 4137 4138 else if (ImageType == NOP_IMAGE_TYPE) { 4139 if (Size < sizeof (AIF_HDR)) { 4140 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 4141 "Invalid image header length: 0x%x < 0x%x", Size, 4142 sizeof (AIF_HDR)); 4143 4144 return (EMLXS_IMAGE_BAD); 4145 } 4146 4147 bcopy(Buffer, &AifHdr, sizeof (AIF_HDR)); 4148 emlxs_disp_aif_header(hba, &AifHdr); 4149 4150 ImageLength = AifHdr.RoSize + AifHdr.RwSize; 4151 4152 if (Size != (sizeof (AIF_HDR) + ImageLength + sizeof (int))) { 4153 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 4154 "Image length incorrect: 0x%x != 0x%x", Size, 4155 sizeof (AIF_HDR) + ImageLength + 4156 sizeof (uint32_t)); 4157 4158 return (EMLXS_IMAGE_BAD); 4159 } 4160 4161 if (AifHdr.ImageBase && AifHdr.ImageBase != 0x20000) { 4162 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 4163 "Invalid imageBase value %x != 0x20000", 4164 AifHdr.ImageBase); 4165 4166 return (EMLXS_IMAGE_BAD); 4167 } 4168 4169 CkSumEnd = 4170 (uint32_t *)(Buffer + ImageLength + sizeof (AIF_HDR)); 4171 if (emlxs_valid_cksum((uint32_t *)Buffer, CkSumEnd)) { 4172 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 4173 "Invalid checksum found."); 4174 4175 return (EMLXS_IMAGE_BAD); 4176 } 4177 4178 image->dwc.offset = 0; 4179 image->dwc.version = AifHdr.AVersion; 4180 image->dwc.revcomp = 0; 4181 4182 id = (AifHdr.AVersion & 0x00ff0000) >> 16; 4183 type = emlxs_type_check((AifHdr.AVersion & 0xff000000) >> 24); 4184 4185 /* Validate the file version */ 4186 if ((rval = emlxs_validate_version(hba, &image->dwc, id, type, 4187 "DWC file"))) { 4188 return (rval); 4189 } 4190 4191 NextImage = SLI_IMAGE_START - AifHdr.ImageBase; 4192 while (Size > NextImage) { 4193 bcopy(&Buffer[NextImage], &ImageHdr, 4194 sizeof (IMAGE_HDR)); 4195 emlxs_dump_image_header(hba, &ImageHdr); 4196 4197 /* Validate block size */ 4198 if (ImageHdr.BlockSize == 0xffffffff) { 4199 break; 4200 } 4201 4202 type = emlxs_type_check(ImageHdr.Id.Type); 4203 4204 /* Calculate the program offset */ 4205 image->prog[type].offset = NextImage; 4206 4207 /* Acquire the versions */ 4208 image->prog[type].version = 4209 (ImageHdr.Id.Type << 24) | 4210 (ImageHdr.Id.Id << 16) | 4211 (ImageHdr.Id.Ver << 8) | 4212 ImageHdr.Id.Rev; 4213 4214 image->prog[type].revcomp = ImageHdr.Id.un.revcomp; 4215 4216 /* Validate the file version */ 4217 if ((rval = emlxs_validate_version(hba, 4218 &image->prog[type], ImageHdr.Id.Id, type, 4219 "DWC prog"))) { 4220 return (rval); 4221 } 4222 4223 NextImage += ImageHdr.BlockSize; 4224 } 4225 4226 } else { /* PRG File */ 4227 4228 /* Precheck image size */ 4229 if (Size < sizeof (IMAGE_HDR)) { 4230 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 4231 "Invalid image header length: 0x%x < 0x%x", Size, 4232 sizeof (IMAGE_HDR)); 4233 4234 return (EMLXS_IMAGE_BAD); 4235 } 4236 4237 bcopy(Buffer, &ImageHdr, sizeof (IMAGE_HDR)); 4238 emlxs_dump_image_header(hba, &ImageHdr); 4239 4240 /* Validate block size */ 4241 if (ImageHdr.BlockSize == 0xffffffff) { 4242 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 4243 "Invalid block size."); 4244 4245 return (EMLXS_IMAGE_BAD); 4246 } 4247 4248 ImageLength = ImageHdr.BlockSize; 4249 4250 /* Validate image length */ 4251 if (Size != ImageLength) { 4252 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 4253 "Invalid image length: 0x%x != 0x%x", Size, 4254 ImageLength); 4255 4256 return (EMLXS_IMAGE_BAD); 4257 } 4258 4259 /* Validate Checksum */ 4260 CkSumEnd = 4261 (uint32_t *)Buffer + (ImageLength / sizeof (uint32_t)) - 4262 1; 4263 if (emlxs_valid_cksum((uint32_t *)Buffer, CkSumEnd)) { 4264 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 4265 "Invalid checksum found."); 4266 4267 return (EMLXS_IMAGE_BAD); 4268 } 4269 4270 type = emlxs_type_check(ImageHdr.Id.Type); 4271 4272 /* Calculate the program offset */ 4273 image->prog[type].offset = 0; 4274 4275 /* Acquire the versions */ 4276 image->prog[type].version = 4277 (ImageHdr.Id.Type << 24) | 4278 (ImageHdr.Id.Id << 16) | 4279 (ImageHdr.Id.Ver << 8) | 4280 ImageHdr.Id.Rev; 4281 4282 image->prog[type].revcomp = ImageHdr.Id.un.revcomp; 4283 4284 /* Validate the file version */ 4285 if ((rval = emlxs_validate_version(hba, &image->prog[type], 4286 ImageHdr.Id.Id, type, "DWC file"))) { 4287 return (rval); 4288 } 4289 } 4290 4291 /* 4292 * This checks if a DragonFly (pre-V2 ASIC) SLI2 4293 * image file is < version 3.8 4294 */ 4295 if (FC_JEDEC_ID(vpd->biuRev) == DRAGONFLY_JEDEC_ID) { 4296 ver = (image->prog[SLI2_OVERLAY].version & 4297 0x0000ff00) >> 8; 4298 4299 if (ver >= 0x38) { 4300 EMLXS_MSGF(EMLXS_CONTEXT, 4301 &emlxs_image_incompat_msg, 4302 "ASIC Check: Image requires DragonFly " 4303 "V2 ASIC"); 4304 4305 return (EMLXS_IMAGE_INCOMPATIBLE); 4306 } 4307 } 4308 4309 return (0); 4310 4311 } /* emlxs_validate_image() */ 4312 4313 4314 static uint32_t 4315 emlxs_update_exp_rom(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms) 4316 { 4317 emlxs_port_t *port = &PPORT; 4318 MAILBOXQ *mbox; 4319 MAILBOX *mb; 4320 uint32_t next_address; 4321 uint32_t rval = 0; 4322 4323 if (WakeUpParms->u1.EROM_prog_wd[0] == 0) { 4324 return (1); 4325 } 4326 4327 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 4328 KM_NOSLEEP)) == NULL) { 4329 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4330 "Unable to allocate mailbox buffer."); 4331 4332 return (1); 4333 } 4334 4335 bzero(mbox, sizeof (MAILBOXQ)); 4336 4337 mb = (MAILBOX *)mbox; 4338 mb->mbxCommand = MBX_LOAD_EXP_ROM; 4339 mb->un.varLdExpRom.step = EROM_CMD_FIND_IMAGE; 4340 mb->un.varLdExpRom.progress = 0; 4341 mb->un.varLdExpRom.un.prog_id = WakeUpParms->u1.EROM_prog_id; 4342 mbox->mbox_cmpl = NULL; 4343 4344 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 4345 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4346 "Unable to load exp ROM. Mailbox cmd=%x status=%x", 4347 mb->mbxCommand, mb->mbxStatus); 4348 4349 rval = 1; 4350 4351 goto SLI_DOWNLOAD_EXIT; 4352 } 4353 4354 if (mb->un.varLdExpRom.progress == EROM_RSP_COPY_DONE) { 4355 (void) emlxs_update_wakeup_parms(hba, WakeUpParms, WakeUpParms); 4356 4357 rval = 1; 4358 goto SLI_DOWNLOAD_EXIT; 4359 } 4360 4361 if (mb->un.varLdExpRom.progress != EROM_RSP_ERASE_STARTED) { 4362 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4363 "Invalid exp ROM progress. progress=%x", 4364 mb->un.varLdExpRom.progress); 4365 4366 rval = 1; 4367 4368 goto SLI_DOWNLOAD_EXIT; 4369 } 4370 4371 /* 4372 * continue Erase 4373 */ 4374 while (mb->un.varLdExpRom.progress != EROM_RSP_ERASE_COMPLETE) { 4375 4376 next_address = mb->un.varLdExpRom.dl_to_adr; 4377 4378 bzero((void *)mb, MAILBOX_CMD_BSIZE); 4379 4380 mb->mbxCommand = MBX_LOAD_EXP_ROM; 4381 mb->un.varLdExpRom.step = EROM_CMD_CONTINUE_ERASE; 4382 mb->un.varLdExpRom.dl_to_adr = next_address; 4383 mb->un.varLdExpRom.progress = 0; 4384 mb->un.varLdExpRom.un.prog_id = WakeUpParms->u1.EROM_prog_id; 4385 mbox->mbox_cmpl = NULL; 4386 4387 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 4388 MBX_SUCCESS) { 4389 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4390 "Unable to load exp ROM. Mailbox cmd=%x status=%x", 4391 mb->mbxCommand, mb->mbxStatus); 4392 4393 rval = 1; 4394 goto SLI_DOWNLOAD_EXIT; 4395 } 4396 4397 } 4398 4399 while (mb->un.varLdExpRom.progress != EROM_RSP_COPY_DONE) { 4400 next_address = mb->un.varLdExpRom.dl_to_adr; 4401 4402 bzero((void *)mb, MAILBOX_CMD_BSIZE); 4403 4404 mb->mbxCommand = MBX_LOAD_EXP_ROM; 4405 mb->un.varLdExpRom.step = EROM_CMD_COPY; 4406 mb->un.varLdExpRom.dl_to_adr = next_address; 4407 mb->un.varLdExpRom.progress = 0; 4408 mb->un.varLdExpRom.un.prog_id = WakeUpParms->u1.EROM_prog_id; 4409 mbox->mbox_cmpl = NULL; 4410 4411 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 4412 MBX_SUCCESS) { 4413 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4414 "Unable to load exp ROM. Mailbox cmd=%x status=%x", 4415 mb->mbxCommand, mb->mbxStatus); 4416 4417 rval = 1; 4418 4419 goto SLI_DOWNLOAD_EXIT; 4420 } 4421 } 4422 4423 rval = emlxs_update_wakeup_parms(hba, WakeUpParms, WakeUpParms); 4424 4425 SLI_DOWNLOAD_EXIT: 4426 4427 if (mbox) { 4428 kmem_free(mbox, sizeof (MAILBOXQ)); 4429 } 4430 4431 return (rval); 4432 4433 } /* emlxs_update_exp_rom() */ 4434 4435 4436 /* 4437 * 4438 * FUNCTION NAME: emlxs_start_abs_download_2mb 4439 * 4440 * DESCRIPTION: Perform absolute download for 2 MB flash. A incoming 4441 * buffer may consist of more than 1 file. This function 4442 * will parse the buffer to find all the files. 4443 * 4444 * 4445 * PARAMETERS: 4446 * 4447 * 4448 * RETURNS: 4449 * 4450 */ 4451 /* ARGSUSED */ 4452 static uint32_t 4453 emlxs_start_abs_download_2mb(emlxs_hba_t *hba, caddr_t buffer, uint32_t len, 4454 uint32_t offline, emlxs_fw_image_t *fw_image) 4455 { 4456 emlxs_port_t *port = &PPORT; 4457 uint32_t rval = 0; 4458 4459 /* If nothing to download then quit now */ 4460 if (!fw_image->awc.version && 4461 !fw_image->dwc.version && 4462 !fw_image->bwc.version) { 4463 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 4464 "Nothing new to update. Exiting."); 4465 return (0); 4466 } 4467 4468 /* 4469 * Everything checks out, now to just do it 4470 */ 4471 if (offline) { 4472 if (emlxs_offline(hba) != FC_SUCCESS) { 4473 return (EMLXS_OFFLINE_FAILED); 4474 } 4475 4476 if (EMLXS_SLI_HBA_RESET(hba, 1, 1, 0) != FC_SUCCESS) { 4477 return (EMLXS_OFFLINE_FAILED); 4478 } 4479 } 4480 4481 if (fw_image->awc.version) { 4482 rval = emlxs_proc_abs_2mb(hba, 4483 (buffer + fw_image->awc.offset), 4484 FILE_TYPE_AWC, 0); 4485 4486 if (rval) { 4487 goto SLI_DOWNLOAD_2MB_EXIT; 4488 } 4489 } 4490 4491 if (fw_image->bwc.version) { 4492 rval = emlxs_proc_abs_2mb(hba, 4493 (buffer + fw_image->bwc.offset), 4494 FILE_TYPE_BWC, 4495 (fw_image->dwc.version)? ALLext:BWCext); 4496 4497 if (rval) { 4498 goto SLI_DOWNLOAD_2MB_EXIT; 4499 } 4500 } 4501 4502 if (fw_image->dwc.version) { 4503 rval = emlxs_proc_rel_2mb(hba, buffer, fw_image); 4504 4505 if (rval) { 4506 goto SLI_DOWNLOAD_2MB_EXIT; 4507 } 4508 } 4509 4510 SLI_DOWNLOAD_2MB_EXIT: 4511 4512 if (offline) { 4513 (void) emlxs_online(hba); 4514 } 4515 4516 return (rval); 4517 4518 } /* emlxs_start_abs_download_2mb() */ 4519 4520 4521 /* 4522 * 4523 * FUNCTION NAME: emlxs_proc_abs_2mb 4524 * 4525 * DESCRIPTION: Given one of the 3 file types(awc/bwc/dwc), it will reset 4526 * the port and download the file with sliIssueMbCommand() 4527 * 4528 * 4529 * PARAMETERS: 4530 * 4531 * 4532 * RETURNS: 4533 * 4534 */ 4535 static uint32_t 4536 emlxs_proc_abs_2mb(emlxs_hba_t *hba, caddr_t EntireBuffer, 4537 uint32_t FileType, uint32_t extType) 4538 { 4539 emlxs_port_t *port = &PPORT; 4540 PAIF_HDR AifHdr; 4541 caddr_t Buffer = NULL; 4542 caddr_t DataBuffer = NULL; 4543 uint32_t *Src; 4544 uint32_t *Dst; 4545 MAILBOXQ *mbox; 4546 MAILBOX *mb; 4547 uint32_t DlByteCount; 4548 uint32_t rval = 0; 4549 uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT; 4550 uint32_t DlToAddr; 4551 uint32_t DlCount; 4552 WAKE_UP_PARMS AbsWakeUpParms; 4553 uint32_t i; 4554 uint32_t NextAddr; 4555 uint32_t EraseByteCount; 4556 uint32_t AreaId; 4557 uint32_t RspProgress = 0; 4558 uint32_t ParamsChg; 4559 4560 AifHdr = (PAIF_HDR)EntireBuffer; 4561 DlByteCount = AifHdr->RoSize + AifHdr->RwSize; 4562 DlToAddr = AifHdr->ImageBase; 4563 4564 if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT, 4565 KM_NOSLEEP)) == NULL) { 4566 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4567 "%x: Unable to allocate data buffer.", FileType); 4568 4569 return (EMLXS_IMAGE_FAILED); 4570 } 4571 4572 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 4573 KM_NOSLEEP)) == NULL) { 4574 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4575 "%x: Unable to allocate mailbox buffer.", FileType); 4576 4577 kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 4578 4579 return (EMLXS_IMAGE_FAILED); 4580 } 4581 4582 mb = (MAILBOX *)mbox; 4583 4584 Buffer = EntireBuffer + sizeof (AIF_HDR); 4585 4586 switch (FileType) { 4587 case FILE_TYPE_AWC: 4588 ParamsChg = 0; 4589 break; 4590 4591 case FILE_TYPE_BWC: 4592 rval = emlxs_build_parms_2mb_bwc(hba, 4593 AifHdr, extType, &AbsWakeUpParms); 4594 4595 if (rval == FALSE) { 4596 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4597 "BWC build parms failed."); 4598 4599 rval = EMLXS_IMAGE_FAILED; 4600 4601 goto EXIT_ABS_DOWNLOAD; 4602 } 4603 ParamsChg = 1; 4604 break; 4605 4606 default: 4607 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 4608 "Invalid file type: %x", FileType); 4609 4610 rval = EMLXS_IMAGE_BAD; 4611 4612 goto EXIT_ABS_DOWNLOAD; 4613 } 4614 4615 EraseByteCount = AifHdr->Area_Size; 4616 AreaId = AifHdr->Area_ID; 4617 4618 emlxs_format_load_area_cmd(mbox, 4619 DlToAddr, 4620 EraseByteCount, 4621 ERASE_FLASH, 4622 0, DL_FROM_SLIM_OFFSET, AreaId, MBX_LOAD_AREA, CMD_START_ERASE); 4623 4624 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 4625 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4626 "%x: Could not erase 2MB Flash: Mailbox cmd=%x status=%x", 4627 FileType, mb->mbxCommand, mb->mbxStatus); 4628 4629 rval = EMLXS_IMAGE_FAILED; 4630 4631 goto EXIT_ABS_DOWNLOAD; 4632 } 4633 4634 while (mb->un.varLdArea.progress != RSP_ERASE_COMPLETE) { 4635 NextAddr = mb->un.varLdArea.dl_to_adr; 4636 4637 emlxs_format_load_area_cmd(mbox, 4638 NextAddr, 4639 EraseByteCount, 4640 ERASE_FLASH, 4641 0, 4642 DL_FROM_SLIM_OFFSET, 4643 AreaId, MBX_LOAD_AREA, CMD_CONTINUE_ERASE); 4644 4645 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 4646 MBX_SUCCESS) { 4647 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4648 "%x: Could not erase 2MB Flash2: Mailbox cmd=%x " 4649 "status=%x", FileType, mb->mbxCommand, 4650 mb->mbxStatus); 4651 4652 rval = EMLXS_IMAGE_FAILED; 4653 4654 goto EXIT_ABS_DOWNLOAD; 4655 } 4656 } 4657 4658 while (DlByteCount) { 4659 if (DlByteCount >= SegSize) 4660 DlCount = SegSize; 4661 else 4662 DlCount = DlByteCount; 4663 4664 DlByteCount -= DlCount; 4665 4666 Dst = (uint32_t *)DataBuffer; 4667 Src = (uint32_t *)Buffer; 4668 4669 for (i = 0; i < (DlCount / 4); i++) { 4670 *Dst = *Src; 4671 Dst++; 4672 Src++; 4673 } 4674 4675 WRITE_SLIM_COPY(hba, (uint32_t *)DataBuffer, 4676 (volatile uint32_t *)((volatile char *) 4677 hba->sli.sli3.slim_addr + sizeof (MAILBOX)), 4678 (DlCount / sizeof (uint32_t))); 4679 4680 if ((RspProgress == RSP_DOWNLOAD_MORE) || (RspProgress == 0)) { 4681 emlxs_format_load_area_cmd(mbox, 4682 DlToAddr, 4683 DlCount, 4684 PROGRAM_FLASH, 4685 (DlByteCount) ? 0 : 1, 4686 DL_FROM_SLIM_OFFSET, 4687 AreaId, 4688 MBX_LOAD_AREA, 4689 (DlByteCount) ? CMD_DOWNLOAD : CMD_END_DOWNLOAD); 4690 4691 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 4692 MBX_SUCCESS) { 4693 EMLXS_MSGF(EMLXS_CONTEXT, 4694 &emlxs_download_failed_msg, 4695 "%x: Could not program 2MB Flash: Mailbox " 4696 "cmd=%x status=%x", FileType, 4697 mb->mbxCommand, mb->mbxStatus); 4698 4699 rval = EMLXS_IMAGE_FAILED; 4700 4701 goto EXIT_ABS_DOWNLOAD; 4702 } 4703 } 4704 4705 RspProgress = mb->un.varLdArea.progress; 4706 4707 Buffer += DlCount; 4708 DlToAddr += DlCount; 4709 } 4710 4711 #ifdef FMA_SUPPORT 4712 if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle) 4713 != DDI_FM_OK) { 4714 EMLXS_MSGF(EMLXS_CONTEXT, 4715 &emlxs_invalid_access_handle_msg, NULL); 4716 4717 rval = EMLXS_IMAGE_FAILED; 4718 4719 goto EXIT_ABS_DOWNLOAD; 4720 } 4721 #endif /* FMA_SUPPORT */ 4722 4723 if (RspProgress != RSP_DOWNLOAD_DONE) { 4724 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4725 "%x: Failed download response received. %x", FileType, 4726 RspProgress); 4727 4728 rval = EMLXS_IMAGE_FAILED; 4729 4730 goto EXIT_ABS_DOWNLOAD; 4731 } 4732 4733 if (ParamsChg) { 4734 if (emlxs_update_wakeup_parms(hba, &AbsWakeUpParms, 4735 &AbsWakeUpParms)) { 4736 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4737 "%x: Unable to update parms.", FileType); 4738 4739 rval = EMLXS_IMAGE_FAILED; 4740 } 4741 } 4742 4743 EXIT_ABS_DOWNLOAD: 4744 4745 if (DataBuffer) { 4746 kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 4747 } 4748 4749 if (mbox) { 4750 kmem_free(mbox, sizeof (MAILBOXQ)); 4751 } 4752 4753 return (rval); 4754 4755 } /* emlxs_proc_abs_2mb() */ 4756 4757 4758 static void 4759 emlxs_format_load_area_cmd(MAILBOXQ * mbq, 4760 uint32_t Base, 4761 uint32_t DlByteCount, 4762 uint32_t Function, 4763 uint32_t Complete, 4764 uint32_t DataOffset, uint32_t AreaId, uint8_t MbxCmd, uint32_t StepCmd) 4765 { 4766 MAILBOX *mb = (MAILBOX *)mbq; 4767 4768 bzero((void *)mb, MAILBOX_CMD_BSIZE); 4769 4770 mb->mbxCommand = MbxCmd; 4771 mb->mbxOwner = OWN_HOST; 4772 mb->un.varLdArea.update_flash = 1; 4773 mb->un.varLdArea.erase_or_prog = Function; 4774 mb->un.varLdArea.dl_to_adr = Base; 4775 mb->un.varLdArea.dl_len = DlByteCount; 4776 mb->un.varLdArea.load_cmplt = Complete; 4777 mb->un.varLdArea.method = DL_FROM_SLIM; 4778 mb->un.varLdArea.area_id = AreaId; 4779 mb->un.varLdArea.step = StepCmd; 4780 mb->un.varLdArea.un.dl_from_slim_offset = DataOffset; 4781 mbq->mbox_cmpl = NULL; 4782 4783 } /* emlxs_format_load_area_cmd() */ 4784 4785 4786 /* ARGSUSED */ 4787 static uint32_t 4788 emlxs_build_parms_2mb_bwc(emlxs_hba_t *hba, 4789 PAIF_HDR AifHdr, uint32_t extType, PWAKE_UP_PARMS AbsWakeUpParms) 4790 { 4791 emlxs_port_t *port = &PPORT; 4792 uint32_t pId[2]; 4793 uint32_t returnStat; 4794 4795 /* Read wakeup paramters */ 4796 if (emlxs_read_wakeup_parms(hba, AbsWakeUpParms, 0) == 4797 (uint32_t)CFG_DATA_NO_REGION) { 4798 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4799 "Unable to get BWC parameters."); 4800 return (FALSE); 4801 } 4802 4803 pId[0] = AifHdr->AVersion; 4804 pId[1] = 0; 4805 4806 if (extType == BWCext) { 4807 AbsWakeUpParms->u0.boot_bios_wd[0] = pId[0]; 4808 AbsWakeUpParms->u0.boot_bios_wd[1] = pId[1]; 4809 AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 4810 AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 4811 } 4812 4813 else if (extType == ALLext) { 4814 if (!AbsWakeUpParms->u0.boot_bios_wd[0]) { 4815 /* case of EROM inactive */ 4816 AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 4817 AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 4818 } else { 4819 /* case of EROM active */ 4820 if (AbsWakeUpParms->u0.boot_bios_wd[0] == pId[0]) { 4821 /* same ID */ 4822 AbsWakeUpParms->u0.boot_bios_wd[0] = pId[0]; 4823 AbsWakeUpParms->u0.boot_bios_wd[1] = pId[1]; 4824 AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 4825 AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 4826 } else { 4827 /* different ID */ 4828 AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 4829 AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 4830 4831 returnStat = 4832 emlxs_update_exp_rom(hba, AbsWakeUpParms); 4833 4834 if (returnStat) { 4835 AbsWakeUpParms->u0.boot_bios_wd[0] = 4836 pId[0]; 4837 AbsWakeUpParms->u0.boot_bios_wd[1] = 4838 pId[1]; 4839 } 4840 } 4841 } 4842 } 4843 4844 return (TRUE); 4845 4846 } /* emlxs_build_parms_2mb_bwc() */ 4847 4848 4849 extern uint32_t 4850 emlxs_get_max_sram(emlxs_hba_t *hba, uint32_t *MaxRbusSize, 4851 uint32_t *MaxIbusSize) 4852 { 4853 emlxs_port_t *port = &PPORT; 4854 MAILBOXQ *mbox; 4855 MAILBOX *mb; 4856 uint32_t *Uptr; 4857 uint32_t rval = 0; 4858 4859 if (MaxRbusSize) { 4860 *MaxRbusSize = 0; 4861 } 4862 4863 if (MaxIbusSize) { 4864 *MaxIbusSize = 0; 4865 } 4866 4867 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 4868 KM_NOSLEEP)) == NULL) { 4869 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4870 "Unable to allocate mailbox buffer."); 4871 4872 return (1); 4873 } 4874 4875 mb = (MAILBOX *)mbox; 4876 4877 emlxs_format_dump(hba, mbox, DMP_MEM_REG, 0, 2, MAX_RBUS_SRAM_SIZE_ADR); 4878 4879 if ((rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0)) != 4880 MBX_SUCCESS) { 4881 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4882 "Unable to get SRAM size: Mailbox cmd=%x status=%x", 4883 mb->mbxCommand, mb->mbxStatus); 4884 4885 rval = 1; 4886 4887 goto Exit_Function; 4888 } 4889 4890 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 4891 EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle, 0, 4892 hba->sli.sli4.dump_region.size, DDI_DMA_SYNC_FORKERNEL); 4893 Uptr = (uint32_t *)hba->sli.sli4.dump_region.virt; 4894 } else { 4895 Uptr = (uint32_t *)&mb->un.varDmp.resp_offset; 4896 } 4897 4898 if (MaxRbusSize) { 4899 *MaxRbusSize = Uptr[0]; 4900 } 4901 4902 if (MaxIbusSize) { 4903 *MaxIbusSize = Uptr[1]; 4904 } 4905 4906 Exit_Function: 4907 4908 if (mbox) { 4909 kmem_free(mbox, sizeof (MAILBOXQ)); 4910 } 4911 4912 #ifdef FMA_SUPPORT 4913 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 4914 if (emlxs_fm_check_dma_handle(hba, 4915 hba->sli.sli4.dump_region.dma_handle) != DDI_FM_OK) { 4916 EMLXS_MSGF(EMLXS_CONTEXT, 4917 &emlxs_invalid_dma_handle_msg, 4918 "emlxs_get_max_sram: hdl=%p", 4919 hba->sli.sli4.dump_region.dma_handle); 4920 rval = 1; 4921 } 4922 } 4923 #endif /* FMA_SUPPORT */ 4924 4925 return (rval); 4926 4927 } /* emlxs_get_max_sram() */ 4928 4929 4930 static uint32_t 4931 emlxs_kern_check(emlxs_hba_t *hba, uint32_t version) 4932 { 4933 uint8_t *ptr; 4934 uint8_t ver; 4935 4936 ver = version & 0xff; 4937 ptr = hba->model_info.pt_FF; 4938 4939 while (*ptr) { 4940 if (*ptr++ == ver) { 4941 return (1); 4942 } 4943 } 4944 4945 return (0); 4946 4947 } /* emlxs_kern_check() */ 4948 4949 static uint32_t 4950 emlxs_stub_check(emlxs_hba_t *hba, uint32_t version) 4951 { 4952 uint8_t *ptr; 4953 uint8_t ver; 4954 4955 ver = version & 0xff; 4956 ptr = hba->model_info.pt_2; 4957 4958 while (*ptr) { 4959 if (*ptr++ == ver) { 4960 return (1); 4961 } 4962 } 4963 4964 return (0); 4965 4966 } /* emlxs_stub_check() */ 4967 4968 static uint32_t 4969 emlxs_bios_check(emlxs_hba_t *hba, uint32_t version) 4970 { 4971 uint8_t *ptr; 4972 uint8_t ver; 4973 4974 ver = version & 0xff; 4975 ptr = hba->model_info.pt_3; 4976 4977 while (*ptr) { 4978 if (*ptr++ == ver) { 4979 return (1); 4980 } 4981 } 4982 4983 return (0); 4984 4985 } /* emlxs_bios_check() */ 4986 4987 static uint32_t 4988 emlxs_sli1_check(emlxs_hba_t *hba, uint32_t version) 4989 { 4990 uint8_t *ptr; 4991 uint8_t ver; 4992 4993 ver = version & 0xff; 4994 ptr = hba->model_info.pt_6; 4995 4996 while (*ptr) { 4997 if (*ptr++ == ver) { 4998 return (1); 4999 } 5000 } 5001 5002 return (0); 5003 5004 } /* emlxs_sli1_check() */ 5005 5006 static uint32_t 5007 emlxs_sli2_check(emlxs_hba_t *hba, uint32_t version) 5008 { 5009 uint8_t *ptr; 5010 uint8_t ver; 5011 5012 ver = version & 0xff; 5013 ptr = hba->model_info.pt_7; 5014 5015 while (*ptr) { 5016 if (*ptr++ == ver) { 5017 return (1); 5018 } 5019 } 5020 5021 return (0); 5022 5023 } /* emlxs_sli2_check() */ 5024 5025 static uint32_t 5026 emlxs_sli3_check(emlxs_hba_t *hba, uint32_t version) 5027 { 5028 uint8_t *ptr; 5029 uint8_t ver; 5030 5031 ver = version & 0xff; 5032 ptr = hba->model_info.pt_B; 5033 5034 while (*ptr) { 5035 if (*ptr++ == ver) { 5036 return (1); 5037 } 5038 } 5039 5040 return (0); 5041 5042 } /* emlxs_sli3_check() */ 5043 5044 5045 static uint32_t 5046 emlxs_sli4_check(emlxs_hba_t *hba, uint32_t version) 5047 { 5048 uint8_t *ptr; 5049 uint8_t ver; 5050 5051 ver = version & 0xff; 5052 ptr = hba->model_info.pt_E; 5053 5054 while (*ptr) { 5055 if (*ptr++ == ver) { 5056 return (1); 5057 } 5058 } 5059 5060 return (0); 5061 5062 } /* emlxs_sli4_check() */ 5063 5064 5065 static uint32_t 5066 emlxs_sbus_fcode_check(emlxs_hba_t *hba, uint32_t version) 5067 { 5068 uint8_t *ptr; 5069 uint8_t ver; 5070 5071 ver = version & 0xff; 5072 ptr = hba->model_info.pt_A; 5073 5074 while (*ptr) { 5075 if (*ptr++ == ver) { 5076 return (1); 5077 } 5078 } 5079 5080 return (0); 5081 5082 } /* emlxs_sbus_fcode_check() */ 5083 5084 5085 static uint32_t 5086 emlxs_type_check(uint32_t type) 5087 { 5088 if (type == 0xff) { 5089 return (KERNEL_CODE); 5090 } 5091 5092 if (type >= MAX_PROG_TYPES) { 5093 return (RESERVED_D); 5094 } 5095 5096 return (type); 5097 5098 } /* emlxs_type_check() */ 5099 5100 5101 extern int32_t 5102 emlxs_boot_code_disable(emlxs_hba_t *hba) 5103 { 5104 emlxs_port_t *port = &PPORT; 5105 PROG_ID Id; 5106 emlxs_vpd_t *vpd; 5107 5108 vpd = &VPD; 5109 5110 if ((hba->model_info.chip == EMLXS_BE2_CHIP) || 5111 (hba->model_info.chip == EMLXS_BE3_CHIP)) { 5112 return (EMLXS_OP_NOT_SUP); 5113 } 5114 5115 if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 0)) { 5116 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, 5117 "emlxs_boot_code_disable: Unable to read wake up parms."); 5118 5119 return (FC_FAILURE); 5120 } 5121 5122 /* Check if boot code is already disabled */ 5123 if (hba->wakeup_parms.u0.boot_bios_wd[0] == 0) { 5124 return (FC_SUCCESS); 5125 } 5126 5127 /* Make sure EROM entry has copy of boot bios entry */ 5128 if (!(hba->model_info.chip & 5129 (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP)) && 5130 (hba->wakeup_parms.u0.boot_bios_wd[0] != 5131 hba->wakeup_parms.u1.EROM_prog_wd[0]) && 5132 (hba->wakeup_parms.u0.boot_bios_wd[1] != 5133 hba->wakeup_parms.u1.EROM_prog_wd[1])) { 5134 (void) emlxs_update_boot_wakeup_parms(hba, &hba->wakeup_parms, 5135 &hba->wakeup_parms.u0.boot_bios_id, 1); 5136 } 5137 5138 /* Update the bios id with a zero id */ 5139 /* Don't load the EROM this time */ 5140 bzero(&Id, sizeof (PROG_ID)); 5141 (void) emlxs_update_boot_wakeup_parms(hba, &hba->wakeup_parms, &Id, 0); 5142 5143 /* Now read the parms again to verify */ 5144 (void) emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1); 5145 emlxs_decode_version(hba->wakeup_parms.u0.boot_bios_wd[0], 5146 vpd->boot_version); 5147 /* (void) strcpy(vpd->fcode_version, vpd->boot_version); */ 5148 5149 /* Return the result */ 5150 return ((hba->wakeup_parms.u0.boot_bios_wd[0] == 0) ? 5151 FC_SUCCESS : FC_FAILURE); 5152 5153 } /* emlxs_boot_code_disable() */ 5154 5155 5156 extern int32_t 5157 emlxs_boot_code_enable(emlxs_hba_t *hba) 5158 { 5159 emlxs_port_t *port = &PPORT; 5160 emlxs_vpd_t *vpd; 5161 PROG_ID load_list[MAX_LOAD_ENTRY]; 5162 uint32_t i; 5163 uint32_t count; 5164 5165 vpd = &VPD; 5166 5167 if ((hba->model_info.chip == EMLXS_BE2_CHIP) || 5168 (hba->model_info.chip == EMLXS_BE3_CHIP)) { 5169 return (FC_SUCCESS); 5170 } 5171 5172 /* Read the wakeup parms */ 5173 if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 0)) { 5174 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, 5175 "emlxs_boot_code_enable: Unable to read wake up parms."); 5176 5177 return (FC_FAILURE); 5178 } 5179 5180 /* Check if boot code is already enabled */ 5181 if (hba->wakeup_parms.u0.boot_bios_id.Type == BOOT_BIOS) { 5182 return (FC_SUCCESS); 5183 } 5184 5185 if (!(hba->model_info.chip & 5186 (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 5187 if (hba->wakeup_parms.u1.EROM_prog_id.Type != BOOT_BIOS) { 5188 return (EMLXS_NO_BOOT_CODE); 5189 } 5190 5191 /* Update the parms with the boot image id */ 5192 /* Don't load the EROM this time */ 5193 (void) emlxs_update_boot_wakeup_parms(hba, &hba->wakeup_parms, 5194 &hba->wakeup_parms.u1.EROM_prog_id, 0); 5195 } else { /* (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP) */ 5196 5197 count = emlxs_get_load_list(hba, load_list); 5198 5199 if (!count) { 5200 return (FC_FAILURE); 5201 } 5202 5203 /* Scan load list for a boot image */ 5204 for (i = 0; i < count; i++) { 5205 if (load_list[i].Type == BOOT_BIOS) { 5206 /* Update the parms with the boot image id */ 5207 /* Don't load the EROM this time */ 5208 (void) emlxs_update_boot_wakeup_parms(hba, 5209 &hba->wakeup_parms, &load_list[i], 0); 5210 5211 break; 5212 } 5213 } 5214 5215 if (i == count) { 5216 return (EMLXS_NO_BOOT_CODE); 5217 } 5218 } 5219 5220 /* Now read the parms again to verify */ 5221 (void) emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1); 5222 emlxs_decode_version(hba->wakeup_parms.u0.boot_bios_wd[0], 5223 vpd->boot_version); 5224 /* (void) strcpy(vpd->fcode_version, vpd->boot_version); */ 5225 5226 /* return the result */ 5227 return ((hba->wakeup_parms.u0.boot_bios_wd[0] != 0) ? 5228 FC_SUCCESS : FC_FAILURE); 5229 5230 } /* emlxs_boot_code_enable() */ 5231 5232 5233 5234 extern int32_t 5235 emlxs_boot_code_state(emlxs_hba_t *hba) 5236 { 5237 emlxs_port_t *port = &PPORT; 5238 5239 if ((hba->model_info.chip == EMLXS_BE2_CHIP) || 5240 (hba->model_info.chip == EMLXS_BE3_CHIP)) { 5241 return (FC_SUCCESS); 5242 } 5243 5244 /* Read the wakeup parms */ 5245 if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1)) { 5246 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, 5247 "emlxs_boot_code_state: Unable to read wake up parms."); 5248 5249 return (FC_FAILURE); 5250 } 5251 5252 /* return the result */ 5253 return ((hba->wakeup_parms.u0.boot_bios_wd[0] != 0) ? 5254 FC_SUCCESS : FC_FAILURE); 5255 5256 } /* emlxs_boot_code_state() */ 5257