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