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