1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Emulex. All rights reserved. 24 * Use is subject to License terms. 25 */ 26 27 #include <emlxs.h> 28 29 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 30 EMLXS_MSG_DEF(EMLXS_DOWNLOAD_C); 31 32 #define MAX_BOOTID 10 33 34 #define DATA32_SWAP(x) ((((x) & 0xFF)<<24) | (((x) & 0xFF00)<<8) | \ 35 (((x) & 0xFF0000)>>8) | \ 36 (((x) & 0xFF000000)>>24)) 37 38 static uint32_t emlxs_erase_fcode_flash(emlxs_hba_t *hba); 39 static uint32_t emlxs_write_fcode_flash(emlxs_hba_t *hba, 40 PIMAGE_HDR ImageHdr, caddr_t Buffer); 41 42 static int32_t emlxs_build_parms(caddr_t Buffer, PWAKE_UP_PARMS AbsWakeUpParms, 43 uint32_t BufferSize, PAIF_HDR AifHeader, 44 int32_t DwcFile); 45 46 static uint32_t emlxs_validate_image(emlxs_hba_t *hba, caddr_t Buffer, 47 uint32_t Size, emlxs_fw_image_t *fw_image); 48 49 static void emlxs_format_dump(MAILBOX *mb, uint32_t Type, uint32_t RegionId, 50 uint32_t WordCount, uint32_t BaseAddr); 51 52 static uint32_t emlxs_start_abs_download(emlxs_hba_t *hba, PAIF_HDR AifHdr, 53 caddr_t Buffer, PWAKE_UP_PARMS WakeUpParms, 54 uint32_t MaxRbusSramSize, uint32_t MaxIbusSramSize, 55 PWAKE_UP_PARMS AbsWakeUpParms, int32_t DwcFile); 56 57 static uint32_t emlxs_start_abs_download_2mb(emlxs_hba_t *hba, caddr_t buffer, 58 uint32_t len, uint32_t offline, 59 emlxs_fw_image_t *fw_image); 60 61 static uint32_t emlxs_proc_abs_2mb(emlxs_hba_t *hba, PAIF_HDR AifHdr, 62 caddr_t EntireBuffer, uint32_t FileType, 63 uint32_t BWCflag, uint32_t extType); 64 65 static void emlxs_format_load_area_cmd(MAILBOX *mb, uint32_t Base, 66 uint32_t DlByteCount, uint32_t Function, 67 uint32_t Complete, uint32_t DataOffset, uint32_t AreaId, 68 uint8_t MbxCmd, uint32_t StepCmd); 69 70 static uint32_t emlxs_build_parms_2mb_bwc(emlxs_hba_t *hba, PAIF_HDR AifHdr, 71 uint32_t extType, PWAKE_UP_PARMS AbsWakeUpParms); 72 73 static uint32_t emlxs_build_parms_2mb_dwc(emlxs_hba_t *hba, caddr_t Buffer, 74 uint32_t BufferSize, PAIF_HDR AifHeader, 75 PWAKE_UP_PARMS AbsWakeUpParms, uint32_t BWCflag, 76 uint32_t extType, uint32_t *numBootImage); 77 78 static uint32_t emlxs_update_exp_rom(emlxs_hba_t *hba, 79 PWAKE_UP_PARMS WakeUpParms); 80 81 extern uint32_t emlxs_get_max_sram(emlxs_hba_t *hba, uint32_t *MaxRbusSize, 82 uint32_t *MaxIbusSize); 83 84 static void emlxs_format_prog_flash(MAILBOX *mb, uint32_t Base, 85 uint32_t DlByteCount, uint32_t Function, 86 uint32_t Complete, uint32_t BdeAddress, 87 uint32_t BdeSize, PROG_ID *ProgId); 88 89 static void emlxs_format_update_parms(MAILBOX *mb, 90 PWAKE_UP_PARMS WakeUpParms); 91 92 static void emlxs_format_update_pci_cfg(emlxs_hba_t *hba, MAILBOX *mb, 93 uint32_t region_id, uint32_t size); 94 95 static uint32_t emlxs_update_wakeup_parms(emlxs_hba_t *hba, 96 PWAKE_UP_PARMS AbsWakeUpParms, 97 PWAKE_UP_PARMS WakeUpParms); 98 99 static uint32_t emlxs_update_boot_wakeup_parms(emlxs_hba_t *hba, 100 PWAKE_UP_PARMS WakeUpParms, PROG_ID *id, 101 uint32_t proc_erom); 102 103 static uint32_t emlxs_update_ff_wakeup_parms(emlxs_hba_t *hba, 104 PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 105 106 static uint32_t emlxs_update_sli1_wakeup_parms(emlxs_hba_t *hba, 107 PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 108 109 static uint32_t emlxs_update_sli2_wakeup_parms(emlxs_hba_t *hba, 110 PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 111 112 static uint32_t emlxs_update_sli3_wakeup_parms(emlxs_hba_t *hba, 113 PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 114 115 static uint32_t emlxs_update_sli4_wakeup_parms(emlxs_hba_t *hba, 116 PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 117 118 119 static uint32_t emlxs_start_rel_download(emlxs_hba_t *hba, PIMAGE_HDR ImageHdr, 120 caddr_t Buffer, PWAKE_UP_PARMS WakeUpParms, 121 uint32_t MaxRbusSramSize, uint32_t MaxIbusSramSize); 122 123 static uint32_t emlxs_read_load_list(emlxs_hba_t *hba, LOAD_LIST *LoadList); 124 125 static uint32_t emlxs_valid_cksum(uint32_t *StartAddr, uint32_t *EndAddr); 126 static void emlxs_disp_aif_header(emlxs_hba_t *hba, PAIF_HDR AifHdr); 127 static void emlxs_dump_image_header(emlxs_hba_t *hba, PIMAGE_HDR image); 128 static uint32_t emlxs_get_abs_image_type(caddr_t Buffer, uint32_t BufferSize); 129 130 static uint32_t emlxs_get_dwc_image_type(emlxs_hba_t *hba, caddr_t Buffer, 131 uint32_t BufferSize, PAIF_HDR AifHeader); 132 133 static uint32_t emlxs_type_check(uint32_t type); 134 static uint32_t emlxs_kern_check(emlxs_hba_t *hba, uint32_t version); 135 static uint32_t emlxs_stub_check(emlxs_hba_t *hba, uint32_t version); 136 static uint32_t emlxs_sli1_check(emlxs_hba_t *hba, uint32_t version); 137 static uint32_t emlxs_sli2_check(emlxs_hba_t *hba, uint32_t version); 138 static uint32_t emlxs_sli3_check(emlxs_hba_t *hba, uint32_t version); 139 static uint32_t emlxs_sli4_check(emlxs_hba_t *hba, uint32_t version); 140 static uint32_t emlxs_bios_check(emlxs_hba_t *hba, uint32_t version); 141 static uint32_t emlxs_sbus_fcode_check(emlxs_hba_t *hba, uint32_t version); 142 static uint32_t emlxs_validate_version(emlxs_hba_t *hba, 143 emlxs_fw_file_t *file, uint32_t id, uint32_t type, 144 char *file_type); 145 146 /* ************************************************************************* */ 147 148 149 extern int32_t 150 emlxs_fw_download(emlxs_hba_t *hba, caddr_t buffer, uint32_t len, 151 uint32_t offline) 152 { 153 emlxs_port_t *port = &PPORT; 154 uint32_t *Uptr; 155 IMAGE_HDR ImageHdr; 156 AIF_HDR AifHdr; 157 uint32_t ImageType; 158 WAKE_UP_PARMS WakeUpParms; 159 WAKE_UP_PARMS AbsWakeUpParms; 160 uint32_t MaxRbusSramSize; 161 uint32_t MaxIbusSramSize; 162 int32_t AbsChangeParams = 0; 163 int32_t DwcFile = FALSE; 164 uint32_t rval = 0; 165 emlxs_fw_image_t fw_image; 166 uint32_t i; 167 168 #ifdef EMLXS_I386 169 caddr_t local_buffer; 170 uint32_t *bptr1; 171 uint32_t *bptr2; 172 #endif /* EMLXS_I386 */ 173 174 if (buffer == NULL || len == 0) { 175 return (EMLXS_IMAGE_BAD); 176 } 177 #ifdef EMLXS_I386 178 /* We need to swap the image buffer before we start */ 179 180 /* 181 * Use KM_SLEEP to allocate a temporary buffer 182 */ 183 local_buffer = (caddr_t)kmem_zalloc(len, KM_SLEEP); 184 185 if (local_buffer == NULL) { 186 return (FC_NOMEM); 187 } 188 189 /* Perform a 32 bit swap of the image */ 190 bptr1 = (uint32_t *)local_buffer; 191 bptr2 = (uint32_t *)buffer; 192 for (i = 0; i < (len / 4); i++) { 193 *bptr1 = SWAP_DATA32(*bptr2); 194 bptr1++; 195 bptr2++; 196 } 197 198 /* Replace the original buffer */ 199 buffer = local_buffer; 200 #endif /* EMLXS_I386 */ 201 202 203 bzero(&fw_image, sizeof (emlxs_fw_image_t)); 204 for (i = 0; i < MAX_PROG_TYPES; i++) { 205 (void) strcpy(fw_image.prog[i].label, "none"); 206 } 207 208 /* Validate image */ 209 if ((rval = emlxs_validate_image(hba, buffer, len, &fw_image))) { 210 goto done; 211 } 212 213 /* Get image type */ 214 Uptr = (uint32_t *)buffer; 215 ImageType = *Uptr; 216 217 /* 218 * Pegasus and beyond FW download is done differently 219 * for absolute download. 220 */ 221 222 /* Check for absolute image */ 223 if ((ImageType == NOP_IMAGE_TYPE) && 224 !(hba->model_info.chip & 225 (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 226 /* 227 * Because 2Mb flash download file format is different from 228 * 512k, it needs to be handled differently 229 */ 230 if (rval = emlxs_start_abs_download_2mb(hba, buffer, len, 231 offline, &fw_image)) { 232 goto done; 233 } 234 235 /* Offline already handled */ 236 offline = 0; 237 238 goto SLI_DOWNLOAD_EXIT; 239 } 240 241 /* Pre-pegasus adapters only */ 242 243 /* Check for absolute image */ 244 else if (ImageType == NOP_IMAGE_TYPE) { 245 bcopy(buffer, &AifHdr, sizeof (AIF_HDR)); 246 bzero((void *)&ImageHdr, sizeof (IMAGE_HDR)); 247 248 if (AifHdr.ImageBase && (AifHdr.ImageBase == 0x20000)) { 249 DwcFile = TRUE; 250 } 251 252 AbsChangeParams = emlxs_build_parms(buffer, 253 &AbsWakeUpParms, len, &AifHdr, DwcFile); 254 } else { /* (ImageType != NOP_IMAGE_TYPE) Relative image */ 255 256 bzero((void *)&AifHdr, sizeof (AIF_HDR)); 257 bcopy(buffer, &ImageHdr, sizeof (IMAGE_HDR)); 258 } 259 260 /* 261 * Everything checks out, now to just do it 262 */ 263 264 if (offline) { 265 if (emlxs_offline(hba) != FC_SUCCESS) { 266 offline = 0; 267 268 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 269 "Unable to take adapter offline."); 270 271 rval = EMLXS_OFFLINE_FAILED; 272 273 goto SLI_DOWNLOAD_EXIT; 274 } 275 276 if (emlxs_sli_hba_reset(hba, 1, 1) != FC_SUCCESS) { 277 offline = 0; 278 279 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 280 "Unable to restart adapter."); 281 282 rval = EMLXS_OFFLINE_FAILED; 283 284 goto SLI_DOWNLOAD_EXIT; 285 } 286 } 287 288 if (ImageHdr.Id.Type == SBUS_FCODE) { 289 /* Erase Flash */ 290 if (emlxs_erase_fcode_flash(hba)) { 291 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 292 "Unable to erase flash."); 293 294 rval = EMLXS_IMAGE_FAILED; 295 296 goto SLI_DOWNLOAD_EXIT; 297 } 298 299 /* Write FCODE */ 300 if (emlxs_write_fcode_flash(hba, &ImageHdr, buffer)) { 301 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 302 "Unable to write flash."); 303 304 rval = EMLXS_IMAGE_FAILED; 305 306 goto SLI_DOWNLOAD_EXIT; 307 } 308 309 } else { /* !SBUS_FCODE */ 310 311 312 if (emlxs_read_wakeup_parms(hba, &WakeUpParms, 1)) { 313 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 314 "Unable to get parameters."); 315 316 rval = EMLXS_IMAGE_FAILED; 317 318 goto SLI_DOWNLOAD_EXIT; 319 } 320 321 if (emlxs_get_max_sram(hba, &MaxRbusSramSize, 322 &MaxIbusSramSize)) { 323 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 324 "Unable to get RAM size."); 325 326 rval = EMLXS_IMAGE_FAILED; 327 328 goto SLI_DOWNLOAD_EXIT; 329 } 330 331 if (ImageType == NOP_IMAGE_TYPE) { 332 if (emlxs_start_abs_download(hba, &AifHdr, buffer, 333 &WakeUpParms, MaxRbusSramSize, MaxIbusSramSize, 334 (AbsChangeParams) ? &AbsWakeUpParms : NULL, 335 DwcFile)) { 336 EMLXS_MSGF(EMLXS_CONTEXT, 337 &emlxs_download_failed_msg, 338 "Failed to program flash."); 339 340 rval = EMLXS_IMAGE_FAILED; 341 342 goto SLI_DOWNLOAD_EXIT; 343 } 344 345 } else { 346 347 if (emlxs_start_rel_download(hba, &ImageHdr, buffer, 348 &WakeUpParms, MaxRbusSramSize, MaxIbusSramSize)) { 349 EMLXS_MSGF(EMLXS_CONTEXT, 350 &emlxs_download_failed_msg, 351 "Failed to program flash."); 352 353 rval = EMLXS_IMAGE_FAILED; 354 355 goto SLI_DOWNLOAD_EXIT; 356 } 357 } 358 359 } /* !SBUS_FCODE */ 360 361 362 SLI_DOWNLOAD_EXIT: 363 364 if (offline) { 365 (void) emlxs_online(hba); 366 } 367 368 if (rval == 0) { 369 370 371 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_complete_msg, 372 "Status good."); 373 } 374 375 done: 376 377 #ifdef EMLXS_I386 378 /* Free the local buffer */ 379 kmem_free(local_buffer, len); 380 #endif /* EMLXS_I386 */ 381 382 return (rval); 383 384 } /* emlxs_fw_download */ 385 386 387 388 extern int32_t 389 emlxs_cfl_download(emlxs_hba_t *hba, uint32_t region, caddr_t buffer, 390 uint32_t len) 391 { 392 emlxs_port_t *port = &PPORT; 393 MAILBOXQ *mbox = NULL; 394 MAILBOX *mb; 395 uint32_t rval = 0; 396 uint32_t region_id; 397 uint32_t id; 398 399 #ifndef EMLXS_I386 400 caddr_t local_buffer; 401 uint32_t *bptr1; 402 uint32_t *bptr2; 403 uint32_t i; 404 #endif /* !EMLXS_I386 */ 405 406 if (buffer == NULL || len == 0) { 407 return (EMLXS_IMAGE_BAD); 408 } 409 #ifndef EMLXS_I386 410 /* We need to swap the image buffer before we start */ 411 412 /* 413 * Use KM_SLEEP to allocate a temporary buffer 414 */ 415 local_buffer = (caddr_t)kmem_zalloc(len, KM_SLEEP); 416 417 if (local_buffer == NULL) { 418 return (FC_NOMEM); 419 } 420 421 /* Perform a 32 bit swap of the image */ 422 bptr1 = (uint32_t *)local_buffer; 423 bptr2 = (uint32_t *)buffer; 424 425 for (i = 0; i < (len / 4); i++) { 426 *bptr1 = DATA32_SWAP(*bptr2); 427 bptr1++; 428 bptr2++; 429 } 430 431 /* Replace the original buffer */ 432 buffer = local_buffer; 433 434 #endif /* !EMLXS_I386 */ 435 436 if (len > 128) { 437 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 438 "Invalid image length: 0x%x > 128", len); 439 440 return (EMLXS_IMAGE_BAD); 441 } 442 443 /* Check the region number */ 444 if ((region > 2) && (region != 0xff)) { 445 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 446 "Invalid region id: 0x%x", region); 447 448 return (EMLXS_IMAGE_BAD); 449 450 } 451 452 /* Check the image vendor id */ 453 id = *(int32_t *)buffer; 454 if ((id & 0xffff) != 0x10df) { 455 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 456 "Invalid image id: 0x%x", id); 457 458 return (EMLXS_IMAGE_BAD); 459 } 460 461 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 462 KM_NOSLEEP)) == NULL) { 463 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 464 "Unable to allocate mailbox buffer."); 465 466 rval = 1; 467 468 goto done; 469 } 470 471 mb = (MAILBOX *)mbox; 472 473 /* 474 * Everything checks out, now to just do it 475 */ 476 if (emlxs_offline(hba) != FC_SUCCESS) { 477 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 478 "Unable to take HBA offline."); 479 480 rval = EMLXS_OFFLINE_FAILED; 481 482 goto done; 483 } 484 485 if (emlxs_sli_hba_reset(hba, 1, 1) != FC_SUCCESS) { 486 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 487 "Unable to restart adapter."); 488 489 rval = EMLXS_OFFLINE_FAILED; 490 491 goto done; 492 } 493 494 /* Check if default region is requested */ 495 if (region == 0xff) { 496 /* 497 * Sun-branded Helios and Zypher have different 498 * default PCI region 499 */ 500 if ((hba->model_info.flags & EMLXS_SUN_BRANDED) && 501 (hba->model_info.chip & 502 (EMLXS_HELIOS_CHIP | EMLXS_ZEPHYR_CHIP))) { 503 region = 2; 504 } else { 505 region = 0; 506 } 507 } 508 509 /* Set region id based on PCI region requested */ 510 region_id = DEF_PCI_CFG_REGION_ID + region; 511 512 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 513 "PCI configuration: PCI%d region=%d id=0x%x size=%d", region, 514 region_id, id, len); 515 516 /* Copy the data buffer to SLIM */ 517 WRITE_SLIM_COPY(hba, (uint32_t *)buffer, 518 (volatile uint32_t *)((volatile char *)hba->slim_addr + 519 sizeof (MAILBOX)), (len / sizeof (uint32_t))); 520 521 #ifdef FMA_SUPPORT 522 if (emlxs_fm_check_acc_handle(hba, hba->slim_acc_handle) 523 != DDI_FM_OK) { 524 EMLXS_MSGF(EMLXS_CONTEXT, 525 &emlxs_invalid_access_handle_msg, NULL); 526 rval = 1; 527 } 528 #endif /* FMA_SUPPORT */ 529 530 emlxs_format_update_pci_cfg(hba, mb, region_id, len); 531 532 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 533 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 534 "Unable to update PCI configuration: Mailbox cmd=%x " 535 "status=%x info=%d", mb->mbxCommand, mb->mbxStatus, 536 mb->un.varUpdateCfg.rsp_info); 537 538 rval = 1; 539 } 540 541 (void) emlxs_online(hba); 542 543 if (rval == 0) { 544 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_complete_msg, 545 "Status good."); 546 } 547 548 done: 549 550 if (mbox) { 551 kmem_free(mbox, sizeof (MAILBOXQ)); 552 } 553 #ifndef EMLXS_I386 554 /* Free the local buffer */ 555 kmem_free(local_buffer, len); 556 #endif /* !EMLXS_I386 */ 557 558 return (rval); 559 560 } /* emlxs_cfl_download */ 561 562 563 564 static uint32_t 565 emlxs_valid_cksum(uint32_t *StartAddr, uint32_t *EndAddr) 566 { 567 uint32_t Temp; 568 uint32_t CkSum; 569 570 EndAddr++; 571 CkSum = SLI_CKSUM_SEED; 572 573 CkSum = (CkSum >> 1) | (CkSum << 31); 574 while (StartAddr != EndAddr) { 575 CkSum = (CkSum << 1) | (CkSum >> 31); 576 Temp = *StartAddr; 577 578 CkSum ^= Temp; 579 StartAddr++; 580 } 581 582 return (CkSum << 1) | (CkSum >> 31); 583 584 } /* emlxs_valid_cksum() */ 585 586 587 static void 588 emlxs_disp_aif_header(emlxs_hba_t *hba, PAIF_HDR AifHdr) 589 { 590 emlxs_port_t *port = &PPORT; 591 592 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "AIF Header: "); 593 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 594 "AIF Header: compress_br = 0x%x", AifHdr->CompressBr); 595 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 596 "AIF Header: reloc_br = 0x%x", AifHdr->RelocBr); 597 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 598 "AIF Header: zinit_br = 0x%x", AifHdr->ZinitBr); 599 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 600 "AIF Header: entry_br = 0x%x", AifHdr->EntryBr); 601 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 602 "AIF Header: area_id = 0x%x", AifHdr->Area_ID); 603 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 604 "AIF Header: rosize = 0x%x", AifHdr->RoSize); 605 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 606 "AIF Header: dbgsize = 0x%x", AifHdr->DbgSize); 607 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 608 "AIF Header: zinitsize = 0x%x", AifHdr->ZinitSize); 609 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 610 "AIF Header: dbgtype = 0x%x", AifHdr->DbgType); 611 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 612 "AIF Header: imagebase = 0x%x", AifHdr->ImageBase); 613 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 614 "AIF Header: area_size = 0x%x", AifHdr->Area_Size); 615 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 616 "AIF Header: address_mode = 0x%x", AifHdr->AddressMode); 617 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 618 "AIF Header: database = 0x%x", AifHdr->DataBase); 619 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 620 "AIF Header: aversion = 0x%x", AifHdr->AVersion); 621 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 622 "AIF Header: spare2 = 0x%x", AifHdr->Spare2); 623 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 624 "AIF Header: debug_swi = 0x%x", AifHdr->DebugSwi); 625 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 626 "AIF Header: zinitcode[0] = 0x%x", AifHdr->ZinitCode[0]); 627 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 628 "AIF Header: zinitcode[1] = 0x%x", AifHdr->ZinitCode[1]); 629 630 } /* emlxs_disp_aif_header() */ 631 632 633 634 static void 635 emlxs_dump_image_header(emlxs_hba_t *hba, PIMAGE_HDR image) 636 { 637 emlxs_port_t *port = &PPORT; 638 639 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "Img Header: "); 640 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 641 "Img Header: BlockSize = 0x%x", image->BlockSize); 642 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 643 "Img Header: PROG_ID Type = 0x%x", image->Id.Type); 644 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 645 "Img Header: PROG_ID Id = 0x%x", image->Id.Id); 646 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 647 "Img Header: PROG_ID Ver = 0x%x", image->Id.Ver); 648 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 649 "Img Header: PROG_ID Rev = 0x%x", image->Id.Rev); 650 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 651 "Img Header: PROG_ID revcomp = 0x%x", image->Id.un.revcomp); 652 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 653 "Img Header: Flags = 0x%x", image->Flags); 654 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 655 "Img Header: EntryAdr = 0x%x", image->EntryAdr); 656 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 657 "Img Header: InitAdr = 0x%x", image->InitAdr); 658 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 659 "Img Header: ExitAdr = 0x%x", image->ExitAdr); 660 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 661 "Img Header: ImageBase = 0x%x", image->ImageBase); 662 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 663 "Img Header: ImageSize = 0x%x", image->ImageSize); 664 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 665 "Img Header: ZinitSize = 0x%x", image->ZinitSize); 666 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 667 "Img Header: RelocSize = 0x%x", image->RelocSize); 668 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 669 "Img Header: HdrCks = 0x%x", image->HdrCks); 670 671 } /* emlxs_dump_image_header() */ 672 673 674 static void 675 emlxs_format_dump(MAILBOX *mb, uint32_t Type, uint32_t RegionId, 676 uint32_t WordCount, uint32_t BaseAddr) 677 { 678 bzero((void *)mb, MAILBOX_CMD_BSIZE); 679 680 mb->mbxCommand = MBX_DUMP_MEMORY; 681 mb->un.varDmp.type = Type; 682 mb->un.varDmp.region_id = RegionId; 683 mb->un.varDmp.word_cnt = WordCount; 684 mb->un.varDmp.base_adr = BaseAddr; 685 mb->mbxOwner = OWN_HOST; 686 687 return; 688 689 } /* emlxs_format_dump() */ 690 691 692 /* ARGSUSED */ 693 static uint32_t 694 emlxs_start_abs_download(emlxs_hba_t *hba, 695 PAIF_HDR AifHdr, 696 caddr_t Buffer, 697 PWAKE_UP_PARMS WakeUpParms, 698 uint32_t MaxRbusSramSize, 699 uint32_t MaxIbusSramSize, PWAKE_UP_PARMS AbsWakeUpParms, int32_t DwcFile) 700 { 701 emlxs_port_t *port = &PPORT; 702 uint32_t DlByteCount = AifHdr->RoSize + AifHdr->RwSize; 703 IMAGE_HDR ImageHdr; 704 uint32_t *Src; 705 uint32_t *Dst; 706 caddr_t DataBuffer = NULL; 707 MAILBOXQ *mbox; 708 MAILBOX *mb; 709 uint32_t rval = 1; 710 uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT; 711 uint32_t DlToAddr = AifHdr->ImageBase; 712 uint32_t DlCount; 713 uint32_t i; 714 715 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 716 "Performing absolute download..."); 717 718 if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT, 719 KM_NOSLEEP)) == NULL) { 720 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 721 "Unable to allocate data buffer."); 722 723 return (rval); 724 } 725 726 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 727 KM_NOSLEEP)) == NULL) { 728 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 729 "Unable to allocate mailbox buffer."); 730 731 kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 732 733 return (rval); 734 } 735 736 mb = (MAILBOX *)mbox; 737 738 Buffer += sizeof (AIF_HDR); 739 740 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, "Erasing flash..."); 741 742 if (DwcFile) { 743 emlxs_format_prog_flash(mb, 0x20000, 0x50000, ERASE_FLASH, 0, 744 0, 0, NULL); 745 } else { 746 emlxs_format_prog_flash(mb, DlToAddr, DlByteCount, 747 ERASE_FLASH, 0, 0, 0, NULL); 748 } 749 750 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 751 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 752 "Unable to erase Flash: Mailbox cmd=%x status=%x", 753 mb->mbxCommand, mb->mbxStatus); 754 755 rval = 1; 756 757 goto EXIT_ABS_DOWNLOAD; 758 } 759 760 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 761 "Programming flash..."); 762 763 while (DlByteCount) { 764 765 if (DlByteCount > SegSize) { 766 DlCount = SegSize; 767 } else { 768 DlCount = DlByteCount; 769 } 770 DlByteCount -= DlCount; 771 772 Dst = (uint32_t *)DataBuffer; 773 Src = (uint32_t *)Buffer; 774 775 for (i = 0; i < (DlCount / 4); i++) { 776 *Dst = *Src; 777 Dst++; 778 Src++; 779 } 780 781 WRITE_SLIM_COPY(hba, (uint32_t *)DataBuffer, 782 (volatile uint32_t *)((volatile char *)hba->slim_addr + 783 sizeof (MAILBOX)), (DlCount / sizeof (uint32_t))); 784 785 emlxs_format_prog_flash(mb, DlToAddr, DlCount, 786 PROGRAM_FLASH, (DlByteCount) ? 0 : 1, 0, DlCount, NULL); 787 788 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 789 MBX_SUCCESS) { 790 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 791 "Unable to program Flash: Mailbox cmd=%x status=%x", 792 mb->mbxCommand, mb->mbxStatus); 793 794 rval = 1; 795 796 goto EXIT_ABS_DOWNLOAD; 797 } 798 799 Buffer += DlCount; 800 DlToAddr += DlCount; 801 } 802 803 #ifdef FMA_SUPPORT 804 if (emlxs_fm_check_acc_handle(hba, hba->slim_acc_handle) 805 != DDI_FM_OK) { 806 EMLXS_MSGF(EMLXS_CONTEXT, 807 &emlxs_invalid_access_handle_msg, NULL); 808 809 rval = 1; 810 811 goto EXIT_ABS_DOWNLOAD; 812 } 813 #endif /* FMA_SUPPORT */ 814 815 bzero((caddr_t)&ImageHdr, sizeof (IMAGE_HDR)); 816 ImageHdr.Id.Type = FUNC_FIRMWARE; 817 818 switch (MaxRbusSramSize) { 819 case REDUCED_RBUS_SRAM_CFG: 820 ImageHdr.Id.Id = REDUCED_SRAM_CFG_PROG_ID; 821 break; 822 case FULL_RBUS_SRAM_CFG: 823 ImageHdr.Id.Id = FULL_SRAM_CFG_PROG_ID; 824 break; 825 default: 826 ImageHdr.Id.Id = OTHER_SRAM_CFG_PROG_ID; 827 break; 828 } 829 830 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, "Updating params..."); 831 832 if (AbsWakeUpParms) { 833 rval = 834 emlxs_update_wakeup_parms(hba, AbsWakeUpParms, 835 WakeUpParms); 836 } else { 837 rval = 838 emlxs_update_boot_wakeup_parms(hba, WakeUpParms, 839 &ImageHdr.Id, 1); 840 } 841 842 EXIT_ABS_DOWNLOAD: 843 if (DataBuffer) { 844 kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 845 } 846 847 if (mbox) { 848 kmem_free(mbox, sizeof (MAILBOXQ)); 849 } 850 851 return (rval); 852 853 } /* emlxs_start_abs_download() */ 854 855 856 /* ARGSUSED */ 857 static void 858 emlxs_format_prog_flash(MAILBOX *mb, 859 uint32_t Base, 860 uint32_t DlByteCount, 861 uint32_t Function, 862 uint32_t Complete, 863 uint32_t BdeAddress, uint32_t BdeSize, PROG_ID *ProgId) 864 { 865 bzero((void *)mb, MAILBOX_CMD_BSIZE); 866 867 if (ProgId) 868 mb->mbxCommand = MBX_DOWN_LOAD; 869 else 870 mb->mbxCommand = MBX_LOAD_SM; 871 872 mb->un.varLdSM.load_cmplt = Complete; 873 mb->un.varLdSM.method = DL_FROM_SLIM; 874 mb->un.varLdSM.update_flash = 1; 875 mb->un.varLdSM.erase_or_prog = Function; 876 mb->un.varLdSM.dl_to_adr = Base; 877 mb->un.varLdSM.dl_len = DlByteCount; 878 879 if (BdeSize) { 880 mb->un.varLdSM.un.dl_from_slim_offset = DL_FROM_SLIM_OFFSET; 881 } else if (ProgId) { 882 mb->un.varLdSM.un.prog_id = *ProgId; 883 } else { 884 mb->un.varLdSM.un.dl_from_slim_offset = 0; 885 } 886 887 mb->mbxOwner = OWN_HOST; 888 889 } /* emlxs_format_prog_flash() */ 890 891 892 static void 893 emlxs_format_update_parms(MAILBOX *mb, PWAKE_UP_PARMS WakeUpParms) 894 { 895 bzero((void *)mb, MAILBOX_CMD_BSIZE); 896 897 mb->mbxCommand = MBX_UPDATE_CFG; 898 mb->un.varUpdateCfg.req_type = UPDATE_DATA; 899 mb->un.varUpdateCfg.region_id = WAKE_UP_PARMS_REGION_ID; 900 mb->un.varUpdateCfg.entry_len = sizeof (WAKE_UP_PARMS); 901 mb->un.varUpdateCfg.byte_len = sizeof (WAKE_UP_PARMS); 902 903 bcopy((caddr_t)WakeUpParms, 904 (caddr_t)&(mb->un.varUpdateCfg.cfg_data), 905 sizeof (WAKE_UP_PARMS)); 906 907 } /* emlxs_format_update_parms () */ 908 909 910 /* ARGSUSED */ 911 static void 912 emlxs_format_update_pci_cfg(emlxs_hba_t *hba, MAILBOX *mb, 913 uint32_t region_id, uint32_t size) 914 { 915 bzero((void *)mb, MAILBOX_CMD_BSIZE); 916 917 mb->mbxCommand = MBX_UPDATE_CFG; 918 mb->un.varUpdateCfg.Vbit = 1; 919 mb->un.varUpdateCfg.Obit = 1; 920 mb->un.varUpdateCfg.cfg_data = DL_FROM_SLIM_OFFSET; 921 mb->un.varUpdateCfg.req_type = UPDATE_DATA; 922 mb->un.varUpdateCfg.region_id = region_id; 923 mb->un.varUpdateCfg.entry_len = size; 924 mb->un.varUpdateCfg.byte_len = size; 925 926 927 } /* emlxs_format_update_pci_cfg() */ 928 929 930 931 static uint32_t 932 emlxs_update_boot_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 933 PROG_ID * prog_id, uint32_t proc_erom) 934 { 935 emlxs_port_t *port = &PPORT; 936 MAILBOX *mb; 937 MAILBOXQ *mbox; 938 uint32_t rval = 0; 939 940 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 941 KM_NOSLEEP)) == NULL) { 942 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 943 "Unable to allocate mailbox buffer."); 944 945 return (1); 946 } 947 948 mb = (MAILBOX *)mbox; 949 950 if (proc_erom && !(hba->model_info.chip & 951 (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 952 WakeUpParms->u1.EROM_prog_id = *prog_id; 953 (void) emlxs_update_exp_rom(hba, WakeUpParms); 954 } 955 956 WakeUpParms->u0.boot_bios_id = *prog_id; 957 958 emlxs_format_update_parms(mb, WakeUpParms); 959 960 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 961 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 962 "Unable to update boot wakeup parms: Mailbox cmd=%x " 963 "status=%x", mb->mbxCommand, mb->mbxStatus); 964 965 rval = 1; 966 } 967 968 if (mbox) { 969 kmem_free(mbox, sizeof (MAILBOXQ)); 970 } 971 972 return (rval); 973 974 } /* emlxs_update_boot_wakeup_parms() */ 975 976 977 978 static uint32_t 979 emlxs_update_ff_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 980 PROG_ID *prog_id) 981 { 982 emlxs_port_t *port = &PPORT; 983 uint32_t rval = 0; 984 MAILBOXQ *mbox; 985 MAILBOX *mb; 986 987 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 988 KM_NOSLEEP)) == NULL) { 989 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 990 "Unable to allocate mailbox buffer."); 991 992 return (1); 993 } 994 995 mb = (MAILBOX *)mbox; 996 997 WakeUpParms->prog_id = *prog_id; 998 999 emlxs_format_update_parms(mb, WakeUpParms); 1000 1001 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 1002 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1003 "Unable to update wakeup parameters: Mailbox cmd=%x " 1004 "status=%x", mb->mbxCommand, mb->mbxStatus); 1005 1006 rval = 1; 1007 } 1008 1009 if (mbox) { 1010 kmem_free(mbox, sizeof (MAILBOXQ)); 1011 } 1012 1013 return (rval); 1014 1015 } /* emlxs_update_ff_wakeup_parms() */ 1016 1017 1018 static uint32_t 1019 emlxs_update_sli1_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 1020 PROG_ID * prog_id) 1021 { 1022 emlxs_port_t *port = &PPORT; 1023 uint32_t rval = 0; 1024 MAILBOXQ *mbox; 1025 MAILBOX *mb; 1026 1027 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1028 KM_NOSLEEP)) == NULL) { 1029 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1030 "Unable to allocate mailbox buffer."); 1031 1032 return (1); 1033 } 1034 1035 mb = (MAILBOX *)mbox; 1036 1037 WakeUpParms->sli1_prog_id = *prog_id; 1038 1039 emlxs_format_update_parms(mb, WakeUpParms); 1040 1041 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 1042 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1043 "Unable to update wakeup parameters. Mailbox cmd=%x " 1044 "status=%x", mb->mbxCommand, mb->mbxStatus); 1045 1046 rval = 1; 1047 } 1048 1049 if (mbox) { 1050 kmem_free(mbox, sizeof (MAILBOXQ)); 1051 } 1052 1053 return (rval); 1054 1055 } /* emlxs_update_sli1_wakeup_parms() */ 1056 1057 1058 static uint32_t 1059 emlxs_update_sli2_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 1060 PROG_ID * prog_id) 1061 { 1062 emlxs_port_t *port = &PPORT; 1063 uint32_t rval = 0; 1064 MAILBOXQ *mbox; 1065 MAILBOX *mb; 1066 1067 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1068 KM_NOSLEEP)) == NULL) { 1069 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1070 "Unable to allocate mailbox buffer."); 1071 1072 return (1); 1073 } 1074 1075 mb = (MAILBOX *)mbox; 1076 1077 WakeUpParms->sli2_prog_id = *prog_id; 1078 1079 emlxs_format_update_parms(mb, WakeUpParms); 1080 1081 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 1082 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1083 "Unable to update wakeup parameters. Mailbox cmd=%x " 1084 "status=%x", mb->mbxCommand, mb->mbxStatus); 1085 1086 rval = 1; 1087 } 1088 1089 if (mbox) { 1090 kmem_free(mbox, sizeof (MAILBOXQ)); 1091 } 1092 1093 return (rval); 1094 1095 } /* emlxs_update_sli2_wakeup_parms() */ 1096 1097 1098 static uint32_t 1099 emlxs_update_sli3_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 1100 PROG_ID *prog_id) 1101 { 1102 emlxs_port_t *port = &PPORT; 1103 uint32_t rval = 0; 1104 MAILBOXQ *mbox; 1105 MAILBOX *mb; 1106 1107 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1108 KM_NOSLEEP)) == NULL) { 1109 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1110 "Unable to allocate mailbox buffer."); 1111 1112 return (1); 1113 } 1114 1115 mb = (MAILBOX *)mbox; 1116 1117 WakeUpParms->sli3_prog_id = *prog_id; 1118 1119 emlxs_format_update_parms(mb, WakeUpParms); 1120 1121 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 1122 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1123 "Unable to update wakeup parameters. Mailbox cmd=%x " 1124 "status=%x", mb->mbxCommand, mb->mbxStatus); 1125 1126 rval = 1; 1127 } 1128 1129 if (mbox) { 1130 kmem_free(mbox, sizeof (MAILBOXQ)); 1131 } 1132 1133 return (rval); 1134 1135 } /* emlxs_update_sli3_wakeup_parms() */ 1136 1137 1138 static uint32_t 1139 emlxs_update_sli4_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 1140 PROG_ID *prog_id) 1141 { 1142 emlxs_port_t *port = &PPORT; 1143 uint32_t rval = 0; 1144 MAILBOXQ *mbox; 1145 MAILBOX *mb; 1146 1147 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1148 KM_NOSLEEP)) == NULL) { 1149 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1150 "Unable to allocate mailbox buffer."); 1151 1152 return (1); 1153 } 1154 1155 mb = (MAILBOX *)mbox; 1156 1157 WakeUpParms->sli4_prog_id = *prog_id; 1158 1159 emlxs_format_update_parms(mb, WakeUpParms); 1160 1161 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 1162 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1163 "Unable to update wakeup parameters. Mailbox cmd=%x " 1164 "status=%x", mb->mbxCommand, mb->mbxStatus); 1165 1166 rval = 1; 1167 } 1168 1169 if (mbox) { 1170 kmem_free(mbox, sizeof (MAILBOXQ)); 1171 } 1172 1173 return (rval); 1174 1175 } /* emlxs_update_sli4_wakeup_parms() */ 1176 1177 1178 /* ARGSUSED */ 1179 static uint32_t 1180 emlxs_start_rel_download(emlxs_hba_t *hba, 1181 PIMAGE_HDR ImageHdr, 1182 caddr_t Buffer, 1183 PWAKE_UP_PARMS WakeUpParms, 1184 uint32_t MaxRbusSramSize, uint32_t MaxIbusSramSize) 1185 { 1186 emlxs_port_t *port = &PPORT; 1187 MAILBOXQ *mbox; 1188 MAILBOX *mb; 1189 uint32_t *Src; 1190 uint32_t *Dst; 1191 caddr_t DataBuffer = NULL; 1192 uint32_t rval = 1; 1193 uint32_t DlByteCount = ImageHdr->BlockSize; 1194 uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT; 1195 uint32_t DlCount; 1196 uint32_t i; 1197 1198 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1199 "Performing relative download..."); 1200 1201 if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT, 1202 KM_NOSLEEP)) == NULL) { 1203 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1204 "Unable to allocate data buffer."); 1205 1206 return (rval); 1207 } 1208 1209 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1210 KM_NOSLEEP)) == NULL) { 1211 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1212 "Unable to allocate mailbox buffer."); 1213 1214 kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 1215 1216 return (rval); 1217 } 1218 1219 if (ImageHdr->Id.Type == FUNC_FIRMWARE) { 1220 switch (MaxRbusSramSize) { 1221 case REDUCED_RBUS_SRAM_CFG: 1222 if (ImageHdr->Id.Id != REDUCED_SRAM_CFG_PROG_ID) { 1223 EMLXS_MSGF(EMLXS_CONTEXT, 1224 &emlxs_image_bad_msg, 1225 "Invalid header id."); 1226 1227 return (1); 1228 } 1229 break; 1230 case FULL_RBUS_SRAM_CFG: 1231 if (ImageHdr->Id.Id != FULL_SRAM_CFG_PROG_ID) { 1232 EMLXS_MSGF(EMLXS_CONTEXT, 1233 &emlxs_image_bad_msg, 1234 "Invalid header id."); 1235 1236 return (1); 1237 } 1238 break; 1239 default: 1240 if (ImageHdr->Id.Id != OTHER_SRAM_CFG_PROG_ID) { 1241 EMLXS_MSGF(EMLXS_CONTEXT, 1242 &emlxs_image_bad_msg, 1243 "Invalid header id."); 1244 1245 return (1); 1246 } 1247 break; 1248 } 1249 } 1250 1251 mb = (MAILBOX *)mbox; 1252 1253 emlxs_format_prog_flash(mb, 0, DlByteCount, ERASE_FLASH, 0, 0, 0, 1254 &ImageHdr->Id); 1255 1256 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, "Erasing flash..."); 1257 1258 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 1259 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1260 "Unable to erase flash. Mailbox cmd=%x status=%x", 1261 mb->mbxCommand, mb->mbxStatus); 1262 1263 rval = 1; 1264 1265 goto EXIT_REL_DOWNLOAD; 1266 } 1267 1268 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1269 "Programming flash..."); 1270 1271 while (DlByteCount) { 1272 if (DlByteCount > SegSize) { 1273 DlCount = SegSize; 1274 } else { 1275 DlCount = DlByteCount; 1276 } 1277 DlByteCount -= DlCount; 1278 1279 Dst = (uint32_t *)DataBuffer; 1280 Src = (uint32_t *)Buffer; 1281 1282 for (i = 0; i < (DlCount / 4); i++) { 1283 *Dst = *Src; 1284 Dst++; 1285 Src++; 1286 } 1287 1288 WRITE_SLIM_COPY(hba, (uint32_t *)DataBuffer, 1289 (volatile uint32_t *)((volatile char *)hba->slim_addr + 1290 sizeof (MAILBOX)), (DlCount / sizeof (uint32_t))); 1291 1292 emlxs_format_prog_flash(mb, 1293 0, 1294 DlCount, 1295 PROGRAM_FLASH, 1296 (DlByteCount) ? 0 : 1, 0, DlCount, &ImageHdr->Id); 1297 1298 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 1299 MBX_SUCCESS) { 1300 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1301 "Unable to program flash. Mailbox cmd=%x status=%x", 1302 mb->mbxCommand, mb->mbxStatus); 1303 1304 rval = 1; 1305 1306 goto EXIT_REL_DOWNLOAD; 1307 } 1308 1309 Buffer += DlCount; 1310 } 1311 1312 #ifdef FMA_SUPPORT 1313 if (emlxs_fm_check_acc_handle(hba, hba->slim_acc_handle) 1314 != DDI_FM_OK) { 1315 EMLXS_MSGF(EMLXS_CONTEXT, 1316 &emlxs_invalid_access_handle_msg, NULL); 1317 1318 rval = 1; 1319 1320 goto EXIT_REL_DOWNLOAD; 1321 } 1322 #endif /* FMA_SUPPORT */ 1323 1324 switch (ImageHdr->Id.Type) { 1325 case TEST_PROGRAM: 1326 rval = 0; 1327 break; 1328 1329 case FUNC_FIRMWARE: 1330 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1331 "FF: Updating parms..."); 1332 rval = 1333 emlxs_update_ff_wakeup_parms(hba, WakeUpParms, 1334 &ImageHdr->Id); 1335 break; 1336 1337 case BOOT_BIOS: 1338 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1339 "BOOT: Updating parms..."); 1340 rval = 1341 emlxs_update_boot_wakeup_parms(hba, WakeUpParms, 1342 &ImageHdr->Id, 1); 1343 break; 1344 1345 case SLI1_OVERLAY: 1346 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1347 "SLI1: Updating parms..."); 1348 rval = 1349 emlxs_update_sli1_wakeup_parms(hba, WakeUpParms, 1350 &ImageHdr->Id); 1351 break; 1352 1353 case SLI2_OVERLAY: 1354 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1355 "SLI2: Updating parms..."); 1356 rval = 1357 emlxs_update_sli2_wakeup_parms(hba, WakeUpParms, 1358 &ImageHdr->Id); 1359 break; 1360 1361 case SLI3_OVERLAY: 1362 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1363 "SLI3: Updating parms..."); 1364 rval = 1365 emlxs_update_sli3_wakeup_parms(hba, WakeUpParms, 1366 &ImageHdr->Id); 1367 break; 1368 1369 case SLI4_OVERLAY: 1370 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1371 "SLI4: Updating parms..."); 1372 rval = 1373 emlxs_update_sli4_wakeup_parms(hba, WakeUpParms, 1374 &ImageHdr->Id); 1375 break; 1376 1377 default: 1378 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 1379 "Image type not supported. Type=%x", ImageHdr->Id.Type); 1380 1381 break; 1382 } 1383 1384 EXIT_REL_DOWNLOAD: 1385 if (DataBuffer) { 1386 kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 1387 } 1388 1389 if (mbox) { 1390 kmem_free(mbox, sizeof (MAILBOXQ)); 1391 } 1392 1393 return (rval); 1394 1395 } /* emlxs_start_rel_download() */ 1396 1397 1398 #define FLASH_POLLING_BIT 0x80 1399 #define FLASH_ERROR_BIT 0x20 1400 1401 typedef struct _flash_t 1402 { 1403 uint32_t offset; 1404 uint8_t val; 1405 } flash_t; 1406 1407 1408 1409 static uint32_t 1410 emlxs_write_fcode_flash(emlxs_hba_t *hba, 1411 PIMAGE_HDR ImageHdr, caddr_t Buffer) 1412 { 1413 emlxs_port_t *port = &PPORT; 1414 uint8_t bb; 1415 uint8_t cc; 1416 uint8_t *src; 1417 uint32_t DlByteCount = ImageHdr->BlockSize; 1418 uint32_t i; 1419 uint32_t j; 1420 uint32_t k; 1421 1422 flash_t wr[3] = { 1423 {0x555, 0xaa}, 1424 {0x2aa, 0x55}, 1425 {0x555, 0xa0} 1426 }; 1427 1428 /* Load Fcode */ 1429 src = (uint8_t *)Buffer + sizeof (IMAGE_HDR); 1430 for (i = 0; i < DlByteCount; i++) { 1431 for (k = 0; k < 3; k++) { 1432 SBUS_WRITE_FLASH_COPY(hba, wr[k].offset, wr[k].val); 1433 } 1434 1435 /* Reverse Endian word alignment */ 1436 j = (i & 3) ^ 3; 1437 1438 bb = src[j]; 1439 1440 if (j == 0) { 1441 src += 4; 1442 } 1443 1444 SBUS_WRITE_FLASH_COPY(hba, i, bb); 1445 1446 /* check for complete */ 1447 for (;;) { 1448 DELAYUS(20); 1449 1450 cc = SBUS_READ_FLASH_COPY(hba, i); 1451 1452 /* If data matches then continue */ 1453 if (cc == bb) { 1454 break; 1455 } 1456 1457 /* Polling bit will be inverse final value */ 1458 /* while active */ 1459 if ((cc ^ bb) & FLASH_POLLING_BIT) { 1460 /* Still busy */ 1461 1462 /* Check for error bit */ 1463 if (cc & FLASH_ERROR_BIT) { 1464 /* Read data one more time */ 1465 cc = SBUS_READ_FLASH_COPY(hba, i); 1466 1467 /* Check if data matches */ 1468 if (cc == bb) { 1469 break; 1470 } 1471 1472 EMLXS_MSGF(EMLXS_CONTEXT, 1473 &emlxs_download_failed_msg, 1474 "FCode write error: offset:%x " 1475 "wrote:%x read:%x\n", i, bb, cc); 1476 1477 return (1); 1478 } 1479 } 1480 } 1481 } 1482 1483 /* Load Header */ 1484 src = (uint8_t *)ImageHdr; 1485 1486 for (i = (0xFFFF - sizeof (IMAGE_HDR)); i < 0xFFFF; i++) { 1487 for (k = 0; k < 3; k++) { 1488 SBUS_WRITE_FLASH_COPY(hba, wr[k].offset, wr[k].val); 1489 } 1490 1491 /* Reverse Endian word alignment */ 1492 j = (i & 3) ^ 3; 1493 1494 bb = src[j]; 1495 1496 if (j == 0) { 1497 src += 4; 1498 } 1499 1500 SBUS_WRITE_FLASH_COPY(hba, i, bb); 1501 1502 /* check for complete */ 1503 for (;;) { 1504 DELAYUS(20); 1505 1506 cc = SBUS_READ_FLASH_COPY(hba, i); 1507 1508 /* If data matches then continue */ 1509 if (cc == bb) { 1510 break; 1511 } 1512 1513 /* Polling bit will be inverse final value */ 1514 /* while active */ 1515 if ((cc ^ bb) & FLASH_POLLING_BIT) { 1516 /* Still busy */ 1517 1518 /* Check for error bit */ 1519 if (cc & FLASH_ERROR_BIT) { 1520 /* Read data one more time */ 1521 cc = SBUS_READ_FLASH_COPY(hba, i); 1522 1523 /* Check if data matches */ 1524 if (cc == bb) { 1525 break; 1526 } 1527 1528 EMLXS_MSGF(EMLXS_CONTEXT, 1529 &emlxs_download_failed_msg, 1530 "FCode write error: offset:%x " 1531 "wrote:%x read:%x\n", i, bb, cc); 1532 1533 return (1); 1534 } 1535 } 1536 } 1537 } 1538 1539 #ifdef FMA_SUPPORT 1540 if (emlxs_fm_check_acc_handle(hba, hba->sbus_flash_acc_handle) 1541 != DDI_FM_OK) { 1542 EMLXS_MSGF(EMLXS_CONTEXT, 1543 &emlxs_invalid_access_handle_msg, NULL); 1544 return (1); 1545 } 1546 #endif /* FMA_SUPPORT */ 1547 1548 return (0); 1549 1550 } /* emlxs_write_fcode_flash() */ 1551 1552 1553 1554 static uint32_t 1555 emlxs_erase_fcode_flash(emlxs_hba_t *hba) 1556 { 1557 emlxs_port_t *port = &PPORT; 1558 int32_t i, j; 1559 uint8_t cc; 1560 uint32_t offset; 1561 1562 flash_t ef[6] = { 1563 {0x555, 0xaa}, 1564 {0x2aa, 0x55}, 1565 {0x555, 0x80}, 1566 {0x555, 0xaa}, 1567 {0x2aa, 0x55}, 1568 {0x555, 0x10} 1569 }; 1570 1571 /* Auto select */ 1572 flash_t as[3] = { 1573 {0x555, 0xaa}, 1574 {0x2aa, 0x55}, 1575 {0x555, 0x90} 1576 }; 1577 1578 1579 /* Check Manufacturers Code */ 1580 for (i = 0; i < 3; i++) { 1581 SBUS_WRITE_FLASH_COPY(hba, as[i].offset, as[i].val); 1582 } 1583 1584 cc = SBUS_READ_FLASH_COPY(hba, 0); 1585 1586 /* Check Device Code */ 1587 for (i = 0; i < 3; i++) { 1588 SBUS_WRITE_FLASH_COPY(hba, as[i].offset, as[i].val); 1589 } 1590 1591 cc = SBUS_READ_FLASH_COPY(hba, 1); 1592 1593 1594 /* Check block protections (up to 4 16K blocks = 64K) */ 1595 for (j = 0; j < 4; j++) { 1596 for (i = 0; i < 3; i++) { 1597 SBUS_WRITE_FLASH_COPY(hba, as[i].offset, as[i].val); 1598 } 1599 1600 offset = (j << 14) | 0x2; 1601 1602 cc = SBUS_READ_FLASH_COPY(hba, offset); 1603 1604 if (cc == 0x01) { 1605 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1606 "Block %d is protected and can't be erased.", j); 1607 } 1608 } 1609 1610 /* Write erase flash sequence */ 1611 for (i = 0; i < 6; i++) { 1612 SBUS_WRITE_FLASH_COPY(hba, ef[i].offset, ef[i].val); 1613 } 1614 1615 /* check for complete */ 1616 for (;;) { 1617 /* Delay 3 seconds */ 1618 DELAYMS(3000); 1619 1620 cc = SBUS_READ_FLASH_COPY(hba, 0); 1621 1622 1623 /* If data matches then continue; */ 1624 if (cc == 0xff) { 1625 break; 1626 } 1627 1628 /* Polling bit will be inverse final value while active */ 1629 if ((cc ^ 0xff) & FLASH_POLLING_BIT) { 1630 /* Still busy */ 1631 1632 /* Check for error bit */ 1633 if (cc & FLASH_ERROR_BIT) { 1634 /* Read data one more time */ 1635 cc = SBUS_READ_FLASH_COPY(hba, 0); 1636 1637 /* Check if data matches */ 1638 if (cc == 0xff) { 1639 break; 1640 } 1641 1642 EMLXS_MSGF(EMLXS_CONTEXT, 1643 &emlxs_download_failed_msg, 1644 "FCode write error: offset:%x wrote:%x " 1645 "read:%x\n", i, 0xff, cc); 1646 1647 return (1); 1648 } 1649 } 1650 } 1651 1652 #ifdef FMA_SUPPORT 1653 if (emlxs_fm_check_acc_handle(hba, hba->sbus_flash_acc_handle) 1654 != DDI_FM_OK) { 1655 EMLXS_MSGF(EMLXS_CONTEXT, 1656 &emlxs_invalid_access_handle_msg, NULL); 1657 return (1); 1658 } 1659 #endif /* FMA_SUPPORT */ 1660 1661 return (0); 1662 1663 } /* emlxs_erase_fcode_flash() */ 1664 1665 1666 extern uint32_t 1667 emlxs_get_load_list(emlxs_hba_t *hba, PROG_ID *load_list) 1668 { 1669 emlxs_port_t *port = &PPORT; 1670 LOAD_ENTRY *LoadEntry; 1671 LOAD_LIST *LoadList = NULL; 1672 uint32_t i; 1673 uint32_t rval = 0; 1674 1675 bzero(load_list, (sizeof (PROG_ID) * MAX_LOAD_ENTRY)); 1676 1677 if ((LoadList = (LOAD_LIST *)kmem_zalloc(sizeof (LOAD_LIST), 1678 KM_NOSLEEP)) == NULL) { 1679 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1680 "Unable to allocate LOADLIST buffer."); 1681 1682 rval = 1; 1683 goto done; 1684 } 1685 1686 if (emlxs_read_load_list(hba, LoadList)) { 1687 rval = 1; 1688 goto done; 1689 } 1690 1691 for (i = 0; i < LoadList->entry_cnt; i++) { 1692 LoadEntry = &LoadList->load_entry[i]; 1693 if ((LoadEntry->un.wd[0] != 0) && 1694 (LoadEntry->un.wd[0] != 0xffffffff)) { 1695 load_list[i] = LoadEntry->un.id; 1696 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1697 "Load List[%d]: %08x %08x", i, 1698 LoadEntry->un.wd[0], LoadEntry->un.wd[1]); 1699 } 1700 } 1701 1702 done: 1703 1704 if (LoadList) { 1705 kmem_free(LoadList, sizeof (LOAD_LIST)); 1706 } 1707 1708 return (rval); 1709 1710 } /* emlxs_get_load_list() */ 1711 1712 1713 extern uint32_t 1714 emlxs_read_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 1715 uint32_t verbose) 1716 { 1717 emlxs_port_t *port = &PPORT; 1718 MAILBOXQ *mbox; 1719 MAILBOX *mb; 1720 uint32_t rval = 0; 1721 uint32_t *wd; 1722 1723 bzero(WakeUpParms, sizeof (WAKE_UP_PARMS)); 1724 1725 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1726 KM_NOSLEEP)) == NULL) { 1727 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1728 "Unable to allocate mailbox buffer."); 1729 1730 return (1); 1731 } 1732 1733 mb = (MAILBOX *)mbox; 1734 1735 emlxs_format_dump(mb, 1736 DMP_NV_PARAMS, 1737 WAKE_UP_PARMS_REGION_ID, 1738 sizeof (WAKE_UP_PARMS) / sizeof (uint32_t), 0); 1739 1740 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 1741 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1742 "Unable to get parameters: Mailbox cmd=%x status=%x", 1743 mb->mbxCommand, mb->mbxStatus); 1744 1745 if (mb->un.varDmp.word_cnt == (uint32_t)CFG_DATA_NO_REGION) { 1746 rval = (uint32_t)CFG_DATA_NO_REGION; 1747 } else { 1748 rval = 1; 1749 } 1750 } else { 1751 bcopy((caddr_t)&mb->un.varDmp.resp_offset, 1752 (caddr_t)WakeUpParms, sizeof (WAKE_UP_PARMS)); 1753 1754 if (verbose) { 1755 wd = (uint32_t *)&WakeUpParms->prog_id; 1756 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1757 "Wakeup: prog_id=%08x %08x", wd[0], wd[1]); 1758 1759 wd = (uint32_t *)&WakeUpParms->u0.boot_bios_id; 1760 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1761 "Wakeup: boot_bios_id=%08x %08x", wd[0], wd[1]); 1762 1763 wd = (uint32_t *)&WakeUpParms->sli1_prog_id; 1764 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1765 "Wakeup: sli1_prog_id=%08x %08x", wd[0], wd[1]); 1766 1767 wd = (uint32_t *)&WakeUpParms->sli2_prog_id; 1768 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1769 "Wakeup: sli2_prog_id=%08x %08x", wd[0], wd[1]); 1770 1771 wd = (uint32_t *)&WakeUpParms->sli3_prog_id; 1772 if (wd[0] || wd[1]) { 1773 EMLXS_MSGF(EMLXS_CONTEXT, 1774 &emlxs_init_debug_msg, 1775 "Wakeup: sli3_prog_id=%08x %08x", wd[0], 1776 wd[1]); 1777 } 1778 1779 wd = (uint32_t *)&WakeUpParms->sli4_prog_id; 1780 if (wd[0] || wd[1]) { 1781 EMLXS_MSGF(EMLXS_CONTEXT, 1782 &emlxs_init_debug_msg, 1783 "Wakeup: sli4_prog_id=%08x %08x", wd[0], 1784 wd[1]); 1785 } 1786 1787 wd = (uint32_t *)&WakeUpParms->u1.EROM_prog_id; 1788 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1789 "Wakeup: EROM_prog_id=%08x %08x", wd[0], wd[1]); 1790 1791 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1792 "Wakeup: pci_cfg_rsvd=%x", 1793 WakeUpParms->pci_cfg_rsvd); 1794 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1795 "Wakeup: use_hdw_def=%x", 1796 WakeUpParms->use_hdw_def); 1797 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1798 "Wakeup: pci_cfg_sel=%x", 1799 WakeUpParms->pci_cfg_sel); 1800 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1801 "Wakeup: cfg_lookup=%x", 1802 WakeUpParms->pci_cfg_lookup_sel); 1803 } 1804 } 1805 1806 done: 1807 1808 if (mbox) { 1809 kmem_free(mbox, sizeof (MAILBOXQ)); 1810 } 1811 1812 return (rval); 1813 1814 } /* emlxs_read_wakeup_parms() */ 1815 1816 1817 static uint32_t 1818 emlxs_read_load_list(emlxs_hba_t *hba, LOAD_LIST *LoadList) 1819 { 1820 emlxs_port_t *port = &PPORT; 1821 LOAD_ENTRY *LoadEntry; 1822 uint32_t *Uptr; 1823 uint32_t CurEntryAddr; 1824 MAILBOXQ *mbox = NULL; 1825 MAILBOX *mb; 1826 1827 bzero((caddr_t)LoadList, sizeof (LOAD_LIST)); 1828 1829 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1830 KM_NOSLEEP)) == NULL) { 1831 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1832 "Unable to allocate mailbox buffer."); 1833 1834 return (1); 1835 } 1836 1837 mb = (MAILBOX *)mbox; 1838 1839 emlxs_format_dump(mb, DMP_MEM_REG, 0, 2, FLASH_LOAD_LIST_ADR); 1840 1841 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 1842 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1843 "Unable to get load list: Mailbox cmd=%x status=%x", 1844 mb->mbxCommand, mb->mbxStatus); 1845 1846 goto done; 1847 } 1848 1849 Uptr = (uint32_t *)&mb->un.varDmp.resp_offset; 1850 1851 LoadList->head = Uptr[0]; 1852 LoadList->tail = Uptr[1]; 1853 1854 CurEntryAddr = LoadList->head; 1855 1856 while ((CurEntryAddr != FLASH_LOAD_LIST_ADR) && 1857 (LoadList->entry_cnt < MAX_LOAD_ENTRY)) { 1858 LoadEntry = &LoadList->load_entry[LoadList->entry_cnt]; 1859 LoadList->entry_cnt++; 1860 1861 emlxs_format_dump(mb, 1862 DMP_MEM_REG, 0, FLASH_LOAD_ENTRY_SIZE, CurEntryAddr); 1863 1864 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 1865 MBX_SUCCESS) { 1866 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1867 "Unable to get load list (%d): Mailbox cmd=%x " 1868 "status=%x", LoadList->entry_cnt, mb->mbxCommand, 1869 mb->mbxStatus); 1870 1871 goto done; 1872 } 1873 1874 Uptr = (uint32_t *)&(mb->un.varDmp.resp_offset); 1875 1876 LoadEntry->next = Uptr[0]; 1877 LoadEntry->prev = Uptr[1]; 1878 LoadEntry->start_adr = Uptr[2]; 1879 LoadEntry->len = Uptr[3]; 1880 LoadEntry->un.wd[0] = Uptr[4]; 1881 LoadEntry->un.wd[1] = Uptr[5]; 1882 1883 /* update next current load entry address */ 1884 CurEntryAddr = LoadEntry->next; 1885 1886 } /* end of while (not end of list) */ 1887 1888 done: 1889 1890 if (mbox) { 1891 kmem_free(mbox, sizeof (MAILBOXQ)); 1892 } 1893 1894 return (0); 1895 1896 } /* emlxs_read_load_list() */ 1897 1898 1899 1900 1901 static uint32_t 1902 emlxs_get_abs_image_type(caddr_t Buffer, uint32_t BufferSize) 1903 { 1904 uint32_t Version; 1905 1906 if (BufferSize < (SLI_VERSION_LOC + 4)) 1907 return (0xffffffff); 1908 1909 Buffer += SLI_VERSION_LOC; 1910 Version = *((uint32_t *)Buffer); 1911 1912 return (Version); 1913 1914 } /* emlxs_get_abs_image_type() */ 1915 1916 1917 static uint32_t 1918 emlxs_get_dwc_image_type(emlxs_hba_t *hba, caddr_t Buffer, 1919 uint32_t BufferSize, PAIF_HDR AifHeader) 1920 { 1921 emlxs_port_t *port = &PPORT; 1922 IMAGE_HDR ImageHdr; 1923 uint32_t NextImage; 1924 uint32_t i; 1925 uint8_t *Sptr; 1926 uint8_t *Dptr; 1927 uint32_t HwId = 0xffffffff; 1928 1929 NextImage = SLI_IMAGE_START - AifHeader->ImageBase; 1930 1931 while (BufferSize > NextImage) { 1932 Sptr = (uint8_t *)&Buffer[NextImage]; 1933 Dptr = (uint8_t *)&ImageHdr; 1934 for (i = 0; i < sizeof (IMAGE_HDR); i++) { 1935 Dptr[i] = Sptr[i]; 1936 } 1937 1938 if (ImageHdr.BlockSize == 0xffffffff) 1939 break; 1940 1941 switch (ImageHdr.Id.Type) { 1942 case 6: 1943 case 7: 1944 if (HwId == 0xffffffff) { 1945 HwId = ImageHdr.Id.Id; 1946 } 1947 1948 if (HwId != ImageHdr.Id.Id) { 1949 EMLXS_MSGF(EMLXS_CONTEXT, 1950 &emlxs_image_bad_msg, 1951 "Invalid hardware id. %x %x", HwId, 1952 ImageHdr.Id.Id); 1953 } 1954 break; 1955 } 1956 1957 NextImage += ImageHdr.BlockSize; 1958 } 1959 1960 return (HwId); 1961 1962 } /* emlxs_get_dwc_image_type() */ 1963 1964 1965 static int 1966 emlxs_build_parms(caddr_t Buffer, 1967 PWAKE_UP_PARMS AbsWakeUpParms, 1968 uint32_t BufferSize, PAIF_HDR AifHeader, int32_t DwcFile) 1969 { 1970 IMAGE_HDR ImageHdr; 1971 uint32_t NextImage; 1972 uint32_t i; 1973 int32_t ChangeParams = FALSE; 1974 caddr_t Sptr; 1975 caddr_t Dptr; 1976 1977 bzero((caddr_t)AbsWakeUpParms, sizeof (WAKE_UP_PARMS)); 1978 1979 if (!DwcFile && ((AifHeader->RoSize + AifHeader->RwSize) <= 0x20000)) { 1980 return (FALSE); 1981 } 1982 1983 NextImage = SLI_IMAGE_START - AifHeader->ImageBase; 1984 1985 while (BufferSize > NextImage) { 1986 Sptr = &Buffer[NextImage]; 1987 Dptr = (caddr_t)&ImageHdr; 1988 for (i = 0; i < sizeof (IMAGE_HDR); i++) { 1989 Dptr[i] = Sptr[i]; 1990 } 1991 1992 if (ImageHdr.BlockSize == 0xffffffff) 1993 break; 1994 1995 switch (ImageHdr.Id.Type) { 1996 case TEST_PROGRAM: 1997 break; 1998 case FUNC_FIRMWARE: 1999 AbsWakeUpParms->prog_id = ImageHdr.Id; 2000 ChangeParams = TRUE; 2001 break; 2002 case BOOT_BIOS: 2003 AbsWakeUpParms->u0.boot_bios_id = ImageHdr.Id; 2004 ChangeParams = TRUE; 2005 break; 2006 case SLI1_OVERLAY: 2007 AbsWakeUpParms->sli1_prog_id = ImageHdr.Id; 2008 ChangeParams = TRUE; 2009 break; 2010 case SLI2_OVERLAY: 2011 AbsWakeUpParms->sli2_prog_id = ImageHdr.Id; 2012 ChangeParams = TRUE; 2013 break; 2014 case SLI3_OVERLAY: 2015 AbsWakeUpParms->sli3_prog_id = ImageHdr.Id; 2016 ChangeParams = TRUE; 2017 break; 2018 case SLI4_OVERLAY: 2019 AbsWakeUpParms->sli4_prog_id = ImageHdr.Id; 2020 ChangeParams = TRUE; 2021 break; 2022 default: 2023 break; 2024 } 2025 2026 NextImage += ImageHdr.BlockSize; 2027 } 2028 2029 return (ChangeParams); 2030 2031 } /* emlxs_build_parms() */ 2032 2033 2034 static uint32_t 2035 emlxs_update_wakeup_parms(emlxs_hba_t *hba, 2036 PWAKE_UP_PARMS AbsWakeUpParms, PWAKE_UP_PARMS WakeUpParms) 2037 { 2038 emlxs_port_t *port = &PPORT; 2039 MAILBOX *mb; 2040 MAILBOXQ *mbox; 2041 uint32_t rval = 0; 2042 2043 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2044 KM_NOSLEEP)) == NULL) { 2045 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2046 "Unable to allocate mailbox buffer."); 2047 2048 return (1); 2049 } 2050 2051 mb = (MAILBOX *)mbox; 2052 2053 WakeUpParms->prog_id = AbsWakeUpParms->prog_id; 2054 WakeUpParms->u0.boot_bios_id = AbsWakeUpParms->u0.boot_bios_id; 2055 WakeUpParms->sli1_prog_id = AbsWakeUpParms->sli1_prog_id; 2056 WakeUpParms->sli2_prog_id = AbsWakeUpParms->sli2_prog_id; 2057 WakeUpParms->sli3_prog_id = AbsWakeUpParms->sli3_prog_id; 2058 WakeUpParms->sli4_prog_id = AbsWakeUpParms->sli4_prog_id; 2059 2060 emlxs_format_update_parms(mb, WakeUpParms); 2061 2062 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 2063 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2064 "Unable to update wakeup parameters: Mailbox cmd=%x " 2065 "status=%x", mb->mbxCommand, mb->mbxStatus); 2066 2067 rval = 1; 2068 } 2069 2070 if (mbox) { 2071 kmem_free(mbox, sizeof (MAILBOXQ)); 2072 } 2073 2074 return (rval); 2075 2076 } /* emlxs_update_wakeup_parms() */ 2077 2078 2079 static uint32_t 2080 emlxs_validate_version(emlxs_hba_t *hba, emlxs_fw_file_t *file, uint32_t id, 2081 uint32_t type, char *file_type) 2082 { 2083 emlxs_port_t *port = &PPORT; 2084 2085 /* Create the version label */ 2086 emlxs_decode_version(file->version, file->label); 2087 2088 /* Process the DWC type */ 2089 switch (type) { 2090 case TEST_PROGRAM: 2091 2092 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2093 "%s: TEST: offset=%08x version=%08x, %s", file_type, 2094 file->offset, file->version, file->label); 2095 2096 break; 2097 2098 case BOOT_BIOS: 2099 2100 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2101 "%s: BOOT: offset=%08x version=%08x, %s", file_type, 2102 file->offset, file->version, file->label); 2103 2104 if (!emlxs_bios_check(hba, id)) { 2105 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2106 "BOOT Check: Image not compatible with %s. id=%02x", 2107 hba->model_info.model, id); 2108 2109 return (EMLXS_IMAGE_INCOMPATIBLE); 2110 } 2111 2112 break; 2113 2114 case FUNC_FIRMWARE: /* Stub */ 2115 2116 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2117 "%s: STUB: offset=%08x version=%08x, %s", file_type, 2118 file->offset, file->version, file->label); 2119 2120 if (!emlxs_stub_check(hba, id)) { 2121 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2122 "STUB Check: Image not compatible with %s. id=%02x", 2123 hba->model_info.model, id); 2124 2125 return (EMLXS_IMAGE_INCOMPATIBLE); 2126 } 2127 2128 break; 2129 2130 case SLI1_OVERLAY: 2131 2132 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2133 "%s: SLI1: offset=%08x version=%08x, %s", file_type, 2134 file->offset, file->version, file->label); 2135 2136 if (!emlxs_sli1_check(hba, id)) { 2137 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2138 "SLI1 Check: Image not compatible with %s. id=%02x", 2139 hba->model_info.model, id); 2140 2141 return (EMLXS_IMAGE_INCOMPATIBLE); 2142 } 2143 2144 break; 2145 2146 case SLI2_OVERLAY: 2147 2148 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2149 "%s: SLI2: offset=%08x version=%08x, %s", file_type, 2150 file->offset, file->version, file->label); 2151 2152 if (!emlxs_sli2_check(hba, id)) { 2153 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2154 "SLI2 Check: Image not compatible with %s. id=%02x", 2155 hba->model_info.model, id); 2156 2157 return (EMLXS_IMAGE_INCOMPATIBLE); 2158 } 2159 2160 break; 2161 2162 case SLI3_OVERLAY: 2163 2164 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2165 "%s: SLI3: offset=%08x version=%08x, %s", file_type, 2166 file->offset, file->version, file->label); 2167 2168 if (!emlxs_sli3_check(hba, id)) { 2169 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2170 "SLI3 Check: Image not compatible with %s. id=%02x", 2171 hba->model_info.model, id); 2172 2173 return (EMLXS_IMAGE_INCOMPATIBLE); 2174 } 2175 2176 break; 2177 2178 case SLI4_OVERLAY: 2179 2180 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2181 "%s: SLI4: offset=%08x version=%08x, %s", file_type, 2182 file->offset, file->version, file->label); 2183 2184 if (!emlxs_sli4_check(hba, id)) { 2185 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2186 "SLI4 Check: Image not compatible with %s. id=%02x", 2187 hba->model_info.model, id); 2188 2189 return (EMLXS_IMAGE_INCOMPATIBLE); 2190 } 2191 2192 break; 2193 2194 case SBUS_FCODE: 2195 2196 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2197 "%s: SBUS FCODE: offset=%08x version=%08x, %s", 2198 file_type, file->offset, file->version, file->label); 2199 2200 if (!emlxs_sbus_fcode_check(hba, id)) { 2201 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2202 "SBUS FCODE Check: Image not compatible with %s. " 2203 "id=%02x", hba->model_info.model, id); 2204 2205 return (EMLXS_IMAGE_INCOMPATIBLE); 2206 } 2207 2208 break; 2209 2210 case KERNEL_CODE: 2211 2212 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2213 "%s: KERN: offset=%08x version=%08x, %s", file_type, 2214 file->offset, file->version, file->label); 2215 2216 if (!emlxs_kern_check(hba, id)) { 2217 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2218 "KERN Check: Image not compatible with %s. id=%02x", 2219 hba->model_info.model, id); 2220 2221 return (EMLXS_IMAGE_INCOMPATIBLE); 2222 } 2223 2224 break; 2225 2226 default: 2227 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2228 "%s: Image type not supported. type=%x", file_type, type); 2229 2230 return (EMLXS_IMAGE_BAD); 2231 } 2232 2233 return (0); 2234 2235 } /* emlxs_validate_version() */ 2236 2237 2238 static uint32_t 2239 emlxs_validate_image(emlxs_hba_t *hba, caddr_t Buffer, uint32_t Size, 2240 emlxs_fw_image_t *image) 2241 { 2242 emlxs_port_t *port = &PPORT; 2243 uint32_t ImageType; 2244 AIF_HDR AifHdr; 2245 IMAGE_HDR ImageHdr; 2246 uint32_t NextImage; 2247 uint32_t FileType; 2248 uint32_t FileLen = 0; 2249 uint32_t TotalLen = 0; 2250 uint32_t *CkSumEnd; 2251 uint32_t id; 2252 uint32_t type; 2253 uint32_t ver; 2254 uint32_t ImageLength; 2255 uint32_t BufferSize; 2256 uint32_t rval = 0; 2257 caddr_t bptr; 2258 emlxs_vpd_t *vpd; 2259 2260 vpd = &VPD; 2261 2262 /* Get image type */ 2263 ImageType = *((uint32_t *)Buffer); 2264 2265 /* Pegasus and beyond adapters */ 2266 if ((ImageType == NOP_IMAGE_TYPE) && 2267 !(hba->model_info.chip & 2268 (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 2269 bptr = Buffer; 2270 TotalLen = sizeof (uint32_t); 2271 2272 while (TotalLen < Size) { 2273 if (Size < sizeof (AIF_HDR)) { 2274 EMLXS_MSGF(EMLXS_CONTEXT, 2275 &emlxs_image_bad_msg, 2276 "Invalid image header length: 0x%x < 0x%x", 2277 Size, sizeof (AIF_HDR)); 2278 2279 return (EMLXS_IMAGE_BAD); 2280 } 2281 2282 bcopy(bptr, &AifHdr, sizeof (AIF_HDR)); 2283 emlxs_disp_aif_header(hba, &AifHdr); 2284 2285 ImageLength = AifHdr.RoSize; 2286 2287 /* Validate checksum */ 2288 CkSumEnd = 2289 (uint32_t *)(bptr + ImageLength + 2290 sizeof (AIF_HDR)); 2291 if (emlxs_valid_cksum((uint32_t *)bptr, CkSumEnd)) { 2292 EMLXS_MSGF(EMLXS_CONTEXT, 2293 &emlxs_image_bad_msg, 2294 "Invalid checksum found."); 2295 2296 return (EMLXS_IMAGE_BAD); 2297 } 2298 2299 FileType = AifHdr.ZinitBr; 2300 switch (FileType) { 2301 case FILE_TYPE_AWC: 2302 image->awc.offset = 2303 (uint32_t)((uintptr_t)bptr - 2304 (uintptr_t)Buffer); 2305 image->awc.version = AifHdr.AVersion; 2306 image->awc.revcomp = 0; 2307 2308 id = (AifHdr.AVersion & 0x00ff0000) >> 16; 2309 type = emlxs_type_check( 2310 (AifHdr.AVersion & 0xff000000) >> 24); 2311 2312 /* Validate the file version */ 2313 if ((rval = emlxs_validate_version(hba, 2314 &image->awc, id, type, "AWC file"))) { 2315 return (rval); 2316 } 2317 2318 break; 2319 2320 case FILE_TYPE_BWC: 2321 image->bwc.offset = 2322 (uint32_t)((uintptr_t)bptr - 2323 (uintptr_t)Buffer); 2324 image->bwc.version = AifHdr.AVersion; 2325 image->bwc.revcomp = 0; 2326 2327 id = (AifHdr.AVersion & 0x00ff0000) >> 16; 2328 type = emlxs_type_check( 2329 (AifHdr.AVersion & 0xff000000) >> 24); 2330 2331 /* Validate the file version */ 2332 if ((rval = emlxs_validate_version(hba, 2333 &image->bwc, id, type, "BWC file"))) { 2334 return (rval); 2335 } 2336 2337 break; 2338 2339 case FILE_TYPE_DWC: 2340 image->dwc.offset = 2341 (uint32_t)((uintptr_t)bptr - 2342 (uintptr_t)Buffer); 2343 image->dwc.version = AifHdr.AVersion; 2344 image->dwc.revcomp = 0; 2345 2346 id = (AifHdr.AVersion & 0x00ff0000) >> 16; 2347 type = emlxs_type_check( 2348 (AifHdr.AVersion & 0xff000000) >> 24); 2349 2350 /* Validate the file version */ 2351 if ((rval = emlxs_validate_version(hba, 2352 &image->dwc, id, type, "DWC file"))) { 2353 return (rval); 2354 } 2355 2356 /* Scan for program types */ 2357 NextImage = sizeof (AIF_HDR) + 4; 2358 BufferSize = AifHdr.RoSize + AifHdr.RwSize; 2359 2360 while (BufferSize > NextImage) { 2361 bcopy(&bptr[NextImage], &ImageHdr, 2362 sizeof (IMAGE_HDR)); 2363 emlxs_dump_image_header(hba, 2364 &ImageHdr); 2365 2366 /* Validate block size */ 2367 if (ImageHdr.BlockSize == 0xffffffff) { 2368 break; 2369 } 2370 2371 type = emlxs_type_check( 2372 ImageHdr.Id.Type); 2373 2374 /* Calculate the program offset */ 2375 image->prog[type].offset = 2376 (uint32_t)((uintptr_t) 2377 &bptr[NextImage] - 2378 (uintptr_t)Buffer); 2379 2380 /* Acquire the versions */ 2381 image->prog[type].version = 2382 (ImageHdr.Id.Type << 24) | 2383 (ImageHdr.Id.Id << 16) | 2384 (ImageHdr.Id.Ver << 8) | 2385 ImageHdr.Id.Rev; 2386 2387 image->prog[type].revcomp = 2388 ImageHdr.Id.un.revcomp; 2389 2390 /* Validate the file version */ 2391 if ((rval = emlxs_validate_version(hba, 2392 &image->prog[type], ImageHdr.Id.Id, 2393 type, "DWC prog"))) { 2394 return (rval); 2395 } 2396 2397 NextImage += ImageHdr.BlockSize; 2398 2399 } /* while() */ 2400 2401 break; 2402 } 2403 2404 FileLen = 2405 sizeof (AIF_HDR) + ImageLength + 2406 sizeof (uint32_t); 2407 TotalLen += FileLen; 2408 bptr += FileLen; 2409 } 2410 } 2411 2412 /* Pre-pegasus adapters */ 2413 2414 else if (ImageType == NOP_IMAGE_TYPE) { 2415 if (Size < sizeof (AIF_HDR)) { 2416 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2417 "Invalid image header length: 0x%x < 0x%x", Size, 2418 sizeof (AIF_HDR)); 2419 2420 return (EMLXS_IMAGE_BAD); 2421 } 2422 2423 bcopy(Buffer, &AifHdr, sizeof (AIF_HDR)); 2424 emlxs_disp_aif_header(hba, &AifHdr); 2425 2426 ImageLength = AifHdr.RoSize + AifHdr.RwSize; 2427 2428 if (Size != (sizeof (AIF_HDR) + ImageLength + sizeof (int))) { 2429 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2430 "Image length incorrect: 0x%x != 0x%x", Size, 2431 sizeof (AIF_HDR) + ImageLength + 2432 sizeof (uint32_t)); 2433 2434 return (EMLXS_IMAGE_BAD); 2435 } 2436 2437 if (AifHdr.ImageBase && AifHdr.ImageBase != 0x20000) { 2438 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2439 "Invalid imageBase value %x != 0x20000", 2440 AifHdr.ImageBase); 2441 2442 return (EMLXS_IMAGE_BAD); 2443 } 2444 2445 CkSumEnd = 2446 (uint32_t *)(Buffer + ImageLength + sizeof (AIF_HDR)); 2447 if (emlxs_valid_cksum((uint32_t *)Buffer, CkSumEnd)) { 2448 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2449 "Invalid checksum found."); 2450 2451 return (EMLXS_IMAGE_BAD); 2452 } 2453 2454 image->dwc.offset = 0; 2455 image->dwc.version = AifHdr.AVersion; 2456 image->dwc.revcomp = 0; 2457 2458 id = (AifHdr.AVersion & 0x00ff0000) >> 16; 2459 type = emlxs_type_check((AifHdr.AVersion & 0xff000000) >> 24); 2460 2461 /* Validate the file version */ 2462 if ((rval = emlxs_validate_version(hba, &image->dwc, id, type, 2463 "DWC file"))) { 2464 return (rval); 2465 } 2466 2467 NextImage = SLI_IMAGE_START - AifHdr.ImageBase; 2468 while (Size > NextImage) { 2469 bcopy(&Buffer[NextImage], &ImageHdr, 2470 sizeof (IMAGE_HDR)); 2471 emlxs_dump_image_header(hba, &ImageHdr); 2472 2473 /* Validate block size */ 2474 if (ImageHdr.BlockSize == 0xffffffff) { 2475 break; 2476 } 2477 2478 type = emlxs_type_check(ImageHdr.Id.Type); 2479 2480 /* Calculate the program offset */ 2481 image->prog[type].offset = NextImage; 2482 2483 /* Acquire the versions */ 2484 image->prog[type].version = 2485 (ImageHdr.Id.Type << 24) | 2486 (ImageHdr.Id.Id << 16) | 2487 (ImageHdr.Id.Ver << 8) | 2488 ImageHdr.Id.Rev; 2489 2490 image->prog[type].revcomp = ImageHdr.Id.un.revcomp; 2491 2492 /* Validate the file version */ 2493 if ((rval = emlxs_validate_version(hba, 2494 &image->prog[type], ImageHdr.Id.Id, type, 2495 "DWC prog"))) { 2496 return (rval); 2497 } 2498 2499 NextImage += ImageHdr.BlockSize; 2500 } 2501 } else { 2502 /* Precheck image size */ 2503 if (Size < sizeof (IMAGE_HDR)) { 2504 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2505 "Invalid image header length: 0x%x < 0x%x", Size, 2506 sizeof (IMAGE_HDR)); 2507 2508 return (EMLXS_IMAGE_BAD); 2509 } 2510 2511 bcopy(Buffer, &ImageHdr, sizeof (IMAGE_HDR)); 2512 emlxs_dump_image_header(hba, &ImageHdr); 2513 2514 /* Validate block size */ 2515 if (ImageHdr.BlockSize == 0xffffffff) { 2516 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2517 "Invalid block size."); 2518 2519 return (EMLXS_IMAGE_BAD); 2520 } 2521 2522 ImageLength = ImageHdr.BlockSize; 2523 2524 /* Validate image length */ 2525 if (Size != ImageLength) { 2526 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2527 "Invalid image length: 0x%x != 0x%x", Size, 2528 ImageLength); 2529 2530 return (EMLXS_IMAGE_BAD); 2531 } 2532 2533 /* Validate Checksum */ 2534 CkSumEnd = 2535 (uint32_t *)Buffer + (ImageLength / sizeof (uint32_t)) - 2536 1; 2537 if (emlxs_valid_cksum((uint32_t *)Buffer, CkSumEnd)) { 2538 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2539 "Invalid checksum found."); 2540 2541 return (EMLXS_IMAGE_BAD); 2542 } 2543 2544 type = emlxs_type_check(ImageHdr.Id.Type); 2545 2546 /* Calculate the program offset */ 2547 image->prog[type].offset = 0; 2548 2549 /* Acquire the versions */ 2550 image->prog[type].version = 2551 (ImageHdr.Id.Type << 24) | (ImageHdr.Id. 2552 Id << 16) | (ImageHdr.Id.Ver << 8) | ImageHdr.Id.Rev; 2553 2554 image->prog[type].revcomp = ImageHdr.Id.un.revcomp; 2555 2556 /* Validate the file version */ 2557 if ((rval = emlxs_validate_version(hba, &image->prog[type], 2558 ImageHdr.Id.Id, type, "DWC file"))) { 2559 return (rval); 2560 } 2561 } 2562 2563 /* 2564 * This checks if a DragonFly (pre-V2 ASIC) SLI2 2565 * image file is greater than version 3.8 2566 */ 2567 if (FC_JEDEC_ID(vpd->biuRev) == DRAGONFLY_JEDEC_ID) { 2568 if (image->prog[SLI2_OVERLAY].version != 0) { 2569 ver = (image->prog[SLI2_OVERLAY].version & 2570 0x0000ff00) >> 8; 2571 2572 if ((((ver & 0xf0) == 0x30) && 2573 ((ver & 0x0f) >= 0x08)) || 2574 ((ver & 0xf0) > 0x30)) { 2575 EMLXS_MSGF(EMLXS_CONTEXT, 2576 &emlxs_image_incompat_msg, 2577 "ASIC Check: Image requires DragonFly " 2578 "V2 ASIC"); 2579 2580 return (EMLXS_IMAGE_INCOMPATIBLE); 2581 } 2582 } 2583 } 2584 2585 return (0); 2586 2587 } /* emlxs_validate_image() */ 2588 2589 2590 static uint32_t 2591 emlxs_update_exp_rom(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms) 2592 { 2593 emlxs_port_t *port = &PPORT; 2594 MAILBOXQ *mbox; 2595 MAILBOX *mb; 2596 uint32_t next_address; 2597 uint32_t rval = 0; 2598 2599 if (WakeUpParms->u1.EROM_prog_wd[0] == 0) { 2600 return (1); 2601 } 2602 2603 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2604 KM_NOSLEEP)) == NULL) { 2605 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2606 "Unable to allocate mailbox buffer."); 2607 2608 return (1); 2609 } 2610 2611 bzero(mbox, sizeof (MAILBOXQ)); 2612 2613 mb = (MAILBOX *)mbox; 2614 mb->mbxCommand = MBX_LOAD_EXP_ROM; 2615 mb->un.varLdExpRom.step = EROM_CMD_FIND_IMAGE; 2616 mb->un.varLdExpRom.progress = 0; 2617 mb->un.varLdExpRom.un.prog_id = WakeUpParms->u1.EROM_prog_id; 2618 2619 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 2620 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2621 "Unable to load exp ROM. Mailbox cmd=%x status=%x", 2622 mb->mbxCommand, mb->mbxStatus); 2623 2624 rval = 1; 2625 2626 goto SLI_DOWNLOAD_EXIT; 2627 } 2628 2629 if (mb->un.varLdExpRom.progress == EROM_RSP_COPY_DONE) { 2630 (void) emlxs_update_wakeup_parms(hba, WakeUpParms, WakeUpParms); 2631 2632 rval = 1; 2633 goto SLI_DOWNLOAD_EXIT; 2634 } 2635 2636 if (mb->un.varLdExpRom.progress != EROM_RSP_ERASE_STARTED) { 2637 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2638 "Invalid exp ROM progress. progress=%x", 2639 mb->un.varLdExpRom.progress); 2640 2641 rval = 1; 2642 2643 goto SLI_DOWNLOAD_EXIT; 2644 } 2645 2646 /* 2647 * continue Erase 2648 */ 2649 while (mb->un.varLdExpRom.progress != EROM_RSP_ERASE_COMPLETE) { 2650 2651 next_address = mb->un.varLdExpRom.dl_to_adr; 2652 2653 bzero((void *)mb, MAILBOX_CMD_BSIZE); 2654 2655 mb->mbxCommand = MBX_LOAD_EXP_ROM; 2656 mb->un.varLdExpRom.step = EROM_CMD_CONTINUE_ERASE; 2657 mb->un.varLdExpRom.dl_to_adr = next_address; 2658 mb->un.varLdExpRom.progress = 0; 2659 mb->un.varLdExpRom.un.prog_id = WakeUpParms->u1.EROM_prog_id; 2660 2661 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 2662 MBX_SUCCESS) { 2663 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2664 "Unable to load exp ROM. Mailbox cmd=%x status=%x", 2665 mb->mbxCommand, mb->mbxStatus); 2666 2667 rval = 1; 2668 goto SLI_DOWNLOAD_EXIT; 2669 } 2670 2671 } 2672 2673 while (mb->un.varLdExpRom.progress != EROM_RSP_COPY_DONE) { 2674 next_address = mb->un.varLdExpRom.dl_to_adr; 2675 2676 bzero((void *)mb, MAILBOX_CMD_BSIZE); 2677 2678 mb->mbxCommand = MBX_LOAD_EXP_ROM; 2679 mb->un.varLdExpRom.step = EROM_CMD_COPY; 2680 mb->un.varLdExpRom.dl_to_adr = next_address; 2681 mb->un.varLdExpRom.progress = 0; 2682 mb->un.varLdExpRom.un.prog_id = WakeUpParms->u1.EROM_prog_id; 2683 2684 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 2685 MBX_SUCCESS) { 2686 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2687 "Unable to load exp ROM. Mailbox cmd=%x status=%x", 2688 mb->mbxCommand, mb->mbxStatus); 2689 2690 rval = 1; 2691 2692 goto SLI_DOWNLOAD_EXIT; 2693 } 2694 } 2695 2696 rval = emlxs_update_wakeup_parms(hba, WakeUpParms, WakeUpParms); 2697 2698 SLI_DOWNLOAD_EXIT: 2699 2700 if (mbox) { 2701 kmem_free(mbox, sizeof (MAILBOXQ)); 2702 } 2703 2704 return (rval); 2705 2706 } /* emlxs_update_exp_rom() */ 2707 2708 2709 /* 2710 * 2711 * FUNCTION NAME: emlxs_start_abs_download_2mb 2712 * 2713 * DESCRIPTION: Perform absolute download for 2 MB flash. A incoming 2714 * buffer may consist of more than 1 file. This function 2715 * will parse the buffer to find all the files. 2716 * 2717 * 2718 * PARAMETERS: 2719 * 2720 * 2721 * RETURNS: 2722 * 2723 */ 2724 /* ARGSUSED */ 2725 static uint32_t 2726 emlxs_start_abs_download_2mb(emlxs_hba_t *hba, caddr_t buffer, uint32_t len, 2727 uint32_t offline, emlxs_fw_image_t *fw_image) 2728 { 2729 emlxs_port_t *port = &PPORT; 2730 caddr_t AwcBuffer = NULL; 2731 caddr_t BwcBuffer = NULL; 2732 caddr_t DwcBuffer = NULL; 2733 AIF_HDR *AwcAifHdr; 2734 AIF_HDR *BwcAifHdr; 2735 AIF_HDR *DwcAifHdr; 2736 uint32_t BWCflag; 2737 emlxs_vpd_t *vpd; 2738 uint32_t i; 2739 uint32_t count; 2740 uint32_t extType = 0; 2741 uint32_t rval = 0; 2742 2743 vpd = &VPD; 2744 2745 /* Check for AWC file */ 2746 if (fw_image->awc.version) { 2747 AwcBuffer = buffer + fw_image->awc.offset; 2748 AwcAifHdr = (AIF_HDR *)AwcBuffer; 2749 } 2750 2751 /* Check for BWC file */ 2752 if (fw_image->bwc.version) { 2753 extType = BWCext; 2754 BwcBuffer = buffer + fw_image->bwc.offset; 2755 BwcAifHdr = (AIF_HDR *)BwcBuffer; 2756 } 2757 2758 /* Check for DWC file */ 2759 if (fw_image->dwc.version) { 2760 extType = DWCext; 2761 DwcBuffer = buffer + fw_image->dwc.offset; 2762 DwcAifHdr = (AIF_HDR *)DwcBuffer; 2763 } 2764 2765 /* Check for program files */ 2766 count = 0; 2767 for (i = 0; i < MAX_PROG_TYPES; i++) { 2768 if (fw_image->prog[i].version) { 2769 count++; 2770 } 2771 } 2772 2773 if (count > 1) { 2774 extType = ALLext; 2775 2776 if (fw_image->bwc.version) { 2777 BWCflag = ALL_WITH_BWC; 2778 } else { 2779 BWCflag = ALL_WITHOUT_BWC; 2780 } 2781 } else { 2782 BWCflag = NO_ALL; 2783 } 2784 2785 /* If nothing to download then quit now */ 2786 if (!AwcBuffer && !DwcBuffer && !BwcBuffer) { 2787 return (0); 2788 } 2789 2790 /* 2791 * Everything checks out, now to just do it 2792 */ 2793 if (offline) { 2794 if (emlxs_offline(hba) != FC_SUCCESS) { 2795 return (EMLXS_OFFLINE_FAILED); 2796 } 2797 2798 if (emlxs_sli_hba_reset(hba, 1, 1) != FC_SUCCESS) { 2799 return (EMLXS_OFFLINE_FAILED); 2800 } 2801 } 2802 2803 if (AwcBuffer) { 2804 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2805 "AWC file: KERN: old=%s new=%s ", vpd->postKernName, 2806 fw_image->awc.label); 2807 2808 rval = emlxs_proc_abs_2mb(hba, 2809 AwcAifHdr, AwcBuffer, FILE_TYPE_AWC, BWCflag, extType); 2810 2811 if (rval) { 2812 goto SLI_DOWNLOAD_2MB_EXIT; 2813 } 2814 } 2815 2816 if (DwcBuffer) { 2817 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2818 "DWC file: TEST: new=%s ", 2819 fw_image->prog[TEST_PROGRAM].label); 2820 2821 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2822 "DWC file: STUB: old=%s new=%s ", vpd->opFwName, 2823 fw_image->prog[FUNC_FIRMWARE].label); 2824 2825 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2826 "DWC file: SLI1: old=%s new=%s ", vpd->sli1FwName, 2827 fw_image->prog[SLI1_OVERLAY].label); 2828 2829 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2830 "DWC file: SLI2: old=%s new=%s ", vpd->sli2FwName, 2831 fw_image->prog[SLI2_OVERLAY].label); 2832 2833 if (vpd->sli3FwRev || fw_image->prog[SLI3_OVERLAY].version) { 2834 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2835 "DWC file: SLI3: old=%s new=%s ", 2836 vpd->sli3FwName, 2837 fw_image->prog[SLI3_OVERLAY].label); 2838 } 2839 2840 if (vpd->sli4FwRev || fw_image->prog[SLI4_OVERLAY].version) { 2841 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2842 "DWC file: SLI4: old=%s new=%s ", 2843 vpd->sli4FwName, 2844 fw_image->prog[SLI4_OVERLAY].label); 2845 } 2846 2847 rval = emlxs_proc_abs_2mb(hba, 2848 DwcAifHdr, DwcBuffer, FILE_TYPE_DWC, BWCflag, extType); 2849 2850 if (rval) { 2851 goto SLI_DOWNLOAD_2MB_EXIT; 2852 } 2853 } 2854 2855 if (BwcBuffer) { 2856 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2857 "BWC file: BOOT: old=%s new=%s ", vpd->fcode_version, 2858 fw_image->bwc.label); 2859 2860 rval = emlxs_proc_abs_2mb(hba, 2861 BwcAifHdr, BwcBuffer, FILE_TYPE_BWC, BWCflag, extType); 2862 } 2863 2864 SLI_DOWNLOAD_2MB_EXIT: 2865 2866 if (offline) { 2867 (void) emlxs_online(hba); 2868 } 2869 2870 return (rval); 2871 2872 } /* emlxs_start_abs_download_2mb() */ 2873 2874 2875 /* 2876 * 2877 * FUNCTION NAME: emlxs_proc_abs_2mb 2878 * 2879 * DESCRIPTION: Given one of the 3 file types(awc/bwc/dwc), it will reset 2880 * the port and download the file with sliIssueMbCommand() 2881 * 2882 * 2883 * PARAMETERS: 2884 * 2885 * 2886 * RETURNS: 2887 * 2888 */ 2889 static uint32_t 2890 emlxs_proc_abs_2mb(emlxs_hba_t *hba, 2891 PAIF_HDR AifHdr, 2892 caddr_t EntireBuffer, 2893 uint32_t FileType, uint32_t BWCflag, uint32_t extType) 2894 { 2895 emlxs_port_t *port = &PPORT; 2896 caddr_t Buffer = NULL; 2897 caddr_t DataBuffer = NULL; 2898 uint32_t *Src; 2899 uint32_t *Dst; 2900 MAILBOXQ *mbox; 2901 MAILBOX *mb; 2902 uint32_t DlByteCount = AifHdr->RoSize + AifHdr->RwSize; 2903 uint32_t rval = 0; 2904 uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT; 2905 uint32_t DlToAddr = AifHdr->ImageBase; 2906 uint32_t DlCount; 2907 WAKE_UP_PARMS AbsWakeUpParms; 2908 uint32_t i; 2909 uint32_t NextAddr; 2910 uint32_t EraseByteCount; 2911 uint32_t AreaId; 2912 uint32_t RspProgress = 0; 2913 uint32_t numBootImage = 0; 2914 uint32_t ParamsChg = 0; 2915 uint32_t BufferSize; 2916 2917 if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT, 2918 KM_NOSLEEP)) == NULL) { 2919 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2920 "%x: Unable to allocate data buffer.", FileType); 2921 2922 return (EMLXS_IMAGE_FAILED); 2923 } 2924 2925 bzero(DataBuffer, sizeof (DL_SLIM_SEG_BYTE_COUNT)); 2926 2927 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2928 KM_NOSLEEP)) == NULL) { 2929 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2930 "%x: Unable to allocate mailbox buffer.", FileType); 2931 2932 kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 2933 2934 return (EMLXS_IMAGE_FAILED); 2935 } 2936 2937 mb = (MAILBOX *)mbox; 2938 2939 BufferSize = DlByteCount + sizeof (AIF_HDR) + sizeof (uint32_t); 2940 Buffer = EntireBuffer + sizeof (AIF_HDR); 2941 2942 switch (FileType) { 2943 case FILE_TYPE_AWC: 2944 break; 2945 2946 case FILE_TYPE_BWC: 2947 ParamsChg = emlxs_build_parms_2mb_bwc(hba, 2948 AifHdr, extType, &AbsWakeUpParms); 2949 2950 if (ParamsChg == FALSE) { 2951 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2952 "BWC build parms failed."); 2953 2954 rval = EMLXS_IMAGE_FAILED; 2955 2956 goto EXIT_ABS_DOWNLOAD; 2957 } 2958 break; 2959 2960 case FILE_TYPE_DWC: 2961 ParamsChg = emlxs_build_parms_2mb_dwc(hba, 2962 Buffer, 2963 BufferSize, 2964 AifHdr, &AbsWakeUpParms, BWCflag, extType, &numBootImage); 2965 2966 if (ParamsChg == FALSE) { 2967 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2968 "DWC build parms failed."); 2969 2970 rval = EMLXS_IMAGE_FAILED; 2971 2972 goto EXIT_ABS_DOWNLOAD; 2973 } 2974 break; 2975 2976 default: 2977 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2978 "Invalid file type: %x", FileType); 2979 2980 rval = EMLXS_IMAGE_BAD; 2981 2982 goto EXIT_ABS_DOWNLOAD; 2983 2984 } 2985 2986 EraseByteCount = AifHdr->Area_Size; 2987 AreaId = AifHdr->Area_ID; 2988 2989 emlxs_format_load_area_cmd(mb, 2990 DlToAddr, 2991 EraseByteCount, 2992 ERASE_FLASH, 2993 0, DL_FROM_SLIM_OFFSET, AreaId, MBX_LOAD_AREA, CMD_START_ERASE); 2994 2995 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 2996 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2997 "%x: Could not erase 2MB Flash: Mailbox cmd=%x status=%x", 2998 FileType, mb->mbxCommand, mb->mbxStatus); 2999 3000 rval = EMLXS_IMAGE_FAILED; 3001 3002 goto EXIT_ABS_DOWNLOAD; 3003 } 3004 3005 while (mb->un.varLdArea.progress != RSP_ERASE_COMPLETE) { 3006 NextAddr = mb->un.varLdArea.dl_to_adr; 3007 3008 emlxs_format_load_area_cmd(mb, 3009 NextAddr, 3010 EraseByteCount, 3011 ERASE_FLASH, 3012 0, 3013 DL_FROM_SLIM_OFFSET, 3014 AreaId, MBX_LOAD_AREA, CMD_CONTINUE_ERASE); 3015 3016 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 3017 MBX_SUCCESS) { 3018 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3019 "%x: Could not erase 2MB Flash2: Mailbox cmd=%x " 3020 "status=%x", FileType, mb->mbxCommand, 3021 mb->mbxStatus); 3022 3023 rval = EMLXS_IMAGE_FAILED; 3024 3025 goto EXIT_ABS_DOWNLOAD; 3026 } 3027 } 3028 3029 while (DlByteCount) { 3030 if (DlByteCount >= SegSize) 3031 DlCount = SegSize; 3032 else 3033 DlCount = DlByteCount; 3034 3035 DlByteCount -= DlCount; 3036 3037 Dst = (uint32_t *)DataBuffer; 3038 Src = (uint32_t *)Buffer; 3039 3040 for (i = 0; i < (DlCount / 4); i++) { 3041 *Dst = *Src; 3042 Dst++; 3043 Src++; 3044 } 3045 3046 WRITE_SLIM_COPY(hba, (uint32_t *)DataBuffer, 3047 (volatile uint32_t *)((volatile char *)hba->slim_addr + 3048 sizeof (MAILBOX)), (DlCount / sizeof (uint32_t))); 3049 3050 if ((RspProgress == RSP_DOWNLOAD_MORE) || (RspProgress == 0)) { 3051 emlxs_format_load_area_cmd(mb, 3052 DlToAddr, 3053 DlCount, 3054 PROGRAM_FLASH, 3055 (DlByteCount) ? 0 : 1, 3056 DL_FROM_SLIM_OFFSET, 3057 AreaId, 3058 MBX_LOAD_AREA, 3059 (DlByteCount) ? CMD_DOWNLOAD : CMD_END_DOWNLOAD); 3060 3061 if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 3062 MBX_SUCCESS) { 3063 EMLXS_MSGF(EMLXS_CONTEXT, 3064 &emlxs_download_failed_msg, 3065 "%x: Could not program 2MB Flash: Mailbox " 3066 "cmd=%x status=%x", FileType, 3067 mb->mbxCommand, mb->mbxStatus); 3068 3069 rval = EMLXS_IMAGE_FAILED; 3070 3071 goto EXIT_ABS_DOWNLOAD; 3072 } 3073 } 3074 3075 RspProgress = mb->un.varLdArea.progress; 3076 3077 Buffer += DlCount; 3078 DlToAddr += DlCount; 3079 } 3080 3081 #ifdef FMA_SUPPORT 3082 if (emlxs_fm_check_acc_handle(hba, hba->slim_acc_handle) 3083 != DDI_FM_OK) { 3084 EMLXS_MSGF(EMLXS_CONTEXT, 3085 &emlxs_invalid_access_handle_msg, NULL); 3086 3087 rval = EMLXS_IMAGE_FAILED; 3088 3089 goto EXIT_ABS_DOWNLOAD; 3090 } 3091 #endif /* FMA_SUPPORT */ 3092 3093 if (RspProgress != RSP_DOWNLOAD_DONE) { 3094 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3095 "%x: Failed download response received. %x", FileType, 3096 RspProgress); 3097 3098 rval = EMLXS_IMAGE_FAILED; 3099 3100 goto EXIT_ABS_DOWNLOAD; 3101 } 3102 3103 if (ParamsChg) { 3104 if (emlxs_update_wakeup_parms(hba, &AbsWakeUpParms, 3105 &AbsWakeUpParms)) { 3106 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3107 "%x: Unable to update parms.", FileType); 3108 3109 rval = EMLXS_IMAGE_FAILED; 3110 } 3111 } 3112 3113 EXIT_ABS_DOWNLOAD: 3114 3115 if (DataBuffer) { 3116 kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 3117 } 3118 3119 if (mbox) { 3120 kmem_free(mbox, sizeof (MAILBOXQ)); 3121 } 3122 3123 return (rval); 3124 3125 } /* emlxs_proc_abs_2mb() */ 3126 3127 3128 static void 3129 emlxs_format_load_area_cmd(MAILBOX * mb, 3130 uint32_t Base, 3131 uint32_t DlByteCount, 3132 uint32_t Function, 3133 uint32_t Complete, 3134 uint32_t DataOffset, uint32_t AreaId, uint8_t MbxCmd, uint32_t StepCmd) 3135 { 3136 bzero((void *)mb, MAILBOX_CMD_BSIZE); 3137 3138 mb->mbxCommand = MbxCmd; 3139 mb->mbxOwner = OWN_HOST; 3140 mb->un.varLdArea.update_flash = 1; 3141 mb->un.varLdArea.erase_or_prog = Function; 3142 mb->un.varLdArea.dl_to_adr = Base; 3143 mb->un.varLdArea.dl_len = DlByteCount; 3144 mb->un.varLdArea.load_cmplt = Complete; 3145 mb->un.varLdArea.method = DL_FROM_SLIM; 3146 mb->un.varLdArea.area_id = AreaId; 3147 mb->un.varLdArea.step = StepCmd; 3148 mb->un.varLdArea.un.dl_from_slim_offset = DataOffset; 3149 3150 } /* emlxs_format_load_area_cmd() */ 3151 3152 3153 /* ARGSUSED */ 3154 static uint32_t 3155 emlxs_build_parms_2mb_bwc(emlxs_hba_t *hba, 3156 PAIF_HDR AifHdr, uint32_t extType, PWAKE_UP_PARMS AbsWakeUpParms) 3157 { 3158 emlxs_port_t *port = &PPORT; 3159 uint32_t pId[2]; 3160 uint32_t returnStat; 3161 3162 /* Read wakeup paramters */ 3163 if (emlxs_read_wakeup_parms(hba, AbsWakeUpParms, 0) == 3164 CFG_DATA_NO_REGION) { 3165 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3166 "Unable to get BWC parameters."); 3167 return (FALSE); 3168 } 3169 3170 pId[0] = AifHdr->AVersion; 3171 pId[1] = 0; 3172 3173 if (extType == BWCext) { 3174 AbsWakeUpParms->u0.boot_bios_wd[0] = pId[0]; 3175 AbsWakeUpParms->u0.boot_bios_wd[1] = pId[1]; 3176 AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 3177 AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 3178 } 3179 3180 else if (extType == ALLext) { 3181 if (!AbsWakeUpParms->u0.boot_bios_wd[0]) { 3182 /* case of EROM inactive */ 3183 AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 3184 AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 3185 } else { 3186 /* case of EROM active */ 3187 if (AbsWakeUpParms->u0.boot_bios_wd[0] == pId[0]) { 3188 /* same ID */ 3189 AbsWakeUpParms->u0.boot_bios_wd[0] = pId[0]; 3190 AbsWakeUpParms->u0.boot_bios_wd[1] = pId[1]; 3191 AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 3192 AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 3193 } else { 3194 /* different ID */ 3195 AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 3196 AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 3197 3198 returnStat = 3199 emlxs_update_exp_rom(hba, AbsWakeUpParms); 3200 3201 if (returnStat) { 3202 AbsWakeUpParms->u0.boot_bios_wd[0] = 3203 pId[0]; 3204 AbsWakeUpParms->u0.boot_bios_wd[1] = 3205 pId[1]; 3206 } 3207 } 3208 } 3209 } 3210 3211 return (TRUE); 3212 3213 } /* emlxs_build_parms_2mb_bwc() */ 3214 3215 3216 /* ARGSUSED */ 3217 static uint32_t 3218 emlxs_build_parms_2mb_dwc(emlxs_hba_t *hba, 3219 caddr_t Buffer, 3220 uint32_t BufferSize, 3221 PAIF_HDR AifHeader, 3222 PWAKE_UP_PARMS AbsWakeUpParms, 3223 uint32_t BWCflag, uint32_t extType, uint32_t *numBootImage) 3224 { 3225 emlxs_port_t *port = &PPORT; 3226 uint32_t NextImage; 3227 uint32_t i; 3228 IMAGE_HDR ImageHdr; 3229 uint32_t *ptr1; 3230 uint32_t *ptr2; 3231 PROG_ID BootId[MAX_BOOTID]; 3232 uint32_t ChangeParams = FALSE; 3233 WAKE_UP_PARMS WakeUpParms; 3234 caddr_t Sptr; 3235 caddr_t Dptr; 3236 3237 bzero(&BootId, (sizeof (PROG_ID)) * MAX_BOOTID); 3238 3239 /* Read wakeup paramters */ 3240 if (emlxs_read_wakeup_parms(hba, AbsWakeUpParms, 0) == 3241 CFG_DATA_NO_REGION) { 3242 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3243 "Unable to get DWC parameters."); 3244 return (FALSE); 3245 } 3246 3247 bcopy((caddr_t)AbsWakeUpParms, (caddr_t)&WakeUpParms, 3248 sizeof (WAKE_UP_PARMS)); 3249 3250 if (((BWCflag == ALL_WITHOUT_BWC) || (extType == DWCext)) && 3251 (WakeUpParms.u0.boot_bios_wd[0])) { 3252 *numBootImage = 0; 3253 } 3254 3255 /* incoming buffer is without aif header */ 3256 NextImage = 0x84 - sizeof (AIF_HDR); 3257 BufferSize -= (sizeof (AIF_HDR) + sizeof (uint32_t)); 3258 3259 while (BufferSize > NextImage) { 3260 Sptr = &Buffer[NextImage]; 3261 Dptr = (caddr_t)&ImageHdr; 3262 for (i = 0; i < sizeof (IMAGE_HDR); i++) { 3263 Dptr[i] = Sptr[i]; 3264 } 3265 3266 if (ImageHdr.BlockSize == 0xffffffff) { 3267 break; 3268 } 3269 3270 switch (ImageHdr.Id.Type) { 3271 case TEST_PROGRAM: 3272 break; 3273 3274 case FUNC_FIRMWARE: 3275 AbsWakeUpParms->prog_id = ImageHdr.Id; 3276 ChangeParams = TRUE; 3277 break; 3278 3279 case BOOT_BIOS: 3280 if (!WakeUpParms.u0.boot_bios_wd[0]) { 3281 if (extType == DWCext) { 3282 break; 3283 } else if (BWCflag == ALL_WITHOUT_BWC) { 3284 /* for possible future changes */ 3285 break; 3286 } 3287 } 3288 ChangeParams = TRUE; 3289 3290 if (*numBootImage < MAX_BOOTID) { 3291 BootId[*numBootImage] = ImageHdr.Id; 3292 (*numBootImage)++; 3293 } 3294 break; 3295 3296 case SLI1_OVERLAY: 3297 AbsWakeUpParms->sli1_prog_id = ImageHdr.Id; 3298 ChangeParams = TRUE; 3299 break; 3300 3301 case SLI2_OVERLAY: 3302 AbsWakeUpParms->sli2_prog_id = ImageHdr.Id; 3303 ChangeParams = TRUE; 3304 break; 3305 3306 case SLI3_OVERLAY: 3307 AbsWakeUpParms->sli3_prog_id = ImageHdr.Id; 3308 ChangeParams = TRUE; 3309 break; 3310 3311 case SLI4_OVERLAY: 3312 AbsWakeUpParms->sli4_prog_id = ImageHdr.Id; 3313 ChangeParams = TRUE; 3314 break; 3315 } 3316 3317 NextImage += ImageHdr.BlockSize; 3318 } 3319 3320 if ((ChangeParams) && ((BWCflag == ALL_WITHOUT_BWC) || 3321 (extType == DWCext))) { 3322 3323 if (*numBootImage > 1) { 3324 for (i = 0; i < *numBootImage; i++) { 3325 ptr1 = 3326 (uint32_t *)&WakeUpParms.u0. 3327 boot_bios_id; 3328 ptr2 = (uint32_t *)&BootId[i]; 3329 3330 if (ptr1[0] == ptr2[0]) { 3331 AbsWakeUpParms->u1.EROM_prog_id = 3332 BootId[i]; 3333 (void) emlxs_update_exp_rom(hba, 3334 AbsWakeUpParms); 3335 break; 3336 } 3337 } 3338 } else { 3339 if (*numBootImage == 1) { 3340 ptr2 = (uint32_t *)&BootId[0]; 3341 3342 if (WakeUpParms.u0.boot_bios_wd[0] == ptr2[0]) { 3343 AbsWakeUpParms->u1.EROM_prog_id = 3344 BootId[0]; 3345 (void) emlxs_update_exp_rom(hba, 3346 AbsWakeUpParms); 3347 } 3348 } 3349 } 3350 } 3351 3352 return (ChangeParams); 3353 3354 3355 } /* emlxs_build_parms_2mb_dwc() */ 3356 3357 3358 extern uint32_t 3359 emlxs_get_max_sram(emlxs_hba_t *hba, uint32_t *MaxRbusSize, 3360 uint32_t *MaxIbusSize) 3361 { 3362 emlxs_port_t *port = &PPORT; 3363 MAILBOXQ *mbox; 3364 MAILBOX *mb; 3365 uint32_t *Uptr; 3366 uint32_t rval = 0; 3367 3368 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 3369 KM_NOSLEEP)) == NULL) { 3370 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3371 "Unable to allocate mailbox buffer."); 3372 3373 return (1); 3374 } 3375 3376 mb = (MAILBOX *)mbox; 3377 3378 emlxs_format_dump(mb, DMP_MEM_REG, 0, 2, MAX_RBUS_SRAM_SIZE_ADR); 3379 3380 if ((rval = emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0)) != 3381 MBX_SUCCESS) { 3382 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3383 "Unable to get SRAM size: Mailbox cmd=%x status=%x", 3384 mb->mbxCommand, mb->mbxStatus); 3385 3386 rval = 1; 3387 3388 goto Exit_Function; 3389 } 3390 3391 Uptr = (uint32_t *)&mb->un.varDmp.resp_offset; 3392 3393 *MaxRbusSize = Uptr[0]; 3394 *MaxIbusSize = Uptr[1]; 3395 3396 Exit_Function: 3397 3398 if (mbox) { 3399 kmem_free(mbox, sizeof (MAILBOXQ)); 3400 } 3401 3402 return (rval); 3403 3404 } /* emlxs_get_max_sram() */ 3405 3406 3407 static uint32_t 3408 emlxs_kern_check(emlxs_hba_t *hba, uint32_t version) 3409 { 3410 uint8_t *ptr; 3411 uint8_t ver; 3412 3413 ver = version & 0xff; 3414 ptr = hba->model_info.pt_FF; 3415 3416 while (*ptr) { 3417 if (*ptr++ == ver) { 3418 return (1); 3419 } 3420 } 3421 3422 return (0); 3423 3424 } /* emlxs_kern_check() */ 3425 3426 static uint32_t 3427 emlxs_stub_check(emlxs_hba_t *hba, uint32_t version) 3428 { 3429 uint8_t *ptr; 3430 uint8_t ver; 3431 3432 ver = version & 0xff; 3433 ptr = hba->model_info.pt_2; 3434 3435 while (*ptr) { 3436 if (*ptr++ == ver) { 3437 return (1); 3438 } 3439 } 3440 3441 return (0); 3442 3443 } /* emlxs_stub_check() */ 3444 3445 static uint32_t 3446 emlxs_bios_check(emlxs_hba_t *hba, uint32_t version) 3447 { 3448 uint8_t *ptr; 3449 uint8_t ver; 3450 3451 ver = version & 0xff; 3452 ptr = hba->model_info.pt_3; 3453 3454 while (*ptr) { 3455 if (*ptr++ == ver) { 3456 return (1); 3457 } 3458 } 3459 3460 return (0); 3461 3462 } /* emlxs_bios_check() */ 3463 3464 static uint32_t 3465 emlxs_sli1_check(emlxs_hba_t *hba, uint32_t version) 3466 { 3467 uint8_t *ptr; 3468 uint8_t ver; 3469 3470 ver = version & 0xff; 3471 ptr = hba->model_info.pt_6; 3472 3473 while (*ptr) { 3474 if (*ptr++ == ver) { 3475 return (1); 3476 } 3477 } 3478 3479 return (0); 3480 3481 } /* emlxs_sli1_check() */ 3482 3483 static uint32_t 3484 emlxs_sli2_check(emlxs_hba_t *hba, uint32_t version) 3485 { 3486 uint8_t *ptr; 3487 uint8_t ver; 3488 3489 ver = version & 0xff; 3490 ptr = hba->model_info.pt_7; 3491 3492 while (*ptr) { 3493 if (*ptr++ == ver) { 3494 return (1); 3495 } 3496 } 3497 3498 return (0); 3499 3500 } /* emlxs_sli2_check() */ 3501 3502 static uint32_t 3503 emlxs_sli3_check(emlxs_hba_t *hba, uint32_t version) 3504 { 3505 uint8_t *ptr; 3506 uint8_t ver; 3507 3508 ver = version & 0xff; 3509 ptr = hba->model_info.pt_B; 3510 3511 while (*ptr) { 3512 if (*ptr++ == ver) { 3513 return (1); 3514 } 3515 } 3516 3517 return (0); 3518 3519 } /* emlxs_sli3_check() */ 3520 3521 3522 static uint32_t 3523 emlxs_sli4_check(emlxs_hba_t *hba, uint32_t version) 3524 { 3525 uint8_t *ptr; 3526 uint8_t ver; 3527 3528 ver = version & 0xff; 3529 ptr = hba->model_info.pt_E; 3530 3531 while (*ptr) { 3532 if (*ptr++ == ver) { 3533 return (1); 3534 } 3535 } 3536 3537 return (0); 3538 3539 } /* emlxs_sli4_check() */ 3540 3541 3542 static uint32_t 3543 emlxs_sbus_fcode_check(emlxs_hba_t *hba, uint32_t version) 3544 { 3545 uint8_t *ptr; 3546 uint8_t ver; 3547 3548 ver = version & 0xff; 3549 ptr = hba->model_info.pt_A; 3550 3551 while (*ptr) { 3552 if (*ptr++ == ver) { 3553 return (1); 3554 } 3555 } 3556 3557 return (0); 3558 3559 } /* emlxs_sbus_fcode_check() */ 3560 3561 static uint32_t 3562 emlxs_type_check(uint32_t type) 3563 { 3564 if (type == 0xff) { 3565 return (KERNEL_CODE); 3566 } 3567 3568 if (type >= MAX_PROG_TYPES) { 3569 return (RESERVED_D); 3570 } 3571 3572 return (type); 3573 3574 } /* emlxs_type_check() */ 3575 3576 3577 3578 extern int32_t 3579 emlxs_boot_code_disable(emlxs_hba_t *hba) 3580 { 3581 emlxs_port_t *port = &PPORT; 3582 PROG_ID Id; 3583 emlxs_vpd_t *vpd; 3584 3585 vpd = &VPD; 3586 3587 if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 0)) { 3588 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, 3589 "emlxs_boot_code_disable: Unable to read wake up parms."); 3590 3591 return (FC_FAILURE); 3592 } 3593 3594 /* Check if boot code is already disabled */ 3595 if (hba->wakeup_parms.u0.boot_bios_wd[0] == 0) { 3596 return (FC_SUCCESS); 3597 } 3598 3599 /* Make sure EROM entry has copy of boot bios entry */ 3600 if (!(hba->model_info.chip & 3601 (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP)) && 3602 (hba->wakeup_parms.u0.boot_bios_wd[0] != 3603 hba->wakeup_parms.u1.EROM_prog_wd[0]) && 3604 (hba->wakeup_parms.u0.boot_bios_wd[1] != 3605 hba->wakeup_parms.u1.EROM_prog_wd[1])) { 3606 (void) emlxs_update_boot_wakeup_parms(hba, &hba->wakeup_parms, 3607 &hba->wakeup_parms.u0.boot_bios_id, 1); 3608 } 3609 3610 /* Update the bios id with a zero id */ 3611 /* Don't load the EROM this time */ 3612 bzero(&Id, sizeof (PROG_ID)); 3613 (void) emlxs_update_boot_wakeup_parms(hba, &hba->wakeup_parms, &Id, 0); 3614 3615 /* Now read the parms again to verify */ 3616 (void) emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1); 3617 emlxs_decode_version(hba->wakeup_parms.u0.boot_bios_wd[0], 3618 vpd->boot_version); 3619 /* (void) strcpy(vpd->fcode_version, vpd->boot_version); */ 3620 3621 /* Return the result */ 3622 return ((hba->wakeup_parms.u0.boot_bios_wd[0] == 0) ? 3623 FC_SUCCESS : FC_FAILURE); 3624 3625 } /* emlxs_boot_code_disable() */ 3626 3627 3628 extern int32_t 3629 emlxs_boot_code_enable(emlxs_hba_t *hba) 3630 { 3631 emlxs_port_t *port = &PPORT; 3632 emlxs_vpd_t *vpd; 3633 PROG_ID load_list[MAX_LOAD_ENTRY]; 3634 uint32_t i; 3635 3636 vpd = &VPD; 3637 3638 /* Read the wakeup parms */ 3639 if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 0)) { 3640 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, 3641 "emlxs_boot_code_enable: Unable to read wake up parms."); 3642 3643 return (FC_FAILURE); 3644 } 3645 3646 /* Check if boot code is already enabled */ 3647 if (hba->wakeup_parms.u0.boot_bios_id.Type == BOOT_BIOS) { 3648 return (FC_SUCCESS); 3649 } 3650 3651 if (!(hba->model_info.chip & 3652 (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 3653 if (hba->wakeup_parms.u1.EROM_prog_id.Type != BOOT_BIOS) { 3654 return (EMLXS_NO_BOOT_CODE); 3655 } 3656 3657 /* Update the parms with the boot image id */ 3658 /* Don't load the EROM this time */ 3659 (void) emlxs_update_boot_wakeup_parms(hba, &hba->wakeup_parms, 3660 &hba->wakeup_parms.u1.EROM_prog_id, 0); 3661 } else { /* (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP) */ 3662 3663 if (emlxs_get_load_list(hba, load_list)) { 3664 return (FC_FAILURE); 3665 } 3666 3667 /* Scan load list for a boot image */ 3668 for (i = 0; i < MAX_LOAD_ENTRY; i++) { 3669 if (load_list[i].Type == BOOT_BIOS) { 3670 /* Update the parms with the boot image id */ 3671 /* Don't load the EROM this time */ 3672 (void) emlxs_update_boot_wakeup_parms(hba, 3673 &hba->wakeup_parms, &load_list[i], 0); 3674 3675 break; 3676 } 3677 } 3678 3679 if (i == MAX_LOAD_ENTRY) { 3680 return (EMLXS_NO_BOOT_CODE); 3681 } 3682 } 3683 3684 /* Now read the parms again to verify */ 3685 (void) emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1); 3686 emlxs_decode_version(hba->wakeup_parms.u0.boot_bios_wd[0], 3687 vpd->boot_version); 3688 /* (void) strcpy(vpd->fcode_version, vpd->boot_version); */ 3689 3690 /* return the result */ 3691 return ((hba->wakeup_parms.u0.boot_bios_wd[0] != 0) ? 3692 FC_SUCCESS : FC_FAILURE); 3693 3694 } /* emlxs_boot_code_enable() */ 3695 3696 3697 3698 extern int32_t 3699 emlxs_boot_code_state(emlxs_hba_t *hba) 3700 { 3701 emlxs_port_t *port = &PPORT; 3702 3703 /* Read the wakeup parms */ 3704 if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1)) { 3705 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, 3706 "emlxs_boot_code_state: Unable to read wake up parms."); 3707 3708 return (FC_FAILURE); 3709 } 3710 3711 /* return the result */ 3712 return ((hba->wakeup_parms.u0.boot_bios_wd[0] != 0) ? 3713 FC_SUCCESS : FC_FAILURE); 3714 3715 } /* emlxs_boot_code_state() */ 3716