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