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