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.
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.
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]
23 * Copyright 2010 Emulex. All rights reserved.
24 * Use is subject to license terms.
30 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
31 EMLXS_MSG_DEF(EMLXS_DOWNLOAD_C
);
35 static uint32_t emlxs_erase_fcode_flash(emlxs_hba_t
*hba
);
37 static uint32_t emlxs_write_fcode_flash(emlxs_hba_t
*hba
,
38 PIMAGE_HDR ImageHdr
, caddr_t Buffer
);
40 static int32_t emlxs_build_parms(caddr_t Buffer
, PWAKE_UP_PARMS AbsWakeUpParms
,
41 uint32_t BufferSize
, PAIF_HDR AifHeader
);
42 static uint32_t emlxs_validate_image(emlxs_hba_t
*hba
, caddr_t Buffer
,
43 uint32_t Size
, emlxs_fw_image_t
*fw_image
);
44 static void emlxs_format_dump(emlxs_hba_t
*hba
, MAILBOXQ
*mbq
,
45 uint32_t Type
, uint32_t RegionId
, uint32_t WordCnt
,
47 static uint32_t emlxs_start_abs_download(emlxs_hba_t
*hba
, PAIF_HDR AifHdr
,
48 caddr_t Buffer
, uint32_t len
,
49 PWAKE_UP_PARMS WakeUpParms
);
50 static uint32_t emlxs_start_abs_download_2mb(emlxs_hba_t
*hba
, caddr_t buffer
,
51 uint32_t len
, uint32_t offline
,
52 emlxs_fw_image_t
*fw_image
);
53 static uint32_t emlxs_proc_abs_2mb(emlxs_hba_t
*hba
,
54 caddr_t EntireBuffer
, uint32_t FileType
,
56 static void emlxs_format_load_area_cmd(MAILBOXQ
*mbq
, uint32_t Base
,
57 uint32_t DlByteCount
, uint32_t Function
,
58 uint32_t Complete
, uint32_t DataOffset
, uint32_t AreaId
,
59 uint8_t MbxCmd
, uint32_t StepCmd
);
60 static uint32_t emlxs_build_parms_2mb_bwc(emlxs_hba_t
*hba
, PAIF_HDR AifHdr
,
61 uint32_t extType
, PWAKE_UP_PARMS AbsWakeUpParms
);
62 static uint32_t emlxs_update_exp_rom(emlxs_hba_t
*hba
,
63 PWAKE_UP_PARMS WakeUpParms
);
64 extern uint32_t emlxs_get_max_sram(emlxs_hba_t
*hba
, uint32_t *MaxRbusSize
,
65 uint32_t *MaxIbusSize
);
66 static void emlxs_format_prog_flash(MAILBOXQ
*mbq
, uint32_t Base
,
67 uint32_t DlByteCount
, uint32_t Function
,
68 uint32_t Complete
, uint32_t BdeAddress
,
69 uint32_t BdeSize
, PROG_ID
*ProgId
, uint32_t keep
);
70 static void emlxs_format_update_parms(MAILBOXQ
*mbq
,
71 PWAKE_UP_PARMS WakeUpParms
);
72 static void emlxs_format_update_pci_cfg(emlxs_hba_t
*hba
, MAILBOXQ
*mbq
,
73 uint32_t region_id
, uint32_t size
);
74 static uint32_t emlxs_update_wakeup_parms(emlxs_hba_t
*hba
,
75 PWAKE_UP_PARMS AbsWakeUpParms
,
76 PWAKE_UP_PARMS WakeUpParms
);
77 static uint32_t emlxs_update_boot_wakeup_parms(emlxs_hba_t
*hba
,
78 PWAKE_UP_PARMS WakeUpParms
, PROG_ID
*id
,
80 static uint32_t emlxs_update_ff_wakeup_parms(emlxs_hba_t
*hba
,
81 PWAKE_UP_PARMS WakeUpParms
, PROG_ID
*id
);
82 static uint32_t emlxs_update_sli1_wakeup_parms(emlxs_hba_t
*hba
,
83 PWAKE_UP_PARMS WakeUpParms
, PROG_ID
*id
);
84 static uint32_t emlxs_update_sli2_wakeup_parms(emlxs_hba_t
*hba
,
85 PWAKE_UP_PARMS WakeUpParms
, PROG_ID
*id
);
86 static uint32_t emlxs_update_sli3_wakeup_parms(emlxs_hba_t
*hba
,
87 PWAKE_UP_PARMS WakeUpParms
, PROG_ID
*id
);
88 static uint32_t emlxs_update_sli4_wakeup_parms(emlxs_hba_t
*hba
,
89 PWAKE_UP_PARMS WakeUpParms
, PROG_ID
*id
);
90 static uint32_t emlxs_start_rel_download(emlxs_hba_t
*hba
, PIMAGE_HDR ImageHdr
,
91 caddr_t Buffer
, PWAKE_UP_PARMS WakeUpParms
,
93 static uint32_t emlxs_read_load_list(emlxs_hba_t
*hba
, LOAD_LIST
*LoadList
);
95 static uint32_t emlxs_valid_cksum(uint32_t *StartAddr
, uint32_t *EndAddr
);
97 static void emlxs_disp_aif_header(emlxs_hba_t
*hba
, PAIF_HDR AifHdr
);
99 static void emlxs_dump_image_header(emlxs_hba_t
*hba
, PIMAGE_HDR image
);
102 static uint32_t emlxs_type_check(uint32_t type
);
104 static uint32_t emlxs_kern_check(emlxs_hba_t
*hba
, uint32_t version
);
106 static uint32_t emlxs_stub_check(emlxs_hba_t
*hba
, uint32_t version
);
108 static uint32_t emlxs_sli1_check(emlxs_hba_t
*hba
, uint32_t version
);
110 static uint32_t emlxs_sli2_check(emlxs_hba_t
*hba
, uint32_t version
);
112 static uint32_t emlxs_sli3_check(emlxs_hba_t
*hba
, uint32_t version
);
114 static uint32_t emlxs_sli4_check(emlxs_hba_t
*hba
, uint32_t version
);
116 static uint32_t emlxs_bios_check(emlxs_hba_t
*hba
, uint32_t version
);
118 static uint32_t emlxs_sbus_fcode_check(emlxs_hba_t
*hba
, uint32_t version
);
120 static uint32_t emlxs_validate_version(emlxs_hba_t
*hba
,
121 emlxs_fw_file_t
*file
, uint32_t id
, uint32_t type
,
123 static uint32_t emlxs_be2_validate_image(emlxs_hba_t
*hba
, caddr_t buffer
,
124 uint32_t len
, emlxs_be_fw_image_t
*fw_image
);
125 static uint32_t emlxs_be3_validate_image(emlxs_hba_t
*hba
, caddr_t buffer
,
126 uint32_t len
, emlxs_be_fw_image_t
*fw_image
);
129 static int32_t emlxs_sli4_verify_crc(emlxs_hba_t
*hba
,
130 emlxs_be_fw_file_t
*file
,
131 MAILBOXQ
*mbq
, MATCHMAP
*mp
);
132 static int32_t emlxs_sli4_flash_image(emlxs_hba_t
*hba
, caddr_t buffer
,
133 emlxs_be_fw_file_t
*file
, MAILBOXQ
*mbq
, MATCHMAP
*mp
);
134 static int32_t emlxs_sli4_fw_download(emlxs_hba_t
*hba
, caddr_t buffer
,
135 uint32_t len
, uint32_t offline
);
136 static uint32_t emlxs_be_version(caddr_t buffer
, uint32_t size
,
137 uint32_t *plus_flag
);
138 static uint32_t emlxs_proc_rel_2mb(emlxs_hba_t
*hba
, caddr_t buffer
,
139 emlxs_fw_image_t
*fw_image
);
140 static uint32_t emlxs_delete_load_entry(emlxs_hba_t
*hba
, PROG_ID
*progId
);
142 static void emlxs_verify_image(emlxs_hba_t
*hba
, emlxs_fw_image_t
*image
);
144 static uint32_t emlxs_clean_flash(emlxs_hba_t
*hba
,
145 PWAKE_UP_PARMS OldWakeUpParms
,
146 PWAKE_UP_PARMS NewWakeUpParms
);
148 /* ************************************************************************* */
151 emlxs_fw_download(emlxs_hba_t
*hba
, caddr_t buffer
, uint32_t len
,
154 emlxs_port_t
*port
= &PPORT
;
159 WAKE_UP_PARMS WakeUpParms
;
161 emlxs_fw_image_t fw_image
;
164 #ifdef EMLXS_LITTLE_ENDIAN
165 caddr_t local_buffer
;
168 #endif /* EMLXS_LITTLE_ENDIAN */
170 if (hba
->sli_mode
== EMLXS_HBA_SLI4_MODE
) {
171 rval
= emlxs_sli4_fw_download(hba
, buffer
, len
, offline
);
175 if (buffer
== NULL
|| len
== 0) {
176 return (EMLXS_IMAGE_BAD
);
179 #ifdef EMLXS_LITTLE_ENDIAN
180 /* We need to swap the image buffer before we start */
183 * Use KM_SLEEP to allocate a temporary buffer
185 local_buffer
= (caddr_t
)kmem_zalloc(len
, KM_SLEEP
);
187 /* Perform a 32 bit swap of the image */
188 bptr1
= (uint32_t *)local_buffer
;
189 bptr2
= (uint32_t *)buffer
;
190 for (i
= 0; i
< (len
/ 4); i
++) {
191 *bptr1
= LE_SWAP32(*bptr2
);
196 /* Replace the original buffer */
197 buffer
= local_buffer
;
198 #endif /* EMLXS_LITTLE_ENDIAN */
200 bzero(&fw_image
, sizeof (emlxs_fw_image_t
));
201 for (i
= 0; i
< MAX_PROG_TYPES
; i
++) {
202 (void) strcpy(fw_image
.prog
[i
].label
, "none");
206 if ((rval
= emlxs_validate_image(hba
, buffer
, len
, &fw_image
))) {
211 emlxs_verify_image(hba
, &fw_image
);
214 Uptr
= (uint32_t *)buffer
;
218 * Pegasus and beyond FW download is done differently
219 * for absolute download.
222 /* Check for absolute image */
223 if ((ImageType
== NOP_IMAGE_TYPE
) &&
224 !(hba
->model_info
.chip
&
225 (EMLXS_DRAGONFLY_CHIP
| EMLXS_CENTAUR_CHIP
))) {
227 * Because 2Mb flash download file format is different from
228 * 512k, it needs to be handled differently
230 if (rval
= emlxs_start_abs_download_2mb(hba
, buffer
, len
,
231 offline
, &fw_image
)) {
235 /* Offline already handled */
238 goto SLI_DOWNLOAD_EXIT
;
241 /* Pre-pegasus adapters only */
243 /* Initialize headers */
244 if (ImageType
== NOP_IMAGE_TYPE
) {
245 bcopy(buffer
, &AifHdr
, sizeof (AIF_HDR
));
246 bzero((void *)&ImageHdr
, sizeof (IMAGE_HDR
));
247 } else { /* PRG file */
248 bzero((void *)&AifHdr
, sizeof (AIF_HDR
));
249 bcopy(buffer
, &ImageHdr
, sizeof (IMAGE_HDR
));
252 /* Everything checks out, now to just do it */
255 if (emlxs_offline(hba
) != FC_SUCCESS
) {
258 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
259 "Unable to take adapter offline.");
261 rval
= EMLXS_OFFLINE_FAILED
;
262 goto SLI_DOWNLOAD_EXIT
;
265 if (EMLXS_SLI_HBA_RESET(hba
, 1, 1, 0) != FC_SUCCESS
) {
268 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
269 "Unable to restart adapter.");
271 rval
= EMLXS_OFFLINE_FAILED
;
272 goto SLI_DOWNLOAD_EXIT
;
276 /* Pre-pegasus adapters */
278 if (ImageHdr
.Id
.Type
== SBUS_FCODE
) {
280 if (emlxs_erase_fcode_flash(hba
)) {
281 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
282 "Unable to erase flash.");
284 rval
= EMLXS_IMAGE_FAILED
;
285 goto SLI_DOWNLOAD_EXIT
;
289 if (emlxs_write_fcode_flash(hba
, &ImageHdr
, buffer
)) {
290 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
291 "Unable to write flash.");
293 rval
= EMLXS_IMAGE_FAILED
;
294 goto SLI_DOWNLOAD_EXIT
;
297 goto SLI_DOWNLOAD_EXIT
;
300 /* Pre-pegasus PCI adapters */
302 if (emlxs_read_wakeup_parms(hba
, &WakeUpParms
, 1)) {
303 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
304 "Unable to get parameters.");
306 rval
= EMLXS_IMAGE_FAILED
;
308 goto SLI_DOWNLOAD_EXIT
;
311 if (ImageType
== NOP_IMAGE_TYPE
) {
312 if (emlxs_start_abs_download(hba
, &AifHdr
,
313 buffer
, len
, &WakeUpParms
)) {
314 EMLXS_MSGF(EMLXS_CONTEXT
,
315 &emlxs_download_failed_msg
,
316 "Failed to program flash.");
318 rval
= EMLXS_IMAGE_FAILED
;
320 goto SLI_DOWNLOAD_EXIT
;
323 } else { /* Relative PRG file */
324 if (emlxs_start_rel_download(hba
, &ImageHdr
, buffer
,
326 EMLXS_MSGF(EMLXS_CONTEXT
,
327 &emlxs_download_failed_msg
,
328 "Failed to program flash.");
330 rval
= EMLXS_IMAGE_FAILED
;
332 goto SLI_DOWNLOAD_EXIT
;
339 (void) emlxs_online(hba
);
343 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_complete_msg
,
349 #ifdef EMLXS_LITTLE_ENDIAN
350 /* Free the local buffer */
351 kmem_free(local_buffer
, len
);
352 #endif /* EMLXS_LITTLE_ENDIAN */
356 } /* emlxs_fw_download */
360 emlxs_memset(uint8_t *buffer
, uint8_t value
, uint32_t size
)
366 } /* emlxs_memset () */
370 emlxs_sli4_flash_image(emlxs_hba_t
*hba
, caddr_t buffer
,
371 emlxs_be_fw_file_t
*file
, MAILBOXQ
*mbq
, MATCHMAP
*mp
)
373 emlxs_port_t
*port
= &PPORT
;
378 IOCTL_COMMON_FLASHROM
*flashrom
;
379 mbox_req_hdr_t
*hdr_req
;
383 uint32_t block_offset
;
387 if (file
->image_size
== 0) {
391 image_ptr
= (uint8_t *)buffer
+ file
->image_offset
;
392 image_size
= file
->image_size
;
393 block_size
= file
->block_size
;
397 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
398 "%s: Downloading...", file
->label
);
401 bzero((void *) mb
, MAILBOX_CMD_SLI4_BSIZE
);
402 bzero((void *) mp
->virt
, mp
->size
);
404 xfer_size
= min(BE_MAX_XFER_SIZE
, block_size
);
406 mb
->un
.varSLIConfig
.be
.embedded
= 0;
407 mbq
->nonembed
= (void *)mp
;
408 mbq
->mbox_cmpl
= NULL
;
410 mb
->mbxCommand
= MBX_SLI_CONFIG
;
411 mb
->mbxOwner
= OWN_HOST
;
413 hdr_req
= (mbox_req_hdr_t
*)mp
->virt
;
414 hdr_req
->subsystem
= IOCTL_SUBSYSTEM_COMMON
;
415 hdr_req
->opcode
= COMMON_OPCODE_WRITE_FLASHROM
;
416 hdr_req
->timeout
= 0;
417 hdr_req
->req_length
= sizeof (IOCTL_COMMON_FLASHROM
) +
420 flashrom
= (IOCTL_COMMON_FLASHROM
*)(hdr_req
+ 1);
421 flashrom
->params
.opcode
= ((block_size
== xfer_size
)?
422 MGMT_FLASHROM_OPCODE_FLASH
:MGMT_FLASHROM_OPCODE_SAVE
);
423 flashrom
->params
.optype
= file
->type
;
424 flashrom
->params
.data_buffer_size
= xfer_size
;
425 flashrom
->params
.offset
= block_offset
;
427 /* Build data buffer payload */
428 payload
= (uint8_t *)(&flashrom
->params
.data_buffer
);
429 emlxs_memset(payload
, 0xff, xfer_size
);
431 /* Copy remaining image into payload */
433 count
= min(image_size
, xfer_size
);
434 BE_SWAP32_BCOPY(image_ptr
, payload
, count
);
439 if (flashrom
->params
.opcode
== MGMT_FLASHROM_OPCODE_FLASH
) {
440 wptr
= (uint32_t *)&payload
[(xfer_size
- 12)];
442 wptr
[0] = file
->load_address
;
443 wptr
[1] = file
->image_size
;
444 wptr
[2] = file
->block_crc
;
447 /* Send write request */
448 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbq
, MBX_WAIT
, 0) !=
450 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
451 "%s: Unable to download image. status=%x",
452 file
->label
, mb
->mbxStatus
);
453 rval
= EMLXS_IMAGE_FAILED
;
457 block_size
-= xfer_size
;
458 block_offset
+= xfer_size
;
461 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
462 "%s: Download complete.", file
->label
);
467 } /* emlxs_sli4_flash_image() */
473 emlxs_sli4_verify_crc(emlxs_hba_t
*hba
,
474 emlxs_be_fw_file_t
*file
, MAILBOXQ
*mbq
, MATCHMAP
*mp
)
476 emlxs_port_t
*port
= &PPORT
;
480 IOCTL_COMMON_FLASHROM
*flashrom
;
481 mbox_req_hdr_t
*hdr_req
;
483 uint32_t block_offset
;
488 block_offset
= file
->block_size
- xfer_size
;
491 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
492 "%s: Verifying CRC...", file
->label
);
494 bzero((void *) mb
, MAILBOX_CMD_SLI4_BSIZE
);
495 bzero((void *) mp
->virt
, mp
->size
);
497 mb
->un
.varSLIConfig
.be
.embedded
= 0;
498 mbq
->nonembed
= (void *)mp
;
499 mbq
->mbox_cmpl
= NULL
;
501 mb
->mbxCommand
= MBX_SLI_CONFIG
;
502 mb
->mbxOwner
= OWN_HOST
;
504 hdr_req
= (mbox_req_hdr_t
*)mp
->virt
;
505 hdr_req
->subsystem
= IOCTL_SUBSYSTEM_COMMON
;
506 hdr_req
->opcode
= COMMON_OPCODE_READ_FLASHROM
;
507 hdr_req
->timeout
= 0;
508 hdr_req
->req_length
= sizeof (IOCTL_COMMON_FLASHROM
) +
511 flashrom
= (IOCTL_COMMON_FLASHROM
*)(hdr_req
+ 1);
512 flashrom
->params
.opcode
= MGMT_FLASHROM_OPCODE_REPORT
;
513 flashrom
->params
.optype
= file
->type
;
514 flashrom
->params
.data_buffer_size
= xfer_size
;
515 flashrom
->params
.offset
= block_offset
;
517 /* Send read request */
518 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbq
, MBX_WAIT
, 0) !=
520 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
521 "%s: Unable to read CRC. status=%x",
522 file
->label
, mb
->mbxStatus
);
528 payload
= (uint8_t *)(&flashrom
->params
.data_buffer
);
529 wptr
= (uint32_t *)(payload
+ xfer_size
- 8);
531 /* Verify image size */
533 if (value
!= file
->image_size
) {
534 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
535 "%s: Image size mismatch. %08x != %08x",
536 file
->label
, value
, file
->image_size
);
542 /* Verify block crc */
544 if (value
!= file
->block_crc
) {
545 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
546 "%s: CRC mismatch. %08x != %08x",
547 file
->label
, value
, file
->block_crc
);
554 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
555 "%s: CRC verified.", file
->label
);
560 } /* emlxs_sli4_verify_crc() */
564 emlxs_sli4_read_fw_version(emlxs_hba_t
*hba
, emlxs_firmware_t
*fw
)
566 emlxs_port_t
*port
= &PPORT
;
567 MAILBOXQ
*mbq
= NULL
;
572 IOCTL_COMMON_FLASHROM
*flashrom
;
573 mbox_req_hdr_t
*hdr_req
;
575 uint32_t block_offset
;
578 bzero((void *) fw
, sizeof (emlxs_firmware_t
));
580 if ((mbq
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
581 KM_SLEEP
)) == NULL
) {
582 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sli_detail_msg
,
583 "read_fw_version: Unable to allocate mailbox buffer.");
589 if ((mp
= emlxs_mem_buf_alloc(hba
, (sizeof (mbox_req_hdr_t
) +
590 sizeof (IOCTL_COMMON_FLASHROM
) + 32))) == NULL
) {
591 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sli_detail_msg
,
592 "read_fw_version: Unable to allocate payload buffer.");
594 rval
= EMLXS_IMAGE_FAILED
;
600 /* Read CRC and size */
602 block_offset
= 0x140000 - xfer_size
;
604 bzero((void *) mb
, MAILBOX_CMD_SLI4_BSIZE
);
605 bzero((void *) mp
->virt
, mp
->size
);
607 mb
->un
.varSLIConfig
.be
.embedded
= 0;
608 mbq
->nonembed
= (void *)mp
;
609 mbq
->mbox_cmpl
= NULL
;
611 mb
->mbxCommand
= MBX_SLI_CONFIG
;
612 mb
->mbxOwner
= OWN_HOST
;
614 hdr_req
= (mbox_req_hdr_t
*)mp
->virt
;
615 hdr_req
->subsystem
= IOCTL_SUBSYSTEM_COMMON
;
616 hdr_req
->opcode
= COMMON_OPCODE_READ_FLASHROM
;
617 hdr_req
->timeout
= 0;
618 hdr_req
->req_length
= sizeof (IOCTL_COMMON_FLASHROM
) +
621 flashrom
= (IOCTL_COMMON_FLASHROM
*)(hdr_req
+ 1);
622 flashrom
->params
.opcode
= MGMT_FLASHROM_OPCODE_REPORT
;
623 flashrom
->params
.optype
= MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE
;
624 flashrom
->params
.data_buffer_size
= xfer_size
;
625 flashrom
->params
.offset
= block_offset
;
627 /* Send read request */
628 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbq
, MBX_WAIT
, 0) !=
630 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sli_detail_msg
,
631 "read_fw_version: Unable to read CRC. status=%x",
638 payload
= (uint8_t *)(&flashrom
->params
.data_buffer
);
640 wptr
= (uint32_t *)payload
;
641 fw
->size
= *wptr
++; /* image size */
642 fw
->sli4
= *wptr
; /* block crc */
646 /* Read version label */
650 bzero((void *) mb
, MAILBOX_CMD_SLI4_BSIZE
);
651 bzero((void *) mp
->virt
, mp
->size
);
653 mb
->un
.varSLIConfig
.be
.embedded
= 0;
654 mbq
->nonembed
= (void *)mp
;
655 mbq
->mbox_cmpl
= NULL
;
657 mb
->mbxCommand
= MBX_SLI_CONFIG
;
658 mb
->mbxOwner
= OWN_HOST
;
660 hdr_req
= (mbox_req_hdr_t
*)mp
->virt
;
661 hdr_req
->subsystem
= IOCTL_SUBSYSTEM_COMMON
;
662 hdr_req
->opcode
= COMMON_OPCODE_READ_FLASHROM
;
663 hdr_req
->timeout
= 0;
664 hdr_req
->req_length
= sizeof (IOCTL_COMMON_FLASHROM
) +
667 flashrom
= (IOCTL_COMMON_FLASHROM
*)(hdr_req
+ 1);
668 flashrom
->params
.opcode
= MGMT_FLASHROM_OPCODE_REPORT
;
669 flashrom
->params
.optype
= MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE
;
670 flashrom
->params
.data_buffer_size
= xfer_size
;
671 flashrom
->params
.offset
= block_offset
;
673 /* Send read request */
674 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbq
, MBX_WAIT
, 0) !=
676 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sli_detail_msg
,
677 "read_fw_version: Unable to read version string. status=%x",
684 payload
= (uint8_t *)(&flashrom
->params
.data_buffer
);
685 BE_SWAP32_BCOPY(payload
, (uint8_t *)fw
->label
, 32);
687 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sli_detail_msg
,
688 "FCOE FIRMWARE: size=%x version=%s (0x%08x)",
689 fw
->size
, fw
->label
, fw
->sli4
);
694 emlxs_mem_put(hba
, MEM_MBOX
, (void *)mbq
);
698 emlxs_mem_buf_free(hba
, mp
);
703 } /* emlxs_sli4_read_fw_version() */
707 emlxs_be_version(caddr_t buffer
, uint32_t size
, uint32_t *plus_flag
)
709 emlxs_be2_ufi_header_t
*ufi_hdr
;
710 char signature
[BE2_SIGNATURE_SIZE
];
711 uint32_t be_version
= 0;
713 if (size
< sizeof (emlxs_be2_ufi_header_t
)) {
716 ufi_hdr
= (emlxs_be2_ufi_header_t
*)buffer
;
718 (void) sprintf(signature
, "%s+", BE_SIGNATURE
);
720 /* Check if this is a UFI image */
721 if (strncmp(signature
, (char *)ufi_hdr
->signature
,
722 strlen(BE_SIGNATURE
)) != 0) {
726 /* Check if this is a UFI plus image */
728 /* Check if this is a UFI plus image */
729 if (strncmp(signature
, (char *)ufi_hdr
->signature
,
730 strlen(BE_SIGNATURE
)+1) == 0) {
737 if ((ufi_hdr
->build
[0] >= '1') && (ufi_hdr
->build
[0] <= '9')) {
738 be_version
= ufi_hdr
->build
[0] - '0';
743 } /* emlxs_be_version() */
747 emlxs_be2_validate_image(emlxs_hba_t
*hba
, caddr_t buffer
,
748 uint32_t len
, emlxs_be_fw_image_t
*fw_image
)
750 emlxs_port_t
*port
= &PPORT
;
751 emlxs_be2_ufi_header_t
*ufi_hdr
;
752 emlxs_be2_flash_dir_t
*flash_dir
;
753 emlxs_be2_flash_entry_t
*entry
;
761 emlxs_be_fw_file_t
*file
;
762 emlxs_be_fw_file_t
*file2
;
763 uint32_t ufi_plus
= 0;
764 uint32_t be_version
= 0;
767 bzero(fw_image
, sizeof (emlxs_be_fw_image_t
));
769 if (hba
->model_info
.chip
!= EMLXS_BE2_CHIP
) {
770 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_incompat_msg
,
771 "Invalid adapter model.");
772 return (EMLXS_IMAGE_INCOMPATIBLE
);
775 if (len
< (sizeof (emlxs_be2_ufi_header_t
) +
776 sizeof (emlxs_be2_flash_dir_t
))) {
777 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
778 "Image too small. (%d < %d)",
779 len
, (sizeof (emlxs_be2_ufi_header_t
) +
780 sizeof (emlxs_be2_flash_dir_t
)));
781 return (EMLXS_IMAGE_BAD
);
784 be_version
= emlxs_be_version(buffer
, len
, &ufi_plus
);
786 /* Check if this is a standard BE2 image */
787 if (be_version
!= 2) {
788 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_incompat_msg
,
789 "Invalid image provided.");
790 return (EMLXS_IMAGE_INCOMPATIBLE
);
793 ufi_hdr
= (emlxs_be2_ufi_header_t
*)buffer
;
795 #ifdef EMLXS_BIG_ENDIAN
796 /* Big Endian Swapping */
797 /* Swap ufi header */
799 SWAP32(ufi_hdr
->checksum
);
801 SWAP32(ufi_hdr
->antidote
);
802 ufi_hdr
->controller
.vendor_id
=
803 SWAP32(ufi_hdr
->controller
.vendor_id
);
804 ufi_hdr
->controller
.device_id
=
805 SWAP32(ufi_hdr
->controller
.device_id
);
806 ufi_hdr
->controller
.sub_vendor_id
=
807 SWAP32(ufi_hdr
->controller
.sub_vendor_id
);
808 ufi_hdr
->controller
.sub_device_id
=
809 SWAP32(ufi_hdr
->controller
.sub_device_id
);
810 ufi_hdr
->file_length
=
811 SWAP32(ufi_hdr
->file_length
);
813 SWAP32(ufi_hdr
->chunk_num
);
815 SWAP32(ufi_hdr
->chunk_cnt
);
817 SWAP32(ufi_hdr
->image_cnt
);
818 #endif /* EMLXS_BIG_ENDIAN */
820 if (len
!= ufi_hdr
->file_length
) {
821 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
822 "Invalid image size (%d != %d)",
823 len
, ufi_hdr
->file_length
);
825 return (EMLXS_IMAGE_BAD
);
828 /* Scan for flash dir signature */
829 bptr
= (uint8_t *)buffer
;
831 for (i
= 0; i
< len
; i
++, bptr
++) {
832 if (strncmp((char *)bptr
, BE_DIR_SIGNATURE
,
833 sizeof (BE_DIR_SIGNATURE
)) == 0) {
834 flash_dir
= (emlxs_be2_flash_dir_t
*)bptr
;
840 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
841 "Unable to find flash directory.");
843 return (EMLXS_IMAGE_BAD
);
846 #ifdef EMLXS_BIG_ENDIAN
847 /* Big Endian Swapping */
849 flash_dir
->header
.format_rev
=
850 SWAP32(flash_dir
->header
.format_rev
);
851 flash_dir
->header
.checksum
=
852 SWAP32(flash_dir
->header
.checksum
);
853 flash_dir
->header
.antidote
=
854 SWAP32(flash_dir
->header
.antidote
);
855 flash_dir
->header
.build_num
=
856 SWAP32(flash_dir
->header
.build_num
);
857 flash_dir
->header
.active_entry_mask
=
858 SWAP32(flash_dir
->header
.active_entry_mask
);
859 flash_dir
->header
.valid_entry_mask
=
860 SWAP32(flash_dir
->header
.valid_entry_mask
);
861 flash_dir
->header
.orig_content_mask
=
862 SWAP32(flash_dir
->header
.orig_content_mask
);
863 flash_dir
->header
.resv0
= SWAP32(flash_dir
->header
.resv0
);
864 flash_dir
->header
.resv1
= SWAP32(flash_dir
->header
.resv1
);
865 flash_dir
->header
.resv2
= SWAP32(flash_dir
->header
.resv2
);
866 flash_dir
->header
.resv3
= SWAP32(flash_dir
->header
.resv3
);
867 flash_dir
->header
.resv4
= SWAP32(flash_dir
->header
.resv4
);
869 for (i
= 0; i
< BE_CONTROLLER_SIZE
; i
++) {
870 flash_dir
->header
.controller
[i
].vendor_id
=
871 SWAP32(flash_dir
->header
.controller
[i
].vendor_id
);
872 flash_dir
->header
.controller
[i
].device_id
=
873 SWAP32(flash_dir
->header
.controller
[i
].device_id
);
874 flash_dir
->header
.controller
[i
].sub_vendor_id
=
875 SWAP32(flash_dir
->header
.controller
[i
].sub_vendor_id
);
876 flash_dir
->header
.controller
[i
].sub_device_id
=
877 SWAP32(flash_dir
->header
.controller
[i
].sub_device_id
);
880 for (i
= 0, mask
= 1; i
< BE_FLASH_ENTRIES
; i
++, mask
<<= 1) {
882 if (!(flash_dir
->header
.valid_entry_mask
& mask
)) {
886 entry
= &flash_dir
->entry
[i
];
888 if ((entry
->type
== 0) ||
889 (entry
->type
== (uint32_t)-1) ||
890 (entry
->image_size
== 0)) {
894 flash_dir
->entry
[i
].type
=
895 SWAP32(flash_dir
->entry
[i
].type
);
896 flash_dir
->entry
[i
].offset
=
897 SWAP32(flash_dir
->entry
[i
].offset
);
898 flash_dir
->entry
[i
].pad_size
=
899 SWAP32(flash_dir
->entry
[i
].pad_size
);
900 flash_dir
->entry
[i
].image_size
=
901 SWAP32(flash_dir
->entry
[i
].image_size
);
902 flash_dir
->entry
[i
].checksum
=
903 SWAP32(flash_dir
->entry
[i
].checksum
);
904 flash_dir
->entry
[i
].entry_point
=
905 SWAP32(flash_dir
->entry
[i
].entry_point
);
906 flash_dir
->entry
[i
].resv0
=
907 SWAP32(flash_dir
->entry
[i
].resv0
);
908 flash_dir
->entry
[i
].resv1
=
909 SWAP32(flash_dir
->entry
[i
].resv1
);
911 #endif /* EMLXS_BIG_ENDIAN */
913 /* Verify adapter model */
915 for (i
= 0; i
< BE_CONTROLLER_SIZE
; i
++) {
916 if (flash_dir
->header
.controller
[i
].device_id
==
917 hba
->model_info
.device_id
) {
923 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_incompat_msg
,
924 "Invalid adapter device id=0x%x.",
925 hba
->model_info
.device_id
);
926 return (EMLXS_IMAGE_INCOMPATIBLE
);
929 /* Build fw_image table */
930 fw_image
->be_version
= 2;
931 fw_image
->ufi_plus
= ufi_plus
;
932 for (i
= 0, mask
= 1; i
< BE_FLASH_ENTRIES
; i
++, mask
<<= 1) {
934 if (!(flash_dir
->header
.valid_entry_mask
& mask
)) {
938 entry
= &flash_dir
->entry
[i
];
940 if ((entry
->type
== 0) ||
941 (entry
->type
== (uint32_t)-1) ||
942 (entry
->image_size
== 0)) {
946 switch (entry
->type
) {
947 case BE_FLASHTYPE_REDBOOT
:
948 file
= &fw_image
->file
[REDBOOT_FLASHTYPE
];
949 (void) strcpy(file
->label
, "REDBOOT");
950 file
->type
= MGMT_FLASHROM_OPTYPE_REDBOOT
;
952 case BE_FLASHTYPE_ISCSI_BIOS
:
953 file
= &fw_image
->file
[ISCSI_BIOS_FLASHTYPE
];
954 (void) strcpy(file
->label
, "ISCSI BIOS");
955 file
->type
= MGMT_FLASHROM_OPTYPE_ISCSI_BIOS
;
957 case BE_FLASHTYPE_PXE_BIOS
:
958 file
= &fw_image
->file
[PXE_BIOS_FLASHTYPE
];
959 (void) strcpy(file
->label
, "PXE BIOS");
960 file
->type
= MGMT_FLASHROM_OPTYPE_PXE_BIOS
;
962 case BE_FLASHTYPE_FCOE_BIOS
:
963 file
= &fw_image
->file
[FCOE_BIOS_FLASHTYPE
];
964 (void) strcpy(file
->label
, "FCOE BIOS");
965 file
->type
= MGMT_FLASHROM_OPTYPE_FCOE_BIOS
;
967 case BE_FLASHTYPE_ISCSI_FIRMWARE
:
968 file
= &fw_image
->file
[ISCSI_FIRMWARE_FLASHTYPE
];
969 (void) strcpy(file
->label
, "ISCSI FIRMWARE");
970 file
->type
= MGMT_FLASHROM_OPTYPE_ISCSI_FIRMWARE
;
972 case BE_FLASHTYPE_FCOE_FIRMWARE
:
973 file
= &fw_image
->file
[FCOE_FIRMWARE_FLASHTYPE
];
974 (void) strcpy(file
->label
, "FCOE FIRMWARE");
975 file
->type
= MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE
;
977 case BE_FLASHTYPE_FCOE_BACKUP
:
978 case BE_FLASHTYPE_ISCSI_BACKUP
:
982 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
983 "Unknown image type found. type=%x",
988 file
->be_version
= fw_image
->be_version
;
989 file
->ufi_plus
= fw_image
->ufi_plus
;
990 file
->image_size
= entry
->image_size
;
991 image_size
= BE_SWAP32(entry
->image_size
);
994 file
->image_offset
= entry
->offset
;
995 file
->block_size
= entry
->pad_size
;
996 file
->block_crc
= entry
->checksum
;
997 file
->load_address
= entry
->entry_point
;
1000 file
->image_offset
= entry
->offset
+
1001 sizeof (emlxs_be2_ufi_header_t
);
1003 /* Get entry block size and crc */
1004 k
= file
->image_offset
+ file
->image_size
;
1007 wptr
= (uint32_t *)(buffer
+ k
);
1008 for (; k
< len
; k
+= 4) {
1009 if (*wptr
++ == image_size
) {
1010 /* Calculate block_size */
1011 file
->block_size
= (k
+ 8) -
1014 /* Read load_address */
1015 value
= *(wptr
- 2);
1016 file
->load_address
= BE_SWAP32(value
);
1018 /* Read block_crc */
1020 file
->block_crc
= BE_SWAP32(value
);
1027 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
1028 "%s: End of block not found. offset=%x",
1029 file
->label
, file
->image_offset
);
1031 bzero(fw_image
, sizeof (emlxs_be_fw_image_t
));
1032 return (EMLXS_IMAGE_BAD
);
1036 /* Make sure image will fit in block specified */
1037 if (file
->image_size
+ 12 > file
->block_size
) {
1038 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
1039 "%s: Image too large for block. image=%x block=%x",
1040 file
->label
, file
->image_size
, file
->block_size
);
1042 bzero(fw_image
, sizeof (emlxs_be_fw_image_t
));
1043 return (EMLXS_IMAGE_BAD
);
1046 /* Automatically create a backup file entry for firmware */
1047 if (file
->type
== MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE
) {
1048 file2
= &fw_image
->file
[FCOE_BACKUP_FLASHTYPE
];
1050 bcopy((uint8_t *)file
, (uint8_t *)file2
,
1051 sizeof (emlxs_be_fw_file_t
));
1052 file2
->type
= MGMT_FLASHROM_OPTYPE_FCOE_BACKUP
;
1053 (void) strcpy(file2
->label
, "FCOE BACKUP");
1055 /* Save FCOE version info */
1056 bptr
= (uint8_t *)buffer
+ file
->image_offset
+ 0x30;
1057 (void) strncpy(fw_image
->fcoe_label
, (char *)bptr
,
1059 fw_image
->fcoe_version
= file
->block_crc
;
1061 } else if (file
->type
==
1062 MGMT_FLASHROM_OPTYPE_ISCSI_FIRMWARE
) {
1063 file2
= &fw_image
->file
[ISCSI_BACKUP_FLASHTYPE
];
1065 bcopy((uint8_t *)file
, (uint8_t *)file2
,
1066 sizeof (emlxs_be_fw_file_t
));
1067 file2
->type
= MGMT_FLASHROM_OPTYPE_ISCSI_BACKUP
;
1068 (void) strcpy(file2
->label
, "ISCSI BACKUP");
1070 /* Save ISCSI version info */
1071 bptr
= (uint8_t *)buffer
+ file
->image_offset
+ 0x30;
1072 (void) strncpy(fw_image
->iscsi_label
, (char *)bptr
,
1074 fw_image
->iscsi_version
= file
->block_crc
;
1078 if (fw_image
->fcoe_version
== 0) {
1079 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
1080 "Unable to find FCOE firmware component.");
1082 bzero(fw_image
, sizeof (emlxs_be_fw_image_t
));
1083 return (EMLXS_IMAGE_BAD
);
1086 /* Display contents */
1087 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
1088 "BE2 UFI Image: %08x, %s", fw_image
->fcoe_version
,
1089 fw_image
->fcoe_label
);
1091 for (i
= 0; i
< BE_MAX_FLASHTYPES
; i
++) {
1092 file
= &fw_image
->file
[i
];
1094 if (file
->image_size
== 0) {
1098 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
1099 "%s: be=%x%s type=%x block=%x image=%x offset=%x crc=%x "
1101 file
->label
, file
->be_version
, (file
->ufi_plus
)?"+":"",
1102 file
->type
, file
->block_size
, file
->image_size
,
1103 file
->image_offset
, file
->block_crc
, file
->load_address
);
1108 } /* emlxs_be2_validate_image() */
1112 emlxs_be3_validate_image(emlxs_hba_t
*hba
, caddr_t buffer
,
1113 uint32_t len
, emlxs_be_fw_image_t
*fw_image
)
1115 emlxs_port_t
*port
= &PPORT
;
1116 emlxs_be3_ufi_header_t
*ufi_hdr
;
1117 emlxs_be3_flash_dir_t
*flash_dir
;
1118 emlxs_be3_flash_entry_t
*entry
;
1119 emlxs_be3_image_header_t
*flash_image_hdr
;
1120 emlxs_be3_image_header_t
*image_hdr
;
1125 emlxs_be_fw_file_t
*file
;
1126 emlxs_be_fw_file_t
*file2
;
1127 uint32_t ufi_plus
= 0;
1128 uint32_t be_version
= 0;
1131 bzero(fw_image
, sizeof (emlxs_be_fw_image_t
));
1133 if (hba
->model_info
.chip
!= EMLXS_BE3_CHIP
) {
1134 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_incompat_msg
,
1135 "Invalid adapter model.");
1136 return (EMLXS_IMAGE_INCOMPATIBLE
);
1139 if (len
< (sizeof (emlxs_be3_ufi_header_t
) +
1140 sizeof (emlxs_be3_flash_dir_t
))) {
1141 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
1142 "Image too small. (%d < %d)",
1143 len
, (sizeof (emlxs_be3_ufi_header_t
) +
1144 sizeof (emlxs_be3_flash_dir_t
)));
1145 return (EMLXS_IMAGE_BAD
);
1148 be_version
= emlxs_be_version(buffer
, len
, &ufi_plus
);
1150 /* Check if this is a standard BE3 image */
1151 if (be_version
!= 3) {
1152 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_incompat_msg
,
1153 "Invalid image provided.");
1154 return (EMLXS_IMAGE_INCOMPATIBLE
);
1157 ufi_hdr
= (emlxs_be3_ufi_header_t
*)buffer
;
1159 #ifdef EMLXS_BIG_ENDIAN
1160 /* Big Endian Swapping */
1161 /* Swap ufi header */
1162 ufi_hdr
->ufi_version
=
1163 SWAP32(ufi_hdr
->ufi_version
);
1164 ufi_hdr
->file_length
=
1165 SWAP32(ufi_hdr
->file_length
);
1167 SWAP32(ufi_hdr
->checksum
);
1169 SWAP32(ufi_hdr
->antidote
);
1170 ufi_hdr
->image_cnt
=
1171 SWAP32(ufi_hdr
->image_cnt
);
1172 #endif /* EMLXS_BIG_ENDIAN */
1174 if (len
!= ufi_hdr
->file_length
) {
1175 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
1176 "Invalid image size (%d != %d)",
1177 len
, ufi_hdr
->file_length
);
1179 return (EMLXS_IMAGE_BAD
);
1182 flash_image_hdr
= NULL
;
1183 image_hdr
= (emlxs_be3_image_header_t
*)(buffer
+
1184 sizeof (emlxs_be3_ufi_header_t
));
1185 for (i
= 0; i
< ufi_hdr
->image_cnt
; i
++, image_hdr
++) {
1186 #ifdef EMLXS_BIG_ENDIAN
1187 image_hdr
->id
= SWAP32(image_hdr
->id
);
1188 image_hdr
->offset
= SWAP32(image_hdr
->offset
);
1189 image_hdr
->length
= SWAP32(image_hdr
->length
);
1190 image_hdr
->checksum
= SWAP32(image_hdr
->checksum
);
1191 #endif /* EMLXS_BIG_ENDIAN */
1193 if (image_hdr
->id
== UFI_BE3_FLASH_ID
) {
1194 flash_image_hdr
= image_hdr
;
1198 if (!flash_image_hdr
) {
1199 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
1200 "No flash image found.");
1202 return (EMLXS_IMAGE_BAD
);
1205 /* Scan for flash dir signature */
1206 bptr
= (uint8_t *)buffer
+ flash_image_hdr
->offset
;
1208 for (i
= 0; i
< flash_image_hdr
->length
; i
++, bptr
++) {
1209 if (strncmp((char *)bptr
, BE_DIR_SIGNATURE
,
1210 sizeof (BE_DIR_SIGNATURE
)) == 0) {
1211 flash_dir
= (emlxs_be3_flash_dir_t
*)bptr
;
1217 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
1218 "Unable to find flash directory.");
1220 return (EMLXS_IMAGE_BAD
);
1223 #ifdef EMLXS_BIG_ENDIAN
1224 /* Big Endian Swapping */
1225 /* Swap flash dir */
1226 flash_dir
->header
.format_rev
=
1227 SWAP32(flash_dir
->header
.format_rev
);
1228 flash_dir
->header
.checksum
=
1229 SWAP32(flash_dir
->header
.checksum
);
1230 flash_dir
->header
.antidote
=
1231 SWAP32(flash_dir
->header
.antidote
);
1232 flash_dir
->header
.entry_count
=
1233 SWAP32(flash_dir
->header
.entry_count
);
1234 flash_dir
->header
.resv0
= SWAP32(flash_dir
->header
.resv0
);
1235 flash_dir
->header
.resv1
= SWAP32(flash_dir
->header
.resv1
);
1236 flash_dir
->header
.resv2
= SWAP32(flash_dir
->header
.resv2
);
1237 flash_dir
->header
.resv3
= SWAP32(flash_dir
->header
.resv3
);
1239 for (i
= 0; i
< BE_CONTROLLER_SIZE
; i
++) {
1240 flash_dir
->header
.controller
[i
].vendor_id
=
1241 SWAP32(flash_dir
->header
.controller
[i
].vendor_id
);
1242 flash_dir
->header
.controller
[i
].device_id
=
1243 SWAP32(flash_dir
->header
.controller
[i
].device_id
);
1244 flash_dir
->header
.controller
[i
].sub_vendor_id
=
1245 SWAP32(flash_dir
->header
.controller
[i
].sub_vendor_id
);
1246 flash_dir
->header
.controller
[i
].sub_device_id
=
1247 SWAP32(flash_dir
->header
.controller
[i
].sub_device_id
);
1250 for (i
= 0; i
< flash_dir
->header
.entry_count
; i
++) {
1251 entry
= &flash_dir
->entry
[i
];
1253 if ((entry
->type
== 0) ||
1254 (entry
->type
== (uint32_t)-1) ||
1255 (entry
->image_size
== 0)) {
1259 flash_dir
->entry
[i
].type
=
1260 SWAP32(flash_dir
->entry
[i
].type
);
1261 flash_dir
->entry
[i
].offset
=
1262 SWAP32(flash_dir
->entry
[i
].offset
);
1263 flash_dir
->entry
[i
].block_size
=
1264 SWAP32(flash_dir
->entry
[i
].block_size
);
1265 flash_dir
->entry
[i
].image_size
=
1266 SWAP32(flash_dir
->entry
[i
].image_size
);
1267 flash_dir
->entry
[i
].checksum
=
1268 SWAP32(flash_dir
->entry
[i
].checksum
);
1269 flash_dir
->entry
[i
].entry_point
=
1270 SWAP32(flash_dir
->entry
[i
].entry_point
);
1271 flash_dir
->entry
[i
].resv0
=
1272 SWAP32(flash_dir
->entry
[i
].resv0
);
1273 flash_dir
->entry
[i
].resv1
=
1274 SWAP32(flash_dir
->entry
[i
].resv1
);
1276 #endif /* EMLXS_BIG_ENDIAN */
1278 /* Verify image checksum */
1279 if (flash_dir
->header
.checksum
!= flash_image_hdr
->checksum
) {
1280 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
1281 "Invalid flash directory checksum. (%x != %x)\n",
1282 flash_dir
->header
.checksum
, flash_image_hdr
->checksum
);
1283 return (EMLXS_IMAGE_BAD
);
1286 /* Verify adapter model */
1288 for (i
= 0; i
< BE_CONTROLLER_SIZE
; i
++) {
1289 if (flash_dir
->header
.controller
[i
].device_id
==
1290 hba
->model_info
.device_id
) {
1296 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_incompat_msg
,
1297 "Invalid adapter device id=0x%x.",
1298 hba
->model_info
.device_id
);
1299 return (EMLXS_IMAGE_INCOMPATIBLE
);
1302 /* Build fw_image table */
1303 fw_image
->be_version
= 3;
1304 fw_image
->ufi_plus
= ufi_plus
;
1305 for (i
= 0; i
< flash_dir
->header
.entry_count
; i
++) {
1306 entry
= &flash_dir
->entry
[i
];
1308 if ((entry
->type
== 0) ||
1309 (entry
->type
== (uint32_t)-1) ||
1310 (entry
->image_size
== 0)) {
1314 switch (entry
->type
) {
1315 case BE_FLASHTYPE_REDBOOT
:
1316 file
= &fw_image
->file
[REDBOOT_FLASHTYPE
];
1317 (void) strcpy(file
->label
, "REDBOOT");
1318 file
->type
= MGMT_FLASHROM_OPTYPE_REDBOOT
;
1320 case BE_FLASHTYPE_ISCSI_BIOS
:
1321 file
= &fw_image
->file
[ISCSI_BIOS_FLASHTYPE
];
1322 (void) strcpy(file
->label
, "ISCSI BIOS");
1323 file
->type
= MGMT_FLASHROM_OPTYPE_ISCSI_BIOS
;
1325 case BE_FLASHTYPE_PXE_BIOS
:
1326 file
= &fw_image
->file
[PXE_BIOS_FLASHTYPE
];
1327 (void) strcpy(file
->label
, "PXE BIOS");
1328 file
->type
= MGMT_FLASHROM_OPTYPE_PXE_BIOS
;
1330 case BE_FLASHTYPE_FCOE_BIOS
:
1331 file
= &fw_image
->file
[FCOE_BIOS_FLASHTYPE
];
1332 (void) strcpy(file
->label
, "FCOE BIOS");
1333 file
->type
= MGMT_FLASHROM_OPTYPE_FCOE_BIOS
;
1335 case BE_FLASHTYPE_ISCSI_FIRMWARE
:
1336 file
= &fw_image
->file
[ISCSI_FIRMWARE_FLASHTYPE
];
1337 (void) strcpy(file
->label
, "ISCSI FIRMWARE");
1338 file
->type
= MGMT_FLASHROM_OPTYPE_ISCSI_FIRMWARE
;
1340 case BE_FLASHTYPE_FCOE_FIRMWARE
:
1341 file
= &fw_image
->file
[FCOE_FIRMWARE_FLASHTYPE
];
1342 (void) strcpy(file
->label
, "FCOE FIRMWARE");
1343 file
->type
= MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE
;
1345 case BE_FLASHTYPE_NCSI_FIRMWARE
:
1346 file
= &fw_image
->file
[NCSI_FIRMWARE_FLASHTYPE
];
1347 (void) strcpy(file
->label
, "NCSI FIRMWARE");
1348 file
->type
= MGMT_FLASHROM_OPTYPE_NCSI_FIRMWARE
;
1350 case BE_FLASHTYPE_FLASH_ISM
:
1351 case BE_FLASHTYPE_FCOE_BACKUP
:
1352 case BE_FLASHTYPE_ISCSI_BACKUP
:
1356 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
1357 "Unknown image type found. type=%x",
1362 file
->be_version
= fw_image
->be_version
;
1363 file
->ufi_plus
= fw_image
->ufi_plus
;
1364 file
->image_size
= entry
->image_size
;
1367 file
->image_offset
= entry
->offset
;
1368 file
->block_size
= entry
->block_size
;
1369 file
->block_crc
= entry
->checksum
;
1370 file
->load_address
= entry
->entry_point
;
1372 file
->image_offset
= entry
->offset
+
1373 flash_image_hdr
->offset
;
1374 file
->block_size
= entry
->block_size
;
1376 wptr
= (uint32_t *)(buffer
+ file
->image_offset
+
1379 /* Read load address */
1380 value
= *(wptr
- 3);
1381 file
->load_address
= BE_SWAP32(value
);
1383 /* Read block_crc */
1384 value
= *(wptr
- 1);
1385 file
->block_crc
= BE_SWAP32(value
);
1388 /* Make sure image will fit in block specified */
1389 if (file
->image_size
+ 12 > file
->block_size
) {
1390 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
1391 "%s: Image too large for block. image=%x block=%x",
1392 file
->label
, file
->image_size
, file
->block_size
);
1394 bzero(fw_image
, sizeof (emlxs_be_fw_image_t
));
1395 return (EMLXS_IMAGE_BAD
);
1398 /* Automatically create a backup file entry for firmware */
1399 if (file
->type
== MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE
) {
1400 file2
= &fw_image
->file
[FCOE_BACKUP_FLASHTYPE
];
1402 bcopy((uint8_t *)file
, (uint8_t *)file2
,
1403 sizeof (emlxs_be_fw_file_t
));
1404 file2
->type
= MGMT_FLASHROM_OPTYPE_FCOE_BACKUP
;
1405 (void) strcpy(file2
->label
, "FCOE BACKUP");
1407 /* Save FCOE version info */
1408 bptr
= (uint8_t *)buffer
+ file
->image_offset
+ 0x30;
1409 (void) strncpy(fw_image
->fcoe_label
, (char *)bptr
,
1411 fw_image
->fcoe_version
= file
->block_crc
;
1413 } else if (file
->type
==
1414 MGMT_FLASHROM_OPTYPE_ISCSI_FIRMWARE
) {
1415 file2
= &fw_image
->file
[ISCSI_BACKUP_FLASHTYPE
];
1417 bcopy((uint8_t *)file
, (uint8_t *)file2
,
1418 sizeof (emlxs_be_fw_file_t
));
1419 file2
->type
= MGMT_FLASHROM_OPTYPE_ISCSI_BACKUP
;
1420 (void) strcpy(file2
->label
, "ISCSI BACKUP");
1422 /* Save ISCSI version info */
1423 bptr
= (uint8_t *)buffer
+ file
->image_offset
+ 0x30;
1424 (void) strncpy(fw_image
->iscsi_label
, (char *)bptr
,
1426 fw_image
->iscsi_version
= file
->block_crc
;
1430 if (fw_image
->fcoe_version
== 0) {
1431 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
1432 "Unable to find FCOE firmware component.");
1434 bzero(fw_image
, sizeof (emlxs_be_fw_image_t
));
1435 return (EMLXS_IMAGE_BAD
);
1438 /* Display contents */
1439 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
1440 "BE3 UFI Image: %08x, %s", fw_image
->fcoe_version
,
1441 fw_image
->fcoe_label
);
1443 for (i
= 0; i
< BE_MAX_FLASHTYPES
; i
++) {
1444 file
= &fw_image
->file
[i
];
1446 if (file
->image_size
== 0) {
1450 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
1451 "%s: be=%x%s type=%x block=%x image=%x offset=%x crc=%x "
1453 file
->label
, file
->be_version
, (file
->ufi_plus
)? "+":"",
1454 file
->type
, file
->block_size
, file
->image_size
,
1455 file
->image_offset
, file
->block_crc
, file
->load_address
);
1460 } /* emlxs_be3_validate_image() */
1464 emlxs_sli4_fw_download(emlxs_hba_t
*hba
, caddr_t buffer
, uint32_t len
,
1467 emlxs_port_t
*port
= &PPORT
;
1469 uint32_t update
= 0;
1471 MAILBOXQ
*mbq
= NULL
;
1472 MATCHMAP
*mp
= NULL
;
1473 emlxs_be_fw_image_t fw_image
;
1474 emlxs_be_fw_file_t
*file
;
1475 uint32_t be_version
;
1477 /* For now we will not take the driver offline during a download */
1480 if (hba
->sli_mode
!= EMLXS_HBA_SLI4_MODE
) {
1481 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_incompat_msg
,
1482 "Invalid sli_mode. mode=%d", hba
->sli_mode
);
1483 return (EMLXS_IMAGE_INCOMPATIBLE
);
1486 if (buffer
== NULL
|| len
== 0) {
1487 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
1488 "Empty buffer provided. buf=%p size=%d", buffer
, len
);
1489 return (EMLXS_IMAGE_BAD
);
1492 be_version
= emlxs_be_version(buffer
, len
, 0);
1494 switch (be_version
) {
1496 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_incompat_msg
,
1497 "Invalid image provided. Non-UFI format.");
1498 return (EMLXS_IMAGE_INCOMPATIBLE
);
1500 rval
= emlxs_be2_validate_image(hba
, buffer
, len
, &fw_image
);
1506 rval
= emlxs_be3_validate_image(hba
, buffer
, len
, &fw_image
);
1512 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_incompat_msg
,
1513 "Invalid image provided. Unknown BE version. (%x)",
1515 return (EMLXS_IMAGE_INCOMPATIBLE
);
1518 /* Allocate resources */
1520 if ((mbq
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
1521 KM_SLEEP
)) == NULL
) {
1522 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
1523 "Unable to allocate mailbox buffer.");
1526 rval
= EMLXS_IMAGE_FAILED
;
1530 if ((mp
= emlxs_mem_buf_alloc(hba
, (sizeof (mbox_req_hdr_t
) +
1531 sizeof (IOCTL_COMMON_FLASHROM
) + BE_MAX_XFER_SIZE
))) == NULL
) {
1532 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
1533 "Unable to allocate flash buffer.");
1536 rval
= EMLXS_IMAGE_FAILED
;
1540 /* Check if update is required */
1541 for (i
= 0; i
< BE_MAX_FLASHTYPES
; i
++) {
1542 file
= &fw_image
.file
[i
];
1544 if (file
->image_size
== 0) {
1548 rval
= emlxs_sli4_verify_crc(hba
, file
, mbq
, mp
);
1552 file
->image_size
= 0;
1566 * Everything checks out, now to just do it
1569 if (emlxs_offline(hba
) != FC_SUCCESS
) {
1571 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
1572 "Unable to take adapter offline.");
1575 rval
= EMLXS_OFFLINE_FAILED
;
1580 /* Download entries which require update */
1581 for (i
= 0; i
< BE_MAX_FLASHTYPES
; i
++) {
1582 file
= &fw_image
.file
[i
];
1584 if (file
->image_size
== 0) {
1588 rval
= emlxs_sli4_flash_image(hba
, buffer
, file
, mbq
, mp
);
1597 emlxs_mem_put(hba
, MEM_MBOX
, (void *)mbq
);
1601 emlxs_mem_buf_free(hba
, mp
);
1605 (void) emlxs_online(hba
);
1610 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_complete_msg
,
1613 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_updated_msg
,
1614 "Please reboot system or power cycle adapter "
1615 "to activate new firmware: %s",
1616 fw_image
.fcoe_label
);
1619 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1620 "No firmware update required.");
1626 } /* emlxs_sli4_fw_download() */
1630 emlxs_cfl_download(emlxs_hba_t
*hba
, uint32_t region
, caddr_t buffer
,
1633 emlxs_port_t
*port
= &PPORT
;
1634 MAILBOXQ
*mbox
= NULL
;
1639 #ifdef EMLXS_BIG_ENDIAN
1640 caddr_t local_buffer
;
1644 #endif /* EMLXS_BIG_ENDIAN */
1646 if (buffer
== NULL
|| len
== 0) {
1647 return (EMLXS_IMAGE_BAD
);
1650 #ifdef EMLXS_BIG_ENDIAN
1651 /* We need to swap the image buffer before we start */
1654 * Use KM_SLEEP to allocate a temporary buffer
1656 local_buffer
= (caddr_t
)kmem_zalloc(len
, KM_SLEEP
);
1658 /* Perform a 32 bit swap of the image */
1659 bptr1
= (uint32_t *)local_buffer
;
1660 bptr2
= (uint32_t *)buffer
;
1662 for (i
= 0; i
< (len
/ 4); i
++) {
1663 *bptr1
= SWAP32(*bptr2
);
1668 /* Replace the original buffer */
1669 buffer
= local_buffer
;
1671 #endif /* EMLXS_BIG_ENDIAN */
1674 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
1675 "Invalid image length: 0x%x > 128", len
);
1677 return (EMLXS_IMAGE_BAD
);
1680 /* Check the region number */
1681 if ((region
> 2) && (region
!= 0xff)) {
1682 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
1683 "Invalid region id: 0x%x", region
);
1685 return (EMLXS_IMAGE_BAD
);
1689 /* Check the image vendor id */
1690 id
= *(int32_t *)buffer
;
1691 if ((id
& 0xffff) != 0x10df) {
1692 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
1693 "Invalid image id: 0x%x", id
);
1695 return (EMLXS_IMAGE_BAD
);
1698 if ((mbox
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
1699 KM_NOSLEEP
)) == NULL
) {
1700 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
1701 "Unable to allocate mailbox buffer.");
1708 mb
= (MAILBOX
*)mbox
;
1711 * Everything checks out, now to just do it
1713 if (emlxs_offline(hba
) != FC_SUCCESS
) {
1714 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
1715 "Unable to take HBA offline.");
1717 rval
= EMLXS_OFFLINE_FAILED
;
1722 if (EMLXS_SLI_HBA_RESET(hba
, 1, 1, 0) != FC_SUCCESS
) {
1723 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
1724 "Unable to restart adapter.");
1726 rval
= EMLXS_OFFLINE_FAILED
;
1731 /* Check if default region is requested */
1732 if (region
== 0xff) {
1734 * Sun-branded Helios and Zypher have different
1735 * default PCI region
1737 if ((hba
->model_info
.flags
& EMLXS_SUN_BRANDED
) &&
1738 (hba
->model_info
.chip
&
1739 (EMLXS_HELIOS_CHIP
| EMLXS_ZEPHYR_CHIP
))) {
1746 /* Set region id based on PCI region requested */
1747 region_id
= DEF_PCI_CFG_REGION_ID
+ region
;
1749 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
1750 "PCI configuration: PCI%d region=%d id=0x%x size=%d", region
,
1751 region_id
, id
, len
);
1753 /* Copy the data buffer to SLIM */
1754 WRITE_SLIM_COPY(hba
, (uint32_t *)buffer
,
1755 (volatile uint32_t *)((volatile char *)hba
->sli
.sli3
.slim_addr
+
1756 sizeof (MAILBOX
)), (len
/ sizeof (uint32_t)));
1759 if (emlxs_fm_check_acc_handle(hba
, hba
->sli
.sli3
.slim_acc_handle
)
1761 EMLXS_MSGF(EMLXS_CONTEXT
,
1762 &emlxs_invalid_access_handle_msg
, NULL
);
1765 #endif /* FMA_SUPPORT */
1767 emlxs_format_update_pci_cfg(hba
, mbox
, region_id
, len
);
1769 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) != MBX_SUCCESS
) {
1770 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
1771 "Unable to update PCI configuration: Mailbox cmd=%x "
1772 "status=%x info=%d", mb
->mbxCommand
, mb
->mbxStatus
,
1773 mb
->un
.varUpdateCfg
.rsp_info
);
1778 (void) emlxs_online(hba
);
1781 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_complete_msg
,
1788 kmem_free(mbox
, sizeof (MAILBOXQ
));
1791 #ifdef EMLXS_BIG_ENDIAN
1792 /* Free the local buffer */
1793 kmem_free(local_buffer
, len
);
1794 #endif /* EMLXS_BIG_ENDIAN */
1798 } /* emlxs_cfl_download */
1802 emlxs_valid_cksum(uint32_t *StartAddr
, uint32_t *EndAddr
)
1808 CkSum
= SLI_CKSUM_SEED
;
1810 CkSum
= (CkSum
>> 1) | (CkSum
<< 31);
1811 while (StartAddr
!= EndAddr
) {
1812 CkSum
= (CkSum
<< 1) | (CkSum
>> 31);
1819 return (CkSum
<< 1) | (CkSum
>> 31);
1821 } /* emlxs_valid_cksum() */
1825 emlxs_disp_aif_header(emlxs_hba_t
*hba
, PAIF_HDR AifHdr
)
1827 emlxs_port_t
*port
= &PPORT
;
1829 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
, "AIF Header: ");
1830 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1831 "AIF Header: compress_br = 0x%x", AifHdr
->CompressBr
);
1832 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1833 "AIF Header: reloc_br = 0x%x", AifHdr
->RelocBr
);
1834 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1835 "AIF Header: zinit_br = 0x%x", AifHdr
->ZinitBr
);
1836 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1837 "AIF Header: entry_br = 0x%x", AifHdr
->EntryBr
);
1838 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1839 "AIF Header: area_id = 0x%x", AifHdr
->Area_ID
);
1840 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1841 "AIF Header: rosize = 0x%x", AifHdr
->RoSize
);
1842 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1843 "AIF Header: dbgsize = 0x%x", AifHdr
->DbgSize
);
1844 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1845 "AIF Header: zinitsize = 0x%x", AifHdr
->ZinitSize
);
1846 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1847 "AIF Header: dbgtype = 0x%x", AifHdr
->DbgType
);
1848 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1849 "AIF Header: imagebase = 0x%x", AifHdr
->ImageBase
);
1850 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1851 "AIF Header: area_size = 0x%x", AifHdr
->Area_Size
);
1852 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1853 "AIF Header: address_mode = 0x%x", AifHdr
->AddressMode
);
1854 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1855 "AIF Header: database = 0x%x", AifHdr
->DataBase
);
1856 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1857 "AIF Header: aversion = 0x%x", AifHdr
->AVersion
);
1858 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1859 "AIF Header: spare2 = 0x%x", AifHdr
->Spare2
);
1860 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1861 "AIF Header: debug_swi = 0x%x", AifHdr
->DebugSwi
);
1862 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1863 "AIF Header: zinitcode[0] = 0x%x", AifHdr
->ZinitCode
[0]);
1864 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1865 "AIF Header: zinitcode[1] = 0x%x", AifHdr
->ZinitCode
[1]);
1867 } /* emlxs_disp_aif_header() */
1872 emlxs_dump_image_header(emlxs_hba_t
*hba
, PIMAGE_HDR image
)
1874 emlxs_port_t
*port
= &PPORT
;
1876 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
, "Img Header: ");
1877 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1878 "Img Header: BlockSize = 0x%x", image
->BlockSize
);
1879 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1880 "Img Header: PROG_ID Type = 0x%x", image
->Id
.Type
);
1881 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1882 "Img Header: PROG_ID Id = 0x%x", image
->Id
.Id
);
1883 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1884 "Img Header: PROG_ID Ver = 0x%x", image
->Id
.Ver
);
1885 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1886 "Img Header: PROG_ID Rev = 0x%x", image
->Id
.Rev
);
1887 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1888 "Img Header: PROG_ID revcomp = 0x%x", image
->Id
.un
.revcomp
);
1889 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1890 "Img Header: Flags = 0x%x", image
->Flags
);
1891 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1892 "Img Header: EntryAdr = 0x%x", image
->EntryAdr
);
1893 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1894 "Img Header: InitAdr = 0x%x", image
->InitAdr
);
1895 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1896 "Img Header: ExitAdr = 0x%x", image
->ExitAdr
);
1897 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1898 "Img Header: ImageBase = 0x%x", image
->ImageBase
);
1899 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1900 "Img Header: ImageSize = 0x%x", image
->ImageSize
);
1901 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1902 "Img Header: ZinitSize = 0x%x", image
->ZinitSize
);
1903 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1904 "Img Header: RelocSize = 0x%x", image
->RelocSize
);
1905 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1906 "Img Header: HdrCks = 0x%x", image
->HdrCks
);
1908 } /* emlxs_dump_image_header() */
1912 emlxs_format_dump(emlxs_hba_t
*hba
, MAILBOXQ
*mbq
, uint32_t Type
,
1913 uint32_t RegionId
, uint32_t WordCount
, uint32_t BaseAddr
)
1916 if (hba
->sli_mode
== EMLXS_HBA_SLI4_MODE
) {
1917 MAILBOX4
*mb
= (MAILBOX4
*)mbq
;
1919 /* Clear the local dump_region */
1920 bzero(hba
->sli
.sli4
.dump_region
.virt
,
1921 hba
->sli
.sli4
.dump_region
.size
);
1923 bzero((void *) mb
, MAILBOX_CMD_SLI4_BSIZE
);
1925 mb
->mbxCommand
= MBX_DUMP_MEMORY
;
1926 mb
->un
.varDmp4
.type
= Type
;
1927 mb
->un
.varDmp4
.entry_index
= BaseAddr
;
1928 mb
->un
.varDmp4
.region_id
= RegionId
;
1930 mb
->un
.varDmp4
.available_cnt
= min((WordCount
*4),
1931 hba
->sli
.sli4
.dump_region
.size
);
1932 mb
->un
.varDmp4
.addrHigh
=
1933 PADDR_HI(hba
->sli
.sli4
.dump_region
.phys
);
1934 mb
->un
.varDmp4
.addrLow
=
1935 PADDR_LO(hba
->sli
.sli4
.dump_region
.phys
);
1936 mb
->un
.varDmp4
.rsp_cnt
= 0;
1938 mb
->mbxOwner
= OWN_HOST
;
1941 MAILBOX
*mb
= (MAILBOX
*)mbq
;
1943 bzero((void *)mb
, MAILBOX_CMD_BSIZE
);
1945 mb
->mbxCommand
= MBX_DUMP_MEMORY
;
1946 mb
->un
.varDmp
.type
= Type
;
1947 mb
->un
.varDmp
.region_id
= RegionId
;
1948 mb
->un
.varDmp
.word_cnt
= WordCount
;
1949 mb
->un
.varDmp
.base_adr
= BaseAddr
;
1950 mb
->mbxOwner
= OWN_HOST
;
1953 mbq
->mbox_cmpl
= NULL
; /* no cmpl needed */
1957 } /* emlxs_format_dump() */
1962 emlxs_start_abs_download(emlxs_hba_t
*hba
,
1966 PWAKE_UP_PARMS WakeUpParms
)
1968 emlxs_port_t
*port
= &PPORT
;
1969 uint32_t DlByteCount
= AifHdr
->RoSize
+ AifHdr
->RwSize
;
1972 caddr_t DataBuffer
= NULL
;
1976 uint32_t SegSize
= DL_SLIM_SEG_BYTE_COUNT
;
1977 uint32_t DlToAddr
= AifHdr
->ImageBase
;
1980 WAKE_UP_PARMS AbsWakeUpParms
;
1981 int32_t AbsChangeParams
;
1983 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
1984 "Performing absolute download...");
1986 if ((DataBuffer
= (caddr_t
)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT
,
1987 KM_NOSLEEP
)) == NULL
) {
1988 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
1989 "Unable to allocate data buffer.");
1994 if ((mbox
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
1995 KM_NOSLEEP
)) == NULL
) {
1996 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
1997 "Unable to allocate mailbox buffer.");
1999 kmem_free(DataBuffer
, DL_SLIM_SEG_BYTE_COUNT
);
2003 mb
= (MAILBOX
*)mbox
;
2005 AbsChangeParams
= emlxs_build_parms(Buffer
,
2006 &AbsWakeUpParms
, len
, AifHdr
);
2008 Buffer
+= sizeof (AIF_HDR
);
2010 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
, "Erasing flash...");
2012 if (AifHdr
->ImageBase
== 0x20000) {
2014 emlxs_format_prog_flash(mbox
, 0x20000, 0x50000, ERASE_FLASH
, 0,
2017 emlxs_format_prog_flash(mbox
, DlToAddr
, DlByteCount
,
2018 ERASE_FLASH
, 0, 0, 0, NULL
, 0);
2021 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) != MBX_SUCCESS
) {
2022 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2023 "Unable to erase Flash: Mailbox cmd=%x status=%x",
2024 mb
->mbxCommand
, mb
->mbxStatus
);
2028 goto EXIT_ABS_DOWNLOAD
;
2031 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
2032 "Programming flash...");
2034 while (DlByteCount
) {
2036 if (DlByteCount
> SegSize
) {
2039 DlCount
= DlByteCount
;
2041 DlByteCount
-= DlCount
;
2043 Dst
= (uint32_t *)DataBuffer
;
2044 Src
= (uint32_t *)Buffer
;
2046 for (i
= 0; i
< (DlCount
/ 4); i
++) {
2052 WRITE_SLIM_COPY(hba
, (uint32_t *)DataBuffer
,
2053 (volatile uint32_t *)
2054 ((volatile char *)hba
->sli
.sli3
.slim_addr
+
2055 sizeof (MAILBOX
)), (DlCount
/ sizeof (uint32_t)));
2057 emlxs_format_prog_flash(mbox
, DlToAddr
, DlCount
,
2058 PROGRAM_FLASH
, (DlByteCount
) ? 0 : 1, 0, DlCount
, NULL
, 0);
2060 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) !=
2062 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2063 "Unable to program Flash: Mailbox cmd=%x status=%x",
2064 mb
->mbxCommand
, mb
->mbxStatus
);
2068 goto EXIT_ABS_DOWNLOAD
;
2072 DlToAddr
+= DlCount
;
2076 if (emlxs_fm_check_acc_handle(hba
, hba
->sli
.sli3
.slim_acc_handle
)
2078 EMLXS_MSGF(EMLXS_CONTEXT
,
2079 &emlxs_invalid_access_handle_msg
, NULL
);
2083 goto EXIT_ABS_DOWNLOAD
;
2085 #endif /* FMA_SUPPORT */
2087 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
, "Updating params...");
2089 if (AbsChangeParams
) {
2091 emlxs_update_wakeup_parms(hba
, &AbsWakeUpParms
,
2097 kmem_free(DataBuffer
, DL_SLIM_SEG_BYTE_COUNT
);
2101 kmem_free(mbox
, sizeof (MAILBOXQ
));
2106 } /* emlxs_start_abs_download() */
2111 emlxs_format_prog_flash(MAILBOXQ
*mbq
,
2113 uint32_t DlByteCount
,
2116 uint32_t BdeAddress
,
2121 MAILBOX
*mb
= (MAILBOX
*)mbq
;
2123 bzero((void *)mb
, MAILBOX_CMD_BSIZE
);
2126 mb
->mbxCommand
= MBX_DOWN_LOAD
;
2128 mb
->mbxCommand
= MBX_LOAD_SM
;
2131 mb
->un
.varLdSM
.load_cmplt
= Complete
;
2132 mb
->un
.varLdSM
.method
= DL_FROM_SLIM
;
2133 mb
->un
.varLdSM
.update_flash
= 1;
2134 mb
->un
.varLdSM
.erase_or_prog
= Function
;
2135 mb
->un
.varLdSM
.dl_to_adr
= Base
;
2136 mb
->un
.varLdSM
.dl_len
= DlByteCount
;
2137 mb
->un
.varLdSM
.keep
= keep
;
2140 mb
->un
.varLdSM
.un
.dl_from_slim_offset
= DL_FROM_SLIM_OFFSET
;
2141 } else if (ProgId
) {
2142 mb
->un
.varLdSM
.un
.prog_id
= *ProgId
;
2144 mb
->un
.varLdSM
.un
.dl_from_slim_offset
= 0;
2147 mb
->mbxOwner
= OWN_HOST
;
2148 mbq
->mbox_cmpl
= NULL
;
2150 } /* emlxs_format_prog_flash() */
2154 emlxs_format_update_parms(MAILBOXQ
*mbq
, PWAKE_UP_PARMS WakeUpParms
)
2156 MAILBOX
*mb
= (MAILBOX
*)mbq
;
2158 bzero((void *)mb
, MAILBOX_CMD_BSIZE
);
2160 mb
->mbxCommand
= MBX_UPDATE_CFG
;
2161 mb
->un
.varUpdateCfg
.req_type
= UPDATE_DATA
;
2162 mb
->un
.varUpdateCfg
.region_id
= WAKE_UP_PARMS_REGION_ID
;
2163 mb
->un
.varUpdateCfg
.entry_len
= sizeof (WAKE_UP_PARMS
);
2164 mb
->un
.varUpdateCfg
.byte_len
= sizeof (WAKE_UP_PARMS
);
2166 bcopy((caddr_t
)WakeUpParms
,
2167 (caddr_t
)&(mb
->un
.varUpdateCfg
.cfg_data
),
2168 sizeof (WAKE_UP_PARMS
));
2169 mbq
->mbox_cmpl
= NULL
;
2171 } /* emlxs_format_update_parms () */
2176 emlxs_format_update_pci_cfg(emlxs_hba_t
*hba
, MAILBOXQ
*mbq
,
2177 uint32_t region_id
, uint32_t size
)
2179 MAILBOX
*mb
= (MAILBOX
*)mbq
;
2181 bzero((void *)mb
, MAILBOX_CMD_BSIZE
);
2183 mb
->mbxCommand
= MBX_UPDATE_CFG
;
2184 mb
->un
.varUpdateCfg
.Vbit
= 1;
2185 mb
->un
.varUpdateCfg
.Obit
= 1;
2186 mb
->un
.varUpdateCfg
.cfg_data
= DL_FROM_SLIM_OFFSET
;
2187 mb
->un
.varUpdateCfg
.req_type
= UPDATE_DATA
;
2188 mb
->un
.varUpdateCfg
.region_id
= region_id
;
2189 mb
->un
.varUpdateCfg
.entry_len
= size
;
2190 mb
->un
.varUpdateCfg
.byte_len
= size
;
2191 mbq
->mbox_cmpl
= NULL
;
2193 } /* emlxs_format_update_pci_cfg() */
2198 emlxs_update_boot_wakeup_parms(emlxs_hba_t
*hba
, PWAKE_UP_PARMS WakeUpParms
,
2199 PROG_ID
* prog_id
, uint32_t proc_erom
)
2201 emlxs_port_t
*port
= &PPORT
;
2205 PROG_ID old_prog_id
;
2207 if ((mbox
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
2208 KM_NOSLEEP
)) == NULL
) {
2209 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2210 "Unable to allocate mailbox buffer.");
2215 mb
= (MAILBOX
*)mbox
;
2217 if (proc_erom
&& !(hba
->model_info
.chip
&
2218 (EMLXS_DRAGONFLY_CHIP
| EMLXS_CENTAUR_CHIP
))) {
2219 WakeUpParms
->u1
.EROM_prog_id
= *prog_id
;
2220 (void) emlxs_update_exp_rom(hba
, WakeUpParms
);
2223 old_prog_id
= WakeUpParms
->u0
.boot_bios_id
;
2224 WakeUpParms
->u0
.boot_bios_id
= *prog_id
;
2226 emlxs_format_update_parms(mbox
, WakeUpParms
);
2228 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) != MBX_SUCCESS
) {
2229 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2230 "Unable to update boot wakeup parms: Mailbox cmd=%x "
2231 "status=%x", mb
->mbxCommand
, mb
->mbxStatus
);
2233 WakeUpParms
->u0
.boot_bios_id
= old_prog_id
;
2238 kmem_free(mbox
, sizeof (MAILBOXQ
));
2243 } /* emlxs_update_boot_wakeup_parms() */
2248 emlxs_update_ff_wakeup_parms(emlxs_hba_t
*hba
, PWAKE_UP_PARMS WakeUpParms
,
2251 emlxs_port_t
*port
= &PPORT
;
2255 PROG_ID old_prog_id
;
2257 if ((mbox
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
2258 KM_NOSLEEP
)) == NULL
) {
2259 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2260 "Unable to allocate mailbox buffer.");
2265 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
2266 "FF: Updating parms...");
2268 mb
= (MAILBOX
*)mbox
;
2270 old_prog_id
= WakeUpParms
->prog_id
;
2271 WakeUpParms
->prog_id
= *prog_id
;
2273 emlxs_format_update_parms(mbox
, WakeUpParms
);
2275 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) != MBX_SUCCESS
) {
2276 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2277 "Unable to update wakeup parameters: Mailbox cmd=%x "
2278 "status=%x", mb
->mbxCommand
, mb
->mbxStatus
);
2280 WakeUpParms
->prog_id
= old_prog_id
;
2285 kmem_free(mbox
, sizeof (MAILBOXQ
));
2290 } /* emlxs_update_ff_wakeup_parms() */
2294 emlxs_update_sli1_wakeup_parms(emlxs_hba_t
*hba
, PWAKE_UP_PARMS WakeUpParms
,
2297 emlxs_port_t
*port
= &PPORT
;
2301 PROG_ID old_prog_id
;
2303 if ((mbox
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
2304 KM_NOSLEEP
)) == NULL
) {
2305 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2306 "Unable to allocate mailbox buffer.");
2311 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
2312 "SLI1: Updating parms...");
2314 mb
= (MAILBOX
*)mbox
;
2316 old_prog_id
= WakeUpParms
->sli1_prog_id
;
2317 WakeUpParms
->sli1_prog_id
= *prog_id
;
2319 emlxs_format_update_parms(mbox
, WakeUpParms
);
2321 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) != MBX_SUCCESS
) {
2322 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2323 "Unable to update wakeup parameters. Mailbox cmd=%x "
2324 "status=%x", mb
->mbxCommand
, mb
->mbxStatus
);
2326 WakeUpParms
->sli1_prog_id
= old_prog_id
;
2331 kmem_free(mbox
, sizeof (MAILBOXQ
));
2336 } /* emlxs_update_sli1_wakeup_parms() */
2340 emlxs_update_sli2_wakeup_parms(emlxs_hba_t
*hba
, PWAKE_UP_PARMS WakeUpParms
,
2343 emlxs_port_t
*port
= &PPORT
;
2347 PROG_ID old_prog_id
;
2349 if ((mbox
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
2350 KM_NOSLEEP
)) == NULL
) {
2351 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2352 "Unable to allocate mailbox buffer.");
2357 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
2358 "SLI2: Updating parms...");
2360 mb
= (MAILBOX
*)mbox
;
2362 old_prog_id
= WakeUpParms
->sli2_prog_id
;
2363 WakeUpParms
->sli2_prog_id
= *prog_id
;
2365 emlxs_format_update_parms(mbox
, WakeUpParms
);
2367 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) != MBX_SUCCESS
) {
2368 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2369 "Unable to update wakeup parameters. Mailbox cmd=%x "
2370 "status=%x", mb
->mbxCommand
, mb
->mbxStatus
);
2372 WakeUpParms
->sli2_prog_id
= old_prog_id
;
2377 kmem_free(mbox
, sizeof (MAILBOXQ
));
2382 } /* emlxs_update_sli2_wakeup_parms() */
2386 emlxs_update_sli3_wakeup_parms(emlxs_hba_t
*hba
, PWAKE_UP_PARMS WakeUpParms
,
2389 emlxs_port_t
*port
= &PPORT
;
2393 PROG_ID old_prog_id
;
2395 if ((mbox
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
2396 KM_NOSLEEP
)) == NULL
) {
2397 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2398 "Unable to allocate mailbox buffer.");
2403 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
2404 "SLI3: Updating parms...");
2406 mb
= (MAILBOX
*)mbox
;
2408 old_prog_id
= WakeUpParms
->sli3_prog_id
;
2409 WakeUpParms
->sli3_prog_id
= *prog_id
;
2411 emlxs_format_update_parms(mbox
, WakeUpParms
);
2413 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) != MBX_SUCCESS
) {
2414 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2415 "Unable to update wakeup parameters. Mailbox cmd=%x "
2416 "status=%x", mb
->mbxCommand
, mb
->mbxStatus
);
2418 WakeUpParms
->sli3_prog_id
= old_prog_id
;
2423 kmem_free(mbox
, sizeof (MAILBOXQ
));
2428 } /* emlxs_update_sli3_wakeup_parms() */
2432 emlxs_update_sli4_wakeup_parms(emlxs_hba_t
*hba
, PWAKE_UP_PARMS WakeUpParms
,
2435 emlxs_port_t
*port
= &PPORT
;
2439 PROG_ID old_prog_id
;
2441 if ((mbox
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
2442 KM_NOSLEEP
)) == NULL
) {
2443 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2444 "Unable to allocate mailbox buffer.");
2449 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
2450 "SLI4: Updating parms...");
2452 mb
= (MAILBOX
*)mbox
;
2454 old_prog_id
= WakeUpParms
->sli4_prog_id
;
2455 WakeUpParms
->sli4_prog_id
= *prog_id
;
2457 emlxs_format_update_parms(mbox
, WakeUpParms
);
2459 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) != MBX_SUCCESS
) {
2460 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2461 "Unable to update wakeup parameters. Mailbox cmd=%x "
2462 "status=%x", mb
->mbxCommand
, mb
->mbxStatus
);
2464 WakeUpParms
->sli4_prog_id
= old_prog_id
;
2469 kmem_free(mbox
, sizeof (MAILBOXQ
));
2474 } /* emlxs_update_sli4_wakeup_parms() */
2478 emlxs_clean_flash(emlxs_hba_t
*hba
,
2479 PWAKE_UP_PARMS OldWakeUpParms
, PWAKE_UP_PARMS NewWakeUpParms
)
2481 emlxs_port_t
*port
= &PPORT
;
2482 PROG_ID load_list
[MAX_LOAD_ENTRY
];
2483 PROG_ID
*wakeup_list
[MAX_LOAD_ENTRY
];
2490 if (!NewWakeUpParms
) {
2494 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
2495 "Cleaning flash...");
2497 /* If old wakeup parameter list is available, */
2498 /* then cleanup old entries */
2499 if (OldWakeUpParms
) {
2500 if (bcmp(&OldWakeUpParms
->prog_id
, &NewWakeUpParms
->prog_id
,
2501 sizeof (PROG_ID
))) {
2503 wptr
= (uint32_t *)&OldWakeUpParms
->prog_id
;
2504 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
2505 "OLD: prog_id: 0x%08x 0x%08x Removing.",
2508 (void) emlxs_delete_load_entry(hba
,
2509 &OldWakeUpParms
->prog_id
);
2512 if (bcmp(&OldWakeUpParms
->u0
.boot_bios_id
,
2513 &NewWakeUpParms
->u0
.boot_bios_id
, sizeof (PROG_ID
))) {
2515 wptr
= (uint32_t *)&OldWakeUpParms
->u0
.boot_bios_id
;
2516 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
2517 "OLD: boot_bios_id: 0x%08x 0x%08x Removing.",
2520 (void) emlxs_delete_load_entry(hba
,
2521 &OldWakeUpParms
->u0
.boot_bios_id
);
2524 if (bcmp(&OldWakeUpParms
->sli1_prog_id
,
2525 &NewWakeUpParms
->sli1_prog_id
, sizeof (PROG_ID
))) {
2527 wptr
= (uint32_t *)&OldWakeUpParms
->sli1_prog_id
;
2528 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
2529 "OLD: sli1_prog_id: 0x%08x 0x%08x Removing.",
2532 (void) emlxs_delete_load_entry(hba
,
2533 &OldWakeUpParms
->sli1_prog_id
);
2536 if (bcmp(&OldWakeUpParms
->sli2_prog_id
,
2537 &NewWakeUpParms
->sli2_prog_id
, sizeof (PROG_ID
))) {
2539 wptr
= (uint32_t *)&OldWakeUpParms
->sli2_prog_id
;
2540 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
2541 "OLD: sli2_prog_id: 0x%08x 0x%08x Removing.",
2544 (void) emlxs_delete_load_entry(hba
,
2545 &OldWakeUpParms
->sli2_prog_id
);
2548 if (bcmp(&OldWakeUpParms
->sli3_prog_id
,
2549 &NewWakeUpParms
->sli3_prog_id
, sizeof (PROG_ID
))) {
2551 wptr
= (uint32_t *)&OldWakeUpParms
->sli3_prog_id
;
2552 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
2553 "OLD: sli3_prog_id: 0x%08x 0x%08x Removing.",
2556 (void) emlxs_delete_load_entry(hba
,
2557 &OldWakeUpParms
->sli3_prog_id
);
2560 if (bcmp(&OldWakeUpParms
->sli4_prog_id
,
2561 &NewWakeUpParms
->sli4_prog_id
, sizeof (PROG_ID
))) {
2563 wptr
= (uint32_t *)&OldWakeUpParms
->sli4_prog_id
;
2564 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
2565 "OLD: sli4_prog_id: 0x%08x 0x%08x Removing.",
2568 (void) emlxs_delete_load_entry(hba
,
2569 &OldWakeUpParms
->sli4_prog_id
);
2575 /* Otherwise use the current load list */
2576 count
= emlxs_get_load_list(hba
, load_list
);
2582 /* Init the wakeup list */
2583 wptr
= (uint32_t *)&NewWakeUpParms
->prog_id
;
2585 wakeup_list
[k
++] = &NewWakeUpParms
->prog_id
;
2588 wptr
= (uint32_t *)&NewWakeUpParms
->u0
.boot_bios_id
;
2590 wakeup_list
[k
++] = &NewWakeUpParms
->u0
.boot_bios_id
;
2593 wptr
= (uint32_t *)&NewWakeUpParms
->sli1_prog_id
;
2595 wakeup_list
[k
++] = &NewWakeUpParms
->sli1_prog_id
;
2598 wptr
= (uint32_t *)&NewWakeUpParms
->sli2_prog_id
;
2600 wakeup_list
[k
++] = &NewWakeUpParms
->sli2_prog_id
;
2603 wptr
= (uint32_t *)&NewWakeUpParms
->sli3_prog_id
;
2605 wakeup_list
[k
++] = &NewWakeUpParms
->sli3_prog_id
;
2608 wptr
= (uint32_t *)&NewWakeUpParms
->sli4_prog_id
;
2610 wakeup_list
[k
++] = &NewWakeUpParms
->sli4_prog_id
;
2617 /* Match load list to wakeup list */
2618 for (i
= 0; i
< count
; i
++) {
2620 wptr
= (uint32_t *)&load_list
[i
];
2622 for (j
= 0; j
< k
; j
++) {
2623 if (bcmp((uint8_t *)wakeup_list
[j
],
2624 (uint8_t *)&load_list
[i
], sizeof (PROG_ID
)) == 0) {
2631 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
2632 "Load List[%d]: %08x %08x Removing.",
2633 i
, wptr
[0], wptr
[1]);
2635 (void) emlxs_delete_load_entry(hba
, &load_list
[i
]);
2637 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
2638 "Load List[%d]: %08x %08x Preserving.",
2639 i
, wptr
[0], wptr
[1]);
2645 } /* emlxs_clean_flash() */
2650 emlxs_start_rel_download(emlxs_hba_t
*hba
,
2651 PIMAGE_HDR ImageHdr
,
2653 PWAKE_UP_PARMS WakeUpParms
,
2656 emlxs_port_t
*port
= &PPORT
;
2661 caddr_t DataBuffer
= NULL
;
2663 uint32_t DlByteCount
;
2664 uint32_t SegSize
= DL_SLIM_SEG_BYTE_COUNT
;
2669 wptr
= (uint32_t *)&ImageHdr
->Id
;
2670 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
2671 "Relative download: %08x %08x", wptr
[0], wptr
[1]);
2673 if ((DataBuffer
= (caddr_t
)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT
,
2674 KM_NOSLEEP
)) == NULL
) {
2675 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2676 "Unable to allocate data buffer.");
2681 if ((mbox
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
2682 KM_NOSLEEP
)) == NULL
) {
2683 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2684 "Unable to allocate mailbox buffer.");
2686 kmem_free(DataBuffer
, DL_SLIM_SEG_BYTE_COUNT
);
2691 mb
= (MAILBOX
*)mbox
;
2693 DlByteCount
= ImageHdr
->BlockSize
;
2695 emlxs_format_prog_flash(mbox
, 0, DlByteCount
, ERASE_FLASH
, 0, 0, 0,
2698 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
2699 " Erasing flash...");
2701 rval
= EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0);
2704 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2705 "Unable to erase flash. Mailbox cmd=%x status=%x",
2706 mb
->mbxCommand
, mb
->mbxStatus
);
2708 goto EXIT_REL_DOWNLOAD
;
2711 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
2712 " Programming flash...");
2714 while (DlByteCount
) {
2715 if (DlByteCount
> SegSize
) {
2718 DlCount
= DlByteCount
;
2720 DlByteCount
-= DlCount
;
2722 Dst
= (uint32_t *)DataBuffer
;
2723 Src
= (uint32_t *)Buffer
;
2725 for (i
= 0; i
< (DlCount
/ 4); i
++) {
2731 WRITE_SLIM_COPY(hba
, (uint32_t *)DataBuffer
,
2732 (volatile uint32_t *)
2733 ((volatile char *)hba
->sli
.sli3
.slim_addr
+
2734 sizeof (MAILBOX
)), (DlCount
/ sizeof (uint32_t)));
2736 emlxs_format_prog_flash(mbox
,
2740 (DlByteCount
) ? 0 : 1,
2741 0, DlCount
, &ImageHdr
->Id
, dwc_flag
);
2743 rval
= EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0);
2746 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2747 "Unable to program flash. Mailbox cmd=%x status=%x",
2748 mb
->mbxCommand
, mb
->mbxStatus
);
2750 goto EXIT_REL_DOWNLOAD
;
2757 if (emlxs_fm_check_acc_handle(hba
, hba
->sli
.sli3
.slim_acc_handle
)
2759 EMLXS_MSGF(EMLXS_CONTEXT
,
2760 &emlxs_invalid_access_handle_msg
, NULL
);
2764 goto EXIT_REL_DOWNLOAD
;
2766 #endif /* FMA_SUPPORT */
2768 /* Update wakeup parameters */
2769 switch (ImageHdr
->Id
.Type
) {
2775 rval
= emlxs_update_ff_wakeup_parms(hba
, WakeUpParms
,
2778 WakeUpParms
->prog_id
= ImageHdr
->Id
;
2784 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
2785 "BOOT: Updating parms...");
2787 rval
= emlxs_update_boot_wakeup_parms(hba
, WakeUpParms
,
2790 if (hba
->wakeup_parms
.u0
.boot_bios_wd
[0]) {
2791 WakeUpParms
->u0
.boot_bios_id
= ImageHdr
->Id
;
2794 if (!(hba
->model_info
.chip
&
2795 (EMLXS_DRAGONFLY_CHIP
| EMLXS_CENTAUR_CHIP
))) {
2796 WakeUpParms
->u1
.EROM_prog_id
= ImageHdr
->Id
;
2803 rval
= emlxs_update_sli1_wakeup_parms(hba
, WakeUpParms
,
2806 WakeUpParms
->sli1_prog_id
= ImageHdr
->Id
;
2812 rval
= emlxs_update_sli2_wakeup_parms(hba
, WakeUpParms
,
2815 WakeUpParms
->sli2_prog_id
= ImageHdr
->Id
;
2821 rval
= emlxs_update_sli3_wakeup_parms(hba
, WakeUpParms
,
2824 WakeUpParms
->sli3_prog_id
= ImageHdr
->Id
;
2830 rval
= emlxs_update_sli4_wakeup_parms(hba
, WakeUpParms
,
2833 WakeUpParms
->sli4_prog_id
= ImageHdr
->Id
;
2838 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_incompat_msg
,
2839 "Image type not supported. Type=%x", ImageHdr
->Id
.Type
);
2846 kmem_free(DataBuffer
, DL_SLIM_SEG_BYTE_COUNT
);
2850 kmem_free(mbox
, sizeof (MAILBOXQ
));
2855 } /* emlxs_start_rel_download() */
2859 emlxs_proc_rel_2mb(emlxs_hba_t
*hba
, caddr_t buffer
, emlxs_fw_image_t
*fw_image
)
2861 emlxs_port_t
*port
= &PPORT
;
2863 WAKE_UP_PARMS RelWakeUpParms
;
2864 WAKE_UP_PARMS WakeUpParms
;
2868 uint32_t flash_cleaned
= 0;
2870 if (emlxs_read_wakeup_parms(hba
, &WakeUpParms
, 0)) {
2871 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2872 "Unable to get wakeup parameters.");
2874 return (EMLXS_IMAGE_FAILED
);
2879 bcopy(&WakeUpParms
, &RelWakeUpParms
, sizeof (WAKE_UP_PARMS
));
2881 for (i
= 0; i
< MAX_PROG_TYPES
; i
++) {
2882 if (!fw_image
->prog
[i
].version
) {
2886 bptr
= buffer
+ fw_image
->prog
[i
].offset
;
2888 bcopy(bptr
, &ImageHdr
, sizeof (IMAGE_HDR
));
2890 rval
= emlxs_start_rel_download(hba
, &ImageHdr
, bptr
,
2891 &RelWakeUpParms
, 1);
2894 EMLXS_MSGF(EMLXS_CONTEXT
,
2895 &emlxs_download_failed_msg
,
2896 "Failed to program flash.");
2898 if ((rval
== NO_FLASH_MEM_AVAIL
) && !flash_cleaned
) {
2899 /* Cleanup using current load list */
2900 (void) emlxs_clean_flash(hba
, 0, &WakeUpParms
);
2906 return (EMLXS_IMAGE_FAILED
);
2910 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_detail_msg
,
2911 "Updating wakeup parameters.");
2913 if (emlxs_update_wakeup_parms(hba
, &RelWakeUpParms
,
2915 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
2916 "Unable to update parameters.");
2918 return (EMLXS_IMAGE_FAILED
);
2921 /* Cleanup using old wakeup paramters */
2922 (void) emlxs_clean_flash(hba
, &WakeUpParms
, &RelWakeUpParms
);
2926 } /* emlxs_proc_rel_2mb() */
2929 #define FLASH_POLLING_BIT 0x80
2930 #define FLASH_ERROR_BIT 0x20
2932 typedef struct _flash_t
2941 emlxs_write_fcode_flash(emlxs_hba_t
*hba
,
2942 PIMAGE_HDR ImageHdr
, caddr_t Buffer
)
2944 emlxs_port_t
*port
= &PPORT
;
2948 uint32_t DlByteCount
= ImageHdr
->BlockSize
;
2960 src
= (uint8_t *)Buffer
+ sizeof (IMAGE_HDR
);
2961 for (i
= 0; i
< DlByteCount
; i
++) {
2962 for (k
= 0; k
< 3; k
++) {
2963 SBUS_WRITE_FLASH_COPY(hba
, wr
[k
].offset
, wr
[k
].val
);
2966 /* Reverse Endian word alignment */
2975 SBUS_WRITE_FLASH_COPY(hba
, i
, bb
);
2977 /* check for complete */
2981 cc
= SBUS_READ_FLASH_COPY(hba
, i
);
2983 /* If data matches then continue */
2988 /* Polling bit will be inverse final value */
2990 if ((cc
^ bb
) & FLASH_POLLING_BIT
) {
2993 /* Check for error bit */
2994 if (cc
& FLASH_ERROR_BIT
) {
2995 /* Read data one more time */
2996 cc
= SBUS_READ_FLASH_COPY(hba
, i
);
2998 /* Check if data matches */
3003 EMLXS_MSGF(EMLXS_CONTEXT
,
3004 &emlxs_download_failed_msg
,
3005 "FCode write error: offset:%x "
3006 "wrote:%x read:%x\n", i
, bb
, cc
);
3015 src
= (uint8_t *)ImageHdr
;
3017 for (i
= (0xFFFF - sizeof (IMAGE_HDR
)); i
< 0xFFFF; i
++) {
3018 for (k
= 0; k
< 3; k
++) {
3019 SBUS_WRITE_FLASH_COPY(hba
, wr
[k
].offset
, wr
[k
].val
);
3022 /* Reverse Endian word alignment */
3031 SBUS_WRITE_FLASH_COPY(hba
, i
, bb
);
3033 /* check for complete */
3037 cc
= SBUS_READ_FLASH_COPY(hba
, i
);
3039 /* If data matches then continue */
3044 /* Polling bit will be inverse final value */
3046 if ((cc
^ bb
) & FLASH_POLLING_BIT
) {
3049 /* Check for error bit */
3050 if (cc
& FLASH_ERROR_BIT
) {
3051 /* Read data one more time */
3052 cc
= SBUS_READ_FLASH_COPY(hba
, i
);
3054 /* Check if data matches */
3059 EMLXS_MSGF(EMLXS_CONTEXT
,
3060 &emlxs_download_failed_msg
,
3061 "FCode write error: offset:%x "
3062 "wrote:%x read:%x\n", i
, bb
, cc
);
3071 if (emlxs_fm_check_acc_handle(hba
, hba
->sli
.sli3
.sbus_flash_acc_handle
)
3073 EMLXS_MSGF(EMLXS_CONTEXT
,
3074 &emlxs_invalid_access_handle_msg
, NULL
);
3077 #endif /* FMA_SUPPORT */
3081 } /* emlxs_write_fcode_flash() */
3086 emlxs_erase_fcode_flash(emlxs_hba_t
*hba
)
3088 emlxs_port_t
*port
= &PPORT
;
3110 /* Check Manufacturers Code */
3111 for (i
= 0; i
< 3; i
++) {
3112 SBUS_WRITE_FLASH_COPY(hba
, as
[i
].offset
, as
[i
].val
);
3115 cc
= SBUS_READ_FLASH_COPY(hba
, 0);
3117 /* Check Device Code */
3118 for (i
= 0; i
< 3; i
++) {
3119 SBUS_WRITE_FLASH_COPY(hba
, as
[i
].offset
, as
[i
].val
);
3122 cc
= SBUS_READ_FLASH_COPY(hba
, 1);
3125 /* Check block protections (up to 4 16K blocks = 64K) */
3126 for (j
= 0; j
< 4; j
++) {
3127 for (i
= 0; i
< 3; i
++) {
3128 SBUS_WRITE_FLASH_COPY(hba
, as
[i
].offset
, as
[i
].val
);
3131 offset
= (j
<< 14) | 0x2;
3133 cc
= SBUS_READ_FLASH_COPY(hba
, offset
);
3136 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
3137 "Block %d is protected and can't be erased.", j
);
3141 /* Write erase flash sequence */
3142 for (i
= 0; i
< 6; i
++) {
3143 SBUS_WRITE_FLASH_COPY(hba
, ef
[i
].offset
, ef
[i
].val
);
3146 /* check for complete */
3148 /* Delay 3 seconds */
3151 cc
= SBUS_READ_FLASH_COPY(hba
, 0);
3154 /* If data matches then continue; */
3159 /* Polling bit will be inverse final value while active */
3160 if ((cc
^ 0xff) & FLASH_POLLING_BIT
) {
3163 /* Check for error bit */
3164 if (cc
& FLASH_ERROR_BIT
) {
3165 /* Read data one more time */
3166 cc
= SBUS_READ_FLASH_COPY(hba
, 0);
3168 /* Check if data matches */
3173 EMLXS_MSGF(EMLXS_CONTEXT
,
3174 &emlxs_download_failed_msg
,
3175 "FCode write error: offset:%x wrote:%x "
3176 "read:%x\n", i
, 0xff, cc
);
3184 if (emlxs_fm_check_acc_handle(hba
, hba
->sli
.sli3
.sbus_flash_acc_handle
)
3186 EMLXS_MSGF(EMLXS_CONTEXT
,
3187 &emlxs_invalid_access_handle_msg
, NULL
);
3190 #endif /* FMA_SUPPORT */
3194 } /* emlxs_erase_fcode_flash() */
3198 emlxs_delete_load_entry(emlxs_hba_t
*hba
, PROG_ID
*progId
)
3200 emlxs_port_t
*port
= &PPORT
;
3201 MAILBOXQ
*mbox
= NULL
;
3205 if ((mbox
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
3206 KM_NOSLEEP
)) == NULL
) {
3207 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
3208 "Unable to allocate mailbox buffer.");
3213 mb
= (MAILBOX
*)mbox
;
3214 mb
->mbxCommand
= MBX_DEL_LD_ENTRY
;
3215 mb
->un
.varDelLdEntry
.list_req
= FLASH_LOAD_LIST
;
3216 mb
->un
.varDelLdEntry
.prog_id
= *progId
;
3218 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) != MBX_SUCCESS
) {
3219 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
3220 "Unable to delete load entry: Mailbox cmd=%x status=%x",
3221 mb
->mbxCommand
, mb
->mbxStatus
);
3229 kmem_free(mbox
, sizeof (MAILBOXQ
));
3234 } /* emlxs_delete_load_entry() */
3238 emlxs_get_load_list(emlxs_hba_t
*hba
, PROG_ID
*load_list
)
3240 emlxs_port_t
*port
= &PPORT
;
3241 LOAD_ENTRY
*LoadEntry
;
3242 LOAD_LIST
*LoadList
= NULL
;
3246 bzero(load_list
, (sizeof (PROG_ID
) * MAX_LOAD_ENTRY
));
3248 if ((LoadList
= (LOAD_LIST
*)kmem_zalloc(sizeof (LOAD_LIST
),
3249 KM_NOSLEEP
)) == NULL
) {
3250 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
3251 "Unable to allocate LOADLIST buffer.");
3256 if (emlxs_read_load_list(hba
, LoadList
)) {
3260 for (i
= 0; i
< LoadList
->entry_cnt
; i
++) {
3261 LoadEntry
= &LoadList
->load_entry
[i
];
3262 if ((LoadEntry
->un
.wd
[0] != 0) &&
3263 (LoadEntry
->un
.wd
[0] != 0xffffffff)) {
3264 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
3265 "Load List[%d]: %08x %08x", count
,
3266 LoadEntry
->un
.wd
[0], LoadEntry
->un
.wd
[1]);
3268 load_list
[count
++] = LoadEntry
->un
.id
;
3275 kmem_free(LoadList
, sizeof (LOAD_LIST
));
3280 } /* emlxs_get_load_list() */
3284 emlxs_read_wakeup_parms(emlxs_hba_t
*hba
, PWAKE_UP_PARMS WakeUpParms
,
3287 emlxs_port_t
*port
= &PPORT
;
3293 bzero(WakeUpParms
, sizeof (WAKE_UP_PARMS
));
3295 if ((mbox
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
3296 KM_NOSLEEP
)) == NULL
) {
3297 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
3298 "Unable to allocate mailbox buffer.");
3303 mb
= (MAILBOX
*)mbox
;
3305 emlxs_format_dump(hba
, mbox
,
3307 WAKE_UP_PARMS_REGION_ID
,
3308 sizeof (WAKE_UP_PARMS
) / sizeof (uint32_t), 0);
3310 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) != MBX_SUCCESS
) {
3311 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
3312 "Unable to get parameters: Mailbox cmd=%x status=%x",
3313 mb
->mbxCommand
, mb
->mbxStatus
);
3315 if (mb
->un
.varDmp
.word_cnt
== (uint32_t)CFG_DATA_NO_REGION
) {
3316 rval
= (uint32_t)CFG_DATA_NO_REGION
;
3321 if (hba
->sli_mode
== EMLXS_HBA_SLI4_MODE
) {
3322 EMLXS_MPDATA_SYNC(hba
->sli
.sli4
.dump_region
.dma_handle
,
3323 0, hba
->sli
.sli4
.dump_region
.size
,
3324 DDI_DMA_SYNC_FORKERNEL
);
3326 bcopy((caddr_t
)hba
->sli
.sli4
.dump_region
.virt
,
3327 (caddr_t
)WakeUpParms
, sizeof (WAKE_UP_PARMS
));
3329 bcopy((caddr_t
)&mb
->un
.varDmp
.resp_offset
,
3330 (caddr_t
)WakeUpParms
, sizeof (WAKE_UP_PARMS
));
3334 wd
= (uint32_t *)&WakeUpParms
->prog_id
;
3335 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
3336 "Wakeup: prog_id=%08x %08x", wd
[0], wd
[1]);
3338 wd
= (uint32_t *)&WakeUpParms
->u0
.boot_bios_id
;
3339 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
3340 "Wakeup: boot_bios_id=%08x %08x", wd
[0], wd
[1]);
3342 wd
= (uint32_t *)&WakeUpParms
->sli1_prog_id
;
3343 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
3344 "Wakeup: sli1_prog_id=%08x %08x", wd
[0], wd
[1]);
3346 wd
= (uint32_t *)&WakeUpParms
->sli2_prog_id
;
3347 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
3348 "Wakeup: sli2_prog_id=%08x %08x", wd
[0], wd
[1]);
3350 wd
= (uint32_t *)&WakeUpParms
->sli3_prog_id
;
3351 if (wd
[0] || wd
[1]) {
3352 EMLXS_MSGF(EMLXS_CONTEXT
,
3353 &emlxs_init_debug_msg
,
3354 "Wakeup: sli3_prog_id=%08x %08x", wd
[0],
3358 wd
= (uint32_t *)&WakeUpParms
->sli4_prog_id
;
3359 if (wd
[0] || wd
[1]) {
3360 EMLXS_MSGF(EMLXS_CONTEXT
,
3361 &emlxs_init_debug_msg
,
3362 "Wakeup: sli4_prog_id=%08x %08x", wd
[0],
3366 wd
= (uint32_t *)&WakeUpParms
->u1
.EROM_prog_id
;
3367 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
3368 "Wakeup: EROM_prog_id=%08x %08x", wd
[0], wd
[1]);
3370 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
3371 "Wakeup: pci_cfg_rsvd=%x",
3372 WakeUpParms
->pci_cfg_rsvd
);
3373 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
3374 "Wakeup: use_hdw_def=%x",
3375 WakeUpParms
->use_hdw_def
);
3376 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
3377 "Wakeup: pci_cfg_sel=%x",
3378 WakeUpParms
->pci_cfg_sel
);
3379 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
3380 "Wakeup: cfg_lookup=%x",
3381 WakeUpParms
->pci_cfg_lookup_sel
);
3388 kmem_free(mbox
, sizeof (MAILBOXQ
));
3392 if (hba
->sli_mode
== EMLXS_HBA_SLI4_MODE
) {
3393 if (emlxs_fm_check_dma_handle(hba
,
3394 hba
->sli
.sli4
.dump_region
.dma_handle
) != DDI_FM_OK
) {
3395 EMLXS_MSGF(EMLXS_CONTEXT
,
3396 &emlxs_invalid_dma_handle_msg
,
3397 "emlxs_read_wakeup_parms: hdl=%p",
3398 hba
->sli
.sli4
.dump_region
.dma_handle
);
3402 #endif /* FMA_SUPPORT */
3406 } /* emlxs_read_wakeup_parms() */
3410 emlxs_read_load_list(emlxs_hba_t
*hba
, LOAD_LIST
*LoadList
)
3412 emlxs_port_t
*port
= &PPORT
;
3413 LOAD_ENTRY
*LoadEntry
;
3415 uint32_t CurEntryAddr
;
3416 MAILBOXQ
*mbox
= NULL
;
3419 bzero((caddr_t
)LoadList
, sizeof (LOAD_LIST
));
3421 if ((mbox
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
3422 KM_NOSLEEP
)) == NULL
) {
3423 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
3424 "Unable to allocate mailbox buffer.");
3429 mb
= (MAILBOX
*)mbox
;
3431 emlxs_format_dump(hba
, mbox
, DMP_MEM_REG
, 0, 2, FLASH_LOAD_LIST_ADR
);
3433 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) != MBX_SUCCESS
) {
3434 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
3435 "Unable to get load list: Mailbox cmd=%x status=%x",
3436 mb
->mbxCommand
, mb
->mbxStatus
);
3441 if (hba
->sli_mode
== EMLXS_HBA_SLI4_MODE
) {
3442 EMLXS_MPDATA_SYNC(hba
->sli
.sli4
.dump_region
.dma_handle
, 0,
3443 hba
->sli
.sli4
.dump_region
.size
, DDI_DMA_SYNC_FORKERNEL
);
3444 Uptr
= (uint32_t *)hba
->sli
.sli4
.dump_region
.virt
;
3446 Uptr
= (uint32_t *)&mb
->un
.varDmp
.resp_offset
;
3449 LoadList
->head
= Uptr
[0];
3450 LoadList
->tail
= Uptr
[1];
3452 CurEntryAddr
= LoadList
->head
;
3454 while ((CurEntryAddr
!= FLASH_LOAD_LIST_ADR
) &&
3455 (LoadList
->entry_cnt
< MAX_LOAD_ENTRY
)) {
3456 LoadEntry
= &LoadList
->load_entry
[LoadList
->entry_cnt
];
3457 LoadList
->entry_cnt
++;
3459 emlxs_format_dump(hba
, mbox
,
3460 DMP_MEM_REG
, 0, FLASH_LOAD_ENTRY_SIZE
, CurEntryAddr
);
3462 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) !=
3464 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
3465 "Unable to get load list (%d): Mailbox cmd=%x "
3466 "status=%x", LoadList
->entry_cnt
, mb
->mbxCommand
,
3472 if (hba
->sli_mode
== EMLXS_HBA_SLI4_MODE
) {
3473 EMLXS_MPDATA_SYNC(hba
->sli
.sli4
.dump_region
.dma_handle
,
3474 0, hba
->sli
.sli4
.dump_region
.size
,
3475 DDI_DMA_SYNC_FORKERNEL
);
3476 Uptr
= (uint32_t *)hba
->sli
.sli4
.dump_region
.virt
;
3478 Uptr
= (uint32_t *)&mb
->un
.varDmp
.resp_offset
;
3481 LoadEntry
->next
= Uptr
[0];
3482 LoadEntry
->prev
= Uptr
[1];
3483 LoadEntry
->start_adr
= Uptr
[2];
3484 LoadEntry
->len
= Uptr
[3];
3485 LoadEntry
->un
.wd
[0] = Uptr
[4];
3486 LoadEntry
->un
.wd
[1] = Uptr
[5];
3488 /* update next current load entry address */
3489 CurEntryAddr
= LoadEntry
->next
;
3491 } /* end of while (not end of list) */
3496 kmem_free(mbox
, sizeof (MAILBOXQ
));
3500 if (hba
->sli_mode
== EMLXS_HBA_SLI4_MODE
) {
3501 if (emlxs_fm_check_dma_handle(hba
,
3502 hba
->sli
.sli4
.dump_region
.dma_handle
) != DDI_FM_OK
) {
3503 EMLXS_MSGF(EMLXS_CONTEXT
,
3504 &emlxs_invalid_dma_handle_msg
,
3505 "emlxs_read_load_list: hdl=%p",
3506 hba
->sli
.sli4
.dump_region
.dma_handle
);
3510 #endif /* FMA_SUPPORT */
3514 } /* emlxs_read_load_list() */
3520 emlxs_build_parms(caddr_t Buffer
,
3521 PWAKE_UP_PARMS AbsWakeUpParms
,
3522 uint32_t BufferSize
, PAIF_HDR AifHeader
)
3527 int32_t ChangeParams
= FALSE
;
3531 bzero((caddr_t
)AbsWakeUpParms
, sizeof (WAKE_UP_PARMS
));
3533 if ((AifHeader
->ImageBase
!= 0x20000) &&
3534 ((AifHeader
->RoSize
+ AifHeader
->RwSize
) <= 0x20000)) {
3538 NextImage
= SLI_IMAGE_START
- AifHeader
->ImageBase
;
3540 while (BufferSize
> NextImage
) {
3541 Sptr
= &Buffer
[NextImage
];
3542 Dptr
= (caddr_t
)&ImageHdr
;
3543 for (i
= 0; i
< sizeof (IMAGE_HDR
); i
++) {
3547 if (ImageHdr
.BlockSize
== 0xffffffff)
3550 switch (ImageHdr
.Id
.Type
) {
3554 AbsWakeUpParms
->prog_id
= ImageHdr
.Id
;
3555 ChangeParams
= TRUE
;
3558 AbsWakeUpParms
->u0
.boot_bios_id
= ImageHdr
.Id
;
3559 ChangeParams
= TRUE
;
3562 AbsWakeUpParms
->sli1_prog_id
= ImageHdr
.Id
;
3563 ChangeParams
= TRUE
;
3566 AbsWakeUpParms
->sli2_prog_id
= ImageHdr
.Id
;
3567 ChangeParams
= TRUE
;
3570 AbsWakeUpParms
->sli3_prog_id
= ImageHdr
.Id
;
3571 ChangeParams
= TRUE
;
3574 AbsWakeUpParms
->sli4_prog_id
= ImageHdr
.Id
;
3575 ChangeParams
= TRUE
;
3581 NextImage
+= ImageHdr
.BlockSize
;
3584 return (ChangeParams
);
3586 } /* emlxs_build_parms() */
3590 emlxs_update_wakeup_parms(emlxs_hba_t
*hba
,
3591 PWAKE_UP_PARMS AbsWakeUpParms
, PWAKE_UP_PARMS WakeUpParms
)
3593 emlxs_port_t
*port
= &PPORT
;
3598 if ((mbox
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
3599 KM_NOSLEEP
)) == NULL
) {
3600 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
3601 "Unable to allocate mailbox buffer.");
3606 mb
= (MAILBOX
*)mbox
;
3608 WakeUpParms
->prog_id
= AbsWakeUpParms
->prog_id
;
3609 WakeUpParms
->u0
.boot_bios_id
= AbsWakeUpParms
->u0
.boot_bios_id
;
3610 WakeUpParms
->sli1_prog_id
= AbsWakeUpParms
->sli1_prog_id
;
3611 WakeUpParms
->sli2_prog_id
= AbsWakeUpParms
->sli2_prog_id
;
3612 WakeUpParms
->sli3_prog_id
= AbsWakeUpParms
->sli3_prog_id
;
3613 WakeUpParms
->sli4_prog_id
= AbsWakeUpParms
->sli4_prog_id
;
3615 emlxs_format_update_parms(mbox
, WakeUpParms
);
3617 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) != MBX_SUCCESS
) {
3618 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
3619 "Unable to update wakeup parameters: Mailbox cmd=%x "
3620 "status=%x", mb
->mbxCommand
, mb
->mbxStatus
);
3626 kmem_free(mbox
, sizeof (MAILBOXQ
));
3631 } /* emlxs_update_wakeup_parms() */
3635 emlxs_validate_version(emlxs_hba_t
*hba
, emlxs_fw_file_t
*file
, uint32_t id
,
3636 uint32_t type
, char *file_type
)
3638 emlxs_port_t
*port
= &PPORT
;
3640 /* Create the version label */
3641 emlxs_decode_version(file
->version
, file
->label
);
3643 /* Process the DWC type */
3647 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
3648 "%s: TEST: offset=%08x version=%08x, %s", file_type
,
3649 file
->offset
, file
->version
, file
->label
);
3655 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
3656 "%s: BOOT: offset=%08x version=%08x, %s", file_type
,
3657 file
->offset
, file
->version
, file
->label
);
3659 if (!emlxs_bios_check(hba
, id
)) {
3660 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_incompat_msg
,
3661 "BOOT Check: Image not compatible with %s. id=%02x",
3662 hba
->model_info
.model
, id
);
3664 return (EMLXS_IMAGE_INCOMPATIBLE
);
3669 case FUNC_FIRMWARE
: /* Stub */
3671 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
3672 "%s: STUB: offset=%08x version=%08x, %s", file_type
,
3673 file
->offset
, file
->version
, file
->label
);
3675 if (!emlxs_stub_check(hba
, id
)) {
3676 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_incompat_msg
,
3677 "STUB Check: Image not compatible with %s. id=%02x",
3678 hba
->model_info
.model
, id
);
3680 return (EMLXS_IMAGE_INCOMPATIBLE
);
3687 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
3688 "%s: SLI1: offset=%08x version=%08x, %s", file_type
,
3689 file
->offset
, file
->version
, file
->label
);
3691 if (!emlxs_sli1_check(hba
, id
)) {
3692 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_incompat_msg
,
3693 "SLI1 Check: Image not compatible with %s. id=%02x",
3694 hba
->model_info
.model
, id
);
3696 return (EMLXS_IMAGE_INCOMPATIBLE
);
3703 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
3704 "%s: SLI2: offset=%08x version=%08x, %s", file_type
,
3705 file
->offset
, file
->version
, file
->label
);
3707 if (!emlxs_sli2_check(hba
, id
)) {
3708 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_incompat_msg
,
3709 "SLI2 Check: Image not compatible with %s. id=%02x",
3710 hba
->model_info
.model
, id
);
3712 return (EMLXS_IMAGE_INCOMPATIBLE
);
3719 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
3720 "%s: SLI3: offset=%08x version=%08x, %s", file_type
,
3721 file
->offset
, file
->version
, file
->label
);
3723 if (!emlxs_sli3_check(hba
, id
)) {
3724 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_incompat_msg
,
3725 "SLI3 Check: Image not compatible with %s. id=%02x",
3726 hba
->model_info
.model
, id
);
3728 return (EMLXS_IMAGE_INCOMPATIBLE
);
3735 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
3736 "%s: SLI4: offset=%08x version=%08x, %s", file_type
,
3737 file
->offset
, file
->version
, file
->label
);
3739 if (!emlxs_sli4_check(hba
, id
)) {
3740 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_incompat_msg
,
3741 "SLI4 Check: Image not compatible with %s. id=%02x",
3742 hba
->model_info
.model
, id
);
3744 return (EMLXS_IMAGE_INCOMPATIBLE
);
3751 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
3752 "%s: SBUS FCODE: offset=%08x version=%08x, %s",
3753 file_type
, file
->offset
, file
->version
, file
->label
);
3755 if (!emlxs_sbus_fcode_check(hba
, id
)) {
3756 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_incompat_msg
,
3757 "SBUS FCODE Check: Image not compatible with %s. "
3758 "id=%02x", hba
->model_info
.model
, id
);
3760 return (EMLXS_IMAGE_INCOMPATIBLE
);
3767 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_msg
,
3768 "%s: KERN: offset=%08x version=%08x, %s", file_type
,
3769 file
->offset
, file
->version
, file
->label
);
3771 if (!emlxs_kern_check(hba
, id
)) {
3772 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_incompat_msg
,
3773 "KERN Check: Image not compatible with %s. id=%02x",
3774 hba
->model_info
.model
, id
);
3776 return (EMLXS_IMAGE_INCOMPATIBLE
);
3782 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
3783 "%s: Image type not supported. type=%x", file_type
, type
);
3785 return (EMLXS_IMAGE_BAD
);
3790 } /* emlxs_validate_version() */
3794 emlxs_verify_image(emlxs_hba_t
*hba
, emlxs_fw_image_t
*fw_image
)
3796 emlxs_port_t
*port
= &PPORT
;
3797 emlxs_vpd_t
*vpd
= &VPD
;
3801 /* Check for AWC file */
3802 if (fw_image
->awc
.version
) {
3803 if (fw_image
->awc
.version
== vpd
->postKernRev
) {
3804 fw_image
->awc
.version
= 0;
3807 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
3808 "AWC file: KERN: old=%s new=%s %s.",
3810 fw_image
->awc
.label
,
3811 (fw_image
->awc
.version
)? "Update":"Skip");
3814 /* Check for BWC file */
3815 if (fw_image
->bwc
.version
) {
3816 if (strcmp(vpd
->fcode_version
, fw_image
->bwc
.label
) == 0) {
3817 fw_image
->bwc
.version
= 0;
3820 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
3821 "BWC file: BOOT: old=%s new=%s %s.",
3823 fw_image
->bwc
.label
,
3824 (fw_image
->bwc
.version
)? "Update":"Skip");
3827 /* Check for DWC file */
3828 if (fw_image
->dwc
.version
) {
3829 /* Check for program files */
3831 for (i
= 0; i
< MAX_PROG_TYPES
; i
++) {
3832 if (!fw_image
->prog
[i
].version
) {
3836 /* Skip components that don't need updating */
3839 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
3840 "DWC file: TEST: new=%s "
3842 fw_image
->prog
[i
].label
);
3846 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
3847 "DWC file: BOOT: new=%s "
3849 fw_image
->prog
[i
].label
);
3854 (fw_image
->prog
[i
].version
==
3856 fw_image
->prog
[i
].version
= 0;
3859 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
3860 "DWC file: STUB: old=%s new=%s %s.",
3862 fw_image
->prog
[i
].label
,
3863 (fw_image
->prog
[i
].version
)?
3868 if (vpd
->sli1FwRev
&&
3869 (fw_image
->prog
[i
].version
==
3871 fw_image
->prog
[i
].version
= 0;
3874 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
3875 "DWC file: SLI1: old=%s new=%s %s.",
3877 fw_image
->prog
[i
].label
,
3878 (fw_image
->prog
[i
].version
)?
3883 if (vpd
->sli2FwRev
&&
3884 (fw_image
->prog
[i
].version
==
3886 fw_image
->prog
[i
].version
= 0;
3889 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
3890 "DWC file: SLI2: old=%s new=%s %s.",
3892 fw_image
->prog
[i
].label
,
3893 (fw_image
->prog
[i
].version
)?
3898 if (vpd
->sli3FwRev
&&
3899 (fw_image
->prog
[i
].version
==
3901 fw_image
->prog
[i
].version
= 0;
3904 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
3905 "DWC file: SLI3: old=%s new=%s %s.",
3907 fw_image
->prog
[i
].label
,
3908 (fw_image
->prog
[i
].version
)?
3913 if (vpd
->sli4FwRev
&&
3914 (fw_image
->prog
[i
].version
==
3916 fw_image
->prog
[i
].version
= 0;
3919 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
3920 "DWC file: SLI4: old=%s new=%s %s.",
3922 fw_image
->prog
[i
].label
,
3923 (fw_image
->prog
[i
].version
)?
3928 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
3929 "DWC file: type=%x version=%x label=%s "
3932 fw_image
->prog
[i
].version
,
3933 fw_image
->prog
[i
].label
);
3936 if (fw_image
->prog
[i
].version
) {
3942 fw_image
->dwc
.version
= 0;
3948 } /* emlxs_verify_image() */
3952 emlxs_validate_image(emlxs_hba_t
*hba
, caddr_t Buffer
, uint32_t Size
,
3953 emlxs_fw_image_t
*image
)
3955 emlxs_port_t
*port
= &PPORT
;
3962 uint32_t FileLen
= 0;
3963 uint32_t TotalLen
= 0;
3968 uint32_t ImageLength
;
3969 uint32_t BufferSize
;
3976 /* Get image type */
3977 ImageType
= *((uint32_t *)Buffer
);
3979 /* Pegasus and beyond adapters */
3980 if ((ImageType
== NOP_IMAGE_TYPE
) &&
3981 !(hba
->model_info
.chip
&
3982 (EMLXS_DRAGONFLY_CHIP
| EMLXS_CENTAUR_CHIP
))) {
3984 TotalLen
= sizeof (uint32_t);
3986 while (TotalLen
< Size
) {
3987 if (Size
< sizeof (AIF_HDR
)) {
3988 EMLXS_MSGF(EMLXS_CONTEXT
,
3989 &emlxs_image_bad_msg
,
3990 "Invalid image header length: 0x%x < 0x%x",
3991 Size
, sizeof (AIF_HDR
));
3993 return (EMLXS_IMAGE_BAD
);
3996 bcopy(bptr
, &AifHdr
, sizeof (AIF_HDR
));
3997 emlxs_disp_aif_header(hba
, &AifHdr
);
3999 ImageLength
= AifHdr
.RoSize
;
4001 /* Validate checksum */
4003 (uint32_t *)(bptr
+ ImageLength
+
4005 if (emlxs_valid_cksum((uint32_t *)bptr
, CkSumEnd
)) {
4006 EMLXS_MSGF(EMLXS_CONTEXT
,
4007 &emlxs_image_bad_msg
,
4008 "Invalid checksum found.");
4010 return (EMLXS_IMAGE_BAD
);
4013 FileType
= AifHdr
.ZinitBr
;
4017 (uint32_t)((uintptr_t)bptr
-
4019 image
->awc
.version
= AifHdr
.AVersion
;
4020 image
->awc
.revcomp
= 0;
4022 id
= (AifHdr
.AVersion
& 0x00ff0000) >> 16;
4023 type
= emlxs_type_check(
4024 (AifHdr
.AVersion
& 0xff000000) >> 24);
4026 /* Validate the file version */
4027 if ((rval
= emlxs_validate_version(hba
,
4028 &image
->awc
, id
, type
, "AWC file"))) {
4036 (uint32_t)((uintptr_t)bptr
-
4038 image
->bwc
.version
= AifHdr
.AVersion
;
4039 image
->bwc
.revcomp
= 0;
4041 id
= (AifHdr
.AVersion
& 0x00ff0000) >> 16;
4042 type
= emlxs_type_check(
4043 (AifHdr
.AVersion
& 0xff000000) >> 24);
4045 /* Validate the file version */
4046 if ((rval
= emlxs_validate_version(hba
,
4047 &image
->bwc
, id
, type
, "BWC file"))) {
4055 (uint32_t)((uintptr_t)bptr
-
4057 image
->dwc
.version
= AifHdr
.AVersion
;
4058 image
->dwc
.revcomp
= 0;
4060 id
= (AifHdr
.AVersion
& 0x00ff0000) >> 16;
4061 type
= emlxs_type_check(
4062 (AifHdr
.AVersion
& 0xff000000) >> 24);
4064 /* Validate the file version */
4065 if ((rval
= emlxs_validate_version(hba
,
4066 &image
->dwc
, id
, type
, "DWC file"))) {
4070 /* Scan for program types */
4071 NextImage
= sizeof (AIF_HDR
) + 4;
4072 BufferSize
= AifHdr
.RoSize
+ AifHdr
.RwSize
;
4075 while (BufferSize
> NextImage
) {
4076 bcopy(&bptr
[NextImage
], &ImageHdr
,
4077 sizeof (IMAGE_HDR
));
4078 emlxs_dump_image_header(hba
,
4081 /* Validate block size */
4082 if (ImageHdr
.BlockSize
== 0xffffffff) {
4086 type
= emlxs_type_check(
4089 /* Calculate the program offset */
4090 image
->prog
[type
].offset
=
4091 (uint32_t)((uintptr_t)
4095 /* Acquire the versions */
4096 image
->prog
[type
].version
=
4097 (ImageHdr
.Id
.Type
<< 24) |
4098 (ImageHdr
.Id
.Id
<< 16) |
4099 (ImageHdr
.Id
.Ver
<< 8) |
4102 image
->prog
[type
].revcomp
=
4103 ImageHdr
.Id
.un
.revcomp
;
4105 /* Validate the file version */
4106 if ((rval
= emlxs_validate_version(hba
,
4107 &image
->prog
[type
], ImageHdr
.Id
.Id
,
4108 type
, "DWC prog"))) {
4113 NextImage
+= ImageHdr
.BlockSize
;
4118 EMLXS_MSGF(EMLXS_CONTEXT
,
4119 &emlxs_image_bad_msg
,
4120 "DWC file has no PRG images.");
4122 return (EMLXS_IMAGE_BAD
);
4129 sizeof (AIF_HDR
) + ImageLength
+
4131 TotalLen
+= FileLen
;
4136 /* Pre-pegasus adapters */
4138 else if (ImageType
== NOP_IMAGE_TYPE
) {
4139 if (Size
< sizeof (AIF_HDR
)) {
4140 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
4141 "Invalid image header length: 0x%x < 0x%x", Size
,
4144 return (EMLXS_IMAGE_BAD
);
4147 bcopy(Buffer
, &AifHdr
, sizeof (AIF_HDR
));
4148 emlxs_disp_aif_header(hba
, &AifHdr
);
4150 ImageLength
= AifHdr
.RoSize
+ AifHdr
.RwSize
;
4152 if (Size
!= (sizeof (AIF_HDR
) + ImageLength
+ sizeof (int))) {
4153 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
4154 "Image length incorrect: 0x%x != 0x%x", Size
,
4155 sizeof (AIF_HDR
) + ImageLength
+
4158 return (EMLXS_IMAGE_BAD
);
4161 if (AifHdr
.ImageBase
&& AifHdr
.ImageBase
!= 0x20000) {
4162 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
4163 "Invalid imageBase value %x != 0x20000",
4166 return (EMLXS_IMAGE_BAD
);
4170 (uint32_t *)(Buffer
+ ImageLength
+ sizeof (AIF_HDR
));
4171 if (emlxs_valid_cksum((uint32_t *)Buffer
, CkSumEnd
)) {
4172 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
4173 "Invalid checksum found.");
4175 return (EMLXS_IMAGE_BAD
);
4178 image
->dwc
.offset
= 0;
4179 image
->dwc
.version
= AifHdr
.AVersion
;
4180 image
->dwc
.revcomp
= 0;
4182 id
= (AifHdr
.AVersion
& 0x00ff0000) >> 16;
4183 type
= emlxs_type_check((AifHdr
.AVersion
& 0xff000000) >> 24);
4185 /* Validate the file version */
4186 if ((rval
= emlxs_validate_version(hba
, &image
->dwc
, id
, type
,
4191 NextImage
= SLI_IMAGE_START
- AifHdr
.ImageBase
;
4192 while (Size
> NextImage
) {
4193 bcopy(&Buffer
[NextImage
], &ImageHdr
,
4194 sizeof (IMAGE_HDR
));
4195 emlxs_dump_image_header(hba
, &ImageHdr
);
4197 /* Validate block size */
4198 if (ImageHdr
.BlockSize
== 0xffffffff) {
4202 type
= emlxs_type_check(ImageHdr
.Id
.Type
);
4204 /* Calculate the program offset */
4205 image
->prog
[type
].offset
= NextImage
;
4207 /* Acquire the versions */
4208 image
->prog
[type
].version
=
4209 (ImageHdr
.Id
.Type
<< 24) |
4210 (ImageHdr
.Id
.Id
<< 16) |
4211 (ImageHdr
.Id
.Ver
<< 8) |
4214 image
->prog
[type
].revcomp
= ImageHdr
.Id
.un
.revcomp
;
4216 /* Validate the file version */
4217 if ((rval
= emlxs_validate_version(hba
,
4218 &image
->prog
[type
], ImageHdr
.Id
.Id
, type
,
4223 NextImage
+= ImageHdr
.BlockSize
;
4226 } else { /* PRG File */
4228 /* Precheck image size */
4229 if (Size
< sizeof (IMAGE_HDR
)) {
4230 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
4231 "Invalid image header length: 0x%x < 0x%x", Size
,
4232 sizeof (IMAGE_HDR
));
4234 return (EMLXS_IMAGE_BAD
);
4237 bcopy(Buffer
, &ImageHdr
, sizeof (IMAGE_HDR
));
4238 emlxs_dump_image_header(hba
, &ImageHdr
);
4240 /* Validate block size */
4241 if (ImageHdr
.BlockSize
== 0xffffffff) {
4242 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
4243 "Invalid block size.");
4245 return (EMLXS_IMAGE_BAD
);
4248 ImageLength
= ImageHdr
.BlockSize
;
4250 /* Validate image length */
4251 if (Size
!= ImageLength
) {
4252 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
4253 "Invalid image length: 0x%x != 0x%x", Size
,
4256 return (EMLXS_IMAGE_BAD
);
4259 /* Validate Checksum */
4261 (uint32_t *)Buffer
+ (ImageLength
/ sizeof (uint32_t)) -
4263 if (emlxs_valid_cksum((uint32_t *)Buffer
, CkSumEnd
)) {
4264 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
4265 "Invalid checksum found.");
4267 return (EMLXS_IMAGE_BAD
);
4270 type
= emlxs_type_check(ImageHdr
.Id
.Type
);
4272 /* Calculate the program offset */
4273 image
->prog
[type
].offset
= 0;
4275 /* Acquire the versions */
4276 image
->prog
[type
].version
=
4277 (ImageHdr
.Id
.Type
<< 24) |
4278 (ImageHdr
.Id
.Id
<< 16) |
4279 (ImageHdr
.Id
.Ver
<< 8) |
4282 image
->prog
[type
].revcomp
= ImageHdr
.Id
.un
.revcomp
;
4284 /* Validate the file version */
4285 if ((rval
= emlxs_validate_version(hba
, &image
->prog
[type
],
4286 ImageHdr
.Id
.Id
, type
, "DWC file"))) {
4292 * This checks if a DragonFly (pre-V2 ASIC) SLI2
4293 * image file is < version 3.8
4295 if (FC_JEDEC_ID(vpd
->biuRev
) == DRAGONFLY_JEDEC_ID
) {
4296 ver
= (image
->prog
[SLI2_OVERLAY
].version
&
4300 EMLXS_MSGF(EMLXS_CONTEXT
,
4301 &emlxs_image_incompat_msg
,
4302 "ASIC Check: Image requires DragonFly "
4305 return (EMLXS_IMAGE_INCOMPATIBLE
);
4311 } /* emlxs_validate_image() */
4315 emlxs_update_exp_rom(emlxs_hba_t
*hba
, PWAKE_UP_PARMS WakeUpParms
)
4317 emlxs_port_t
*port
= &PPORT
;
4320 uint32_t next_address
;
4323 if (WakeUpParms
->u1
.EROM_prog_wd
[0] == 0) {
4327 if ((mbox
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
4328 KM_NOSLEEP
)) == NULL
) {
4329 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
4330 "Unable to allocate mailbox buffer.");
4335 bzero(mbox
, sizeof (MAILBOXQ
));
4337 mb
= (MAILBOX
*)mbox
;
4338 mb
->mbxCommand
= MBX_LOAD_EXP_ROM
;
4339 mb
->un
.varLdExpRom
.step
= EROM_CMD_FIND_IMAGE
;
4340 mb
->un
.varLdExpRom
.progress
= 0;
4341 mb
->un
.varLdExpRom
.un
.prog_id
= WakeUpParms
->u1
.EROM_prog_id
;
4342 mbox
->mbox_cmpl
= NULL
;
4344 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) != MBX_SUCCESS
) {
4345 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
4346 "Unable to load exp ROM. Mailbox cmd=%x status=%x",
4347 mb
->mbxCommand
, mb
->mbxStatus
);
4351 goto SLI_DOWNLOAD_EXIT
;
4354 if (mb
->un
.varLdExpRom
.progress
== EROM_RSP_COPY_DONE
) {
4355 (void) emlxs_update_wakeup_parms(hba
, WakeUpParms
, WakeUpParms
);
4358 goto SLI_DOWNLOAD_EXIT
;
4361 if (mb
->un
.varLdExpRom
.progress
!= EROM_RSP_ERASE_STARTED
) {
4362 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
4363 "Invalid exp ROM progress. progress=%x",
4364 mb
->un
.varLdExpRom
.progress
);
4368 goto SLI_DOWNLOAD_EXIT
;
4374 while (mb
->un
.varLdExpRom
.progress
!= EROM_RSP_ERASE_COMPLETE
) {
4376 next_address
= mb
->un
.varLdExpRom
.dl_to_adr
;
4378 bzero((void *)mb
, MAILBOX_CMD_BSIZE
);
4380 mb
->mbxCommand
= MBX_LOAD_EXP_ROM
;
4381 mb
->un
.varLdExpRom
.step
= EROM_CMD_CONTINUE_ERASE
;
4382 mb
->un
.varLdExpRom
.dl_to_adr
= next_address
;
4383 mb
->un
.varLdExpRom
.progress
= 0;
4384 mb
->un
.varLdExpRom
.un
.prog_id
= WakeUpParms
->u1
.EROM_prog_id
;
4385 mbox
->mbox_cmpl
= NULL
;
4387 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) !=
4389 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
4390 "Unable to load exp ROM. Mailbox cmd=%x status=%x",
4391 mb
->mbxCommand
, mb
->mbxStatus
);
4394 goto SLI_DOWNLOAD_EXIT
;
4399 while (mb
->un
.varLdExpRom
.progress
!= EROM_RSP_COPY_DONE
) {
4400 next_address
= mb
->un
.varLdExpRom
.dl_to_adr
;
4402 bzero((void *)mb
, MAILBOX_CMD_BSIZE
);
4404 mb
->mbxCommand
= MBX_LOAD_EXP_ROM
;
4405 mb
->un
.varLdExpRom
.step
= EROM_CMD_COPY
;
4406 mb
->un
.varLdExpRom
.dl_to_adr
= next_address
;
4407 mb
->un
.varLdExpRom
.progress
= 0;
4408 mb
->un
.varLdExpRom
.un
.prog_id
= WakeUpParms
->u1
.EROM_prog_id
;
4409 mbox
->mbox_cmpl
= NULL
;
4411 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) !=
4413 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
4414 "Unable to load exp ROM. Mailbox cmd=%x status=%x",
4415 mb
->mbxCommand
, mb
->mbxStatus
);
4419 goto SLI_DOWNLOAD_EXIT
;
4423 rval
= emlxs_update_wakeup_parms(hba
, WakeUpParms
, WakeUpParms
);
4428 kmem_free(mbox
, sizeof (MAILBOXQ
));
4433 } /* emlxs_update_exp_rom() */
4438 * FUNCTION NAME: emlxs_start_abs_download_2mb
4440 * DESCRIPTION: Perform absolute download for 2 MB flash. A incoming
4441 * buffer may consist of more than 1 file. This function
4442 * will parse the buffer to find all the files.
4453 emlxs_start_abs_download_2mb(emlxs_hba_t
*hba
, caddr_t buffer
, uint32_t len
,
4454 uint32_t offline
, emlxs_fw_image_t
*fw_image
)
4456 emlxs_port_t
*port
= &PPORT
;
4459 /* If nothing to download then quit now */
4460 if (!fw_image
->awc
.version
&&
4461 !fw_image
->dwc
.version
&&
4462 !fw_image
->bwc
.version
) {
4463 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_msg
,
4464 "Nothing new to update. Exiting.");
4469 * Everything checks out, now to just do it
4472 if (emlxs_offline(hba
) != FC_SUCCESS
) {
4473 return (EMLXS_OFFLINE_FAILED
);
4476 if (EMLXS_SLI_HBA_RESET(hba
, 1, 1, 0) != FC_SUCCESS
) {
4477 return (EMLXS_OFFLINE_FAILED
);
4481 if (fw_image
->awc
.version
) {
4482 rval
= emlxs_proc_abs_2mb(hba
,
4483 (buffer
+ fw_image
->awc
.offset
),
4487 goto SLI_DOWNLOAD_2MB_EXIT
;
4491 if (fw_image
->bwc
.version
) {
4492 rval
= emlxs_proc_abs_2mb(hba
,
4493 (buffer
+ fw_image
->bwc
.offset
),
4495 (fw_image
->dwc
.version
)? ALLext
:BWCext
);
4498 goto SLI_DOWNLOAD_2MB_EXIT
;
4502 if (fw_image
->dwc
.version
) {
4503 rval
= emlxs_proc_rel_2mb(hba
, buffer
, fw_image
);
4506 goto SLI_DOWNLOAD_2MB_EXIT
;
4510 SLI_DOWNLOAD_2MB_EXIT
:
4513 (void) emlxs_online(hba
);
4518 } /* emlxs_start_abs_download_2mb() */
4523 * FUNCTION NAME: emlxs_proc_abs_2mb
4525 * DESCRIPTION: Given one of the 3 file types(awc/bwc/dwc), it will reset
4526 * the port and download the file with sliIssueMbCommand()
4536 emlxs_proc_abs_2mb(emlxs_hba_t
*hba
, caddr_t EntireBuffer
,
4537 uint32_t FileType
, uint32_t extType
)
4539 emlxs_port_t
*port
= &PPORT
;
4541 caddr_t Buffer
= NULL
;
4542 caddr_t DataBuffer
= NULL
;
4547 uint32_t DlByteCount
;
4549 uint32_t SegSize
= DL_SLIM_SEG_BYTE_COUNT
;
4552 WAKE_UP_PARMS AbsWakeUpParms
;
4555 uint32_t EraseByteCount
;
4557 uint32_t RspProgress
= 0;
4560 AifHdr
= (PAIF_HDR
)EntireBuffer
;
4561 DlByteCount
= AifHdr
->RoSize
+ AifHdr
->RwSize
;
4562 DlToAddr
= AifHdr
->ImageBase
;
4564 if ((DataBuffer
= (caddr_t
)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT
,
4565 KM_NOSLEEP
)) == NULL
) {
4566 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
4567 "%x: Unable to allocate data buffer.", FileType
);
4569 return (EMLXS_IMAGE_FAILED
);
4572 if ((mbox
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
4573 KM_NOSLEEP
)) == NULL
) {
4574 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
4575 "%x: Unable to allocate mailbox buffer.", FileType
);
4577 kmem_free(DataBuffer
, DL_SLIM_SEG_BYTE_COUNT
);
4579 return (EMLXS_IMAGE_FAILED
);
4582 mb
= (MAILBOX
*)mbox
;
4584 Buffer
= EntireBuffer
+ sizeof (AIF_HDR
);
4592 rval
= emlxs_build_parms_2mb_bwc(hba
,
4593 AifHdr
, extType
, &AbsWakeUpParms
);
4595 if (rval
== FALSE
) {
4596 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
4597 "BWC build parms failed.");
4599 rval
= EMLXS_IMAGE_FAILED
;
4601 goto EXIT_ABS_DOWNLOAD
;
4607 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_image_bad_msg
,
4608 "Invalid file type: %x", FileType
);
4610 rval
= EMLXS_IMAGE_BAD
;
4612 goto EXIT_ABS_DOWNLOAD
;
4615 EraseByteCount
= AifHdr
->Area_Size
;
4616 AreaId
= AifHdr
->Area_ID
;
4618 emlxs_format_load_area_cmd(mbox
,
4622 0, DL_FROM_SLIM_OFFSET
, AreaId
, MBX_LOAD_AREA
, CMD_START_ERASE
);
4624 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) != MBX_SUCCESS
) {
4625 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
4626 "%x: Could not erase 2MB Flash: Mailbox cmd=%x status=%x",
4627 FileType
, mb
->mbxCommand
, mb
->mbxStatus
);
4629 rval
= EMLXS_IMAGE_FAILED
;
4631 goto EXIT_ABS_DOWNLOAD
;
4634 while (mb
->un
.varLdArea
.progress
!= RSP_ERASE_COMPLETE
) {
4635 NextAddr
= mb
->un
.varLdArea
.dl_to_adr
;
4637 emlxs_format_load_area_cmd(mbox
,
4642 DL_FROM_SLIM_OFFSET
,
4643 AreaId
, MBX_LOAD_AREA
, CMD_CONTINUE_ERASE
);
4645 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) !=
4647 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
4648 "%x: Could not erase 2MB Flash2: Mailbox cmd=%x "
4649 "status=%x", FileType
, mb
->mbxCommand
,
4652 rval
= EMLXS_IMAGE_FAILED
;
4654 goto EXIT_ABS_DOWNLOAD
;
4658 while (DlByteCount
) {
4659 if (DlByteCount
>= SegSize
)
4662 DlCount
= DlByteCount
;
4664 DlByteCount
-= DlCount
;
4666 Dst
= (uint32_t *)DataBuffer
;
4667 Src
= (uint32_t *)Buffer
;
4669 for (i
= 0; i
< (DlCount
/ 4); i
++) {
4675 WRITE_SLIM_COPY(hba
, (uint32_t *)DataBuffer
,
4676 (volatile uint32_t *)((volatile char *)
4677 hba
->sli
.sli3
.slim_addr
+ sizeof (MAILBOX
)),
4678 (DlCount
/ sizeof (uint32_t)));
4680 if ((RspProgress
== RSP_DOWNLOAD_MORE
) || (RspProgress
== 0)) {
4681 emlxs_format_load_area_cmd(mbox
,
4685 (DlByteCount
) ? 0 : 1,
4686 DL_FROM_SLIM_OFFSET
,
4689 (DlByteCount
) ? CMD_DOWNLOAD
: CMD_END_DOWNLOAD
);
4691 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0) !=
4693 EMLXS_MSGF(EMLXS_CONTEXT
,
4694 &emlxs_download_failed_msg
,
4695 "%x: Could not program 2MB Flash: Mailbox "
4696 "cmd=%x status=%x", FileType
,
4697 mb
->mbxCommand
, mb
->mbxStatus
);
4699 rval
= EMLXS_IMAGE_FAILED
;
4701 goto EXIT_ABS_DOWNLOAD
;
4705 RspProgress
= mb
->un
.varLdArea
.progress
;
4708 DlToAddr
+= DlCount
;
4712 if (emlxs_fm_check_acc_handle(hba
, hba
->sli
.sli3
.slim_acc_handle
)
4714 EMLXS_MSGF(EMLXS_CONTEXT
,
4715 &emlxs_invalid_access_handle_msg
, NULL
);
4717 rval
= EMLXS_IMAGE_FAILED
;
4719 goto EXIT_ABS_DOWNLOAD
;
4721 #endif /* FMA_SUPPORT */
4723 if (RspProgress
!= RSP_DOWNLOAD_DONE
) {
4724 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
4725 "%x: Failed download response received. %x", FileType
,
4728 rval
= EMLXS_IMAGE_FAILED
;
4730 goto EXIT_ABS_DOWNLOAD
;
4734 if (emlxs_update_wakeup_parms(hba
, &AbsWakeUpParms
,
4736 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
4737 "%x: Unable to update parms.", FileType
);
4739 rval
= EMLXS_IMAGE_FAILED
;
4746 kmem_free(DataBuffer
, DL_SLIM_SEG_BYTE_COUNT
);
4750 kmem_free(mbox
, sizeof (MAILBOXQ
));
4755 } /* emlxs_proc_abs_2mb() */
4759 emlxs_format_load_area_cmd(MAILBOXQ
* mbq
,
4761 uint32_t DlByteCount
,
4764 uint32_t DataOffset
, uint32_t AreaId
, uint8_t MbxCmd
, uint32_t StepCmd
)
4766 MAILBOX
*mb
= (MAILBOX
*)mbq
;
4768 bzero((void *)mb
, MAILBOX_CMD_BSIZE
);
4770 mb
->mbxCommand
= MbxCmd
;
4771 mb
->mbxOwner
= OWN_HOST
;
4772 mb
->un
.varLdArea
.update_flash
= 1;
4773 mb
->un
.varLdArea
.erase_or_prog
= Function
;
4774 mb
->un
.varLdArea
.dl_to_adr
= Base
;
4775 mb
->un
.varLdArea
.dl_len
= DlByteCount
;
4776 mb
->un
.varLdArea
.load_cmplt
= Complete
;
4777 mb
->un
.varLdArea
.method
= DL_FROM_SLIM
;
4778 mb
->un
.varLdArea
.area_id
= AreaId
;
4779 mb
->un
.varLdArea
.step
= StepCmd
;
4780 mb
->un
.varLdArea
.un
.dl_from_slim_offset
= DataOffset
;
4781 mbq
->mbox_cmpl
= NULL
;
4783 } /* emlxs_format_load_area_cmd() */
4788 emlxs_build_parms_2mb_bwc(emlxs_hba_t
*hba
,
4789 PAIF_HDR AifHdr
, uint32_t extType
, PWAKE_UP_PARMS AbsWakeUpParms
)
4791 emlxs_port_t
*port
= &PPORT
;
4793 uint32_t returnStat
;
4795 /* Read wakeup paramters */
4796 if (emlxs_read_wakeup_parms(hba
, AbsWakeUpParms
, 0) ==
4797 (uint32_t)CFG_DATA_NO_REGION
) {
4798 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
4799 "Unable to get BWC parameters.");
4803 pId
[0] = AifHdr
->AVersion
;
4806 if (extType
== BWCext
) {
4807 AbsWakeUpParms
->u0
.boot_bios_wd
[0] = pId
[0];
4808 AbsWakeUpParms
->u0
.boot_bios_wd
[1] = pId
[1];
4809 AbsWakeUpParms
->u1
.EROM_prog_wd
[0] = pId
[0];
4810 AbsWakeUpParms
->u1
.EROM_prog_wd
[1] = pId
[1];
4813 else if (extType
== ALLext
) {
4814 if (!AbsWakeUpParms
->u0
.boot_bios_wd
[0]) {
4815 /* case of EROM inactive */
4816 AbsWakeUpParms
->u1
.EROM_prog_wd
[1] = pId
[1];
4817 AbsWakeUpParms
->u1
.EROM_prog_wd
[0] = pId
[0];
4819 /* case of EROM active */
4820 if (AbsWakeUpParms
->u0
.boot_bios_wd
[0] == pId
[0]) {
4822 AbsWakeUpParms
->u0
.boot_bios_wd
[0] = pId
[0];
4823 AbsWakeUpParms
->u0
.boot_bios_wd
[1] = pId
[1];
4824 AbsWakeUpParms
->u1
.EROM_prog_wd
[0] = pId
[0];
4825 AbsWakeUpParms
->u1
.EROM_prog_wd
[1] = pId
[1];
4828 AbsWakeUpParms
->u1
.EROM_prog_wd
[0] = pId
[0];
4829 AbsWakeUpParms
->u1
.EROM_prog_wd
[1] = pId
[1];
4832 emlxs_update_exp_rom(hba
, AbsWakeUpParms
);
4835 AbsWakeUpParms
->u0
.boot_bios_wd
[0] =
4837 AbsWakeUpParms
->u0
.boot_bios_wd
[1] =
4846 } /* emlxs_build_parms_2mb_bwc() */
4850 emlxs_get_max_sram(emlxs_hba_t
*hba
, uint32_t *MaxRbusSize
,
4851 uint32_t *MaxIbusSize
)
4853 emlxs_port_t
*port
= &PPORT
;
4867 if ((mbox
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
4868 KM_NOSLEEP
)) == NULL
) {
4869 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
4870 "Unable to allocate mailbox buffer.");
4875 mb
= (MAILBOX
*)mbox
;
4877 emlxs_format_dump(hba
, mbox
, DMP_MEM_REG
, 0, 2, MAX_RBUS_SRAM_SIZE_ADR
);
4879 if ((rval
= EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbox
, MBX_WAIT
, 0)) !=
4881 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_download_failed_msg
,
4882 "Unable to get SRAM size: Mailbox cmd=%x status=%x",
4883 mb
->mbxCommand
, mb
->mbxStatus
);
4890 if (hba
->sli_mode
== EMLXS_HBA_SLI4_MODE
) {
4891 EMLXS_MPDATA_SYNC(hba
->sli
.sli4
.dump_region
.dma_handle
, 0,
4892 hba
->sli
.sli4
.dump_region
.size
, DDI_DMA_SYNC_FORKERNEL
);
4893 Uptr
= (uint32_t *)hba
->sli
.sli4
.dump_region
.virt
;
4895 Uptr
= (uint32_t *)&mb
->un
.varDmp
.resp_offset
;
4899 *MaxRbusSize
= Uptr
[0];
4903 *MaxIbusSize
= Uptr
[1];
4909 kmem_free(mbox
, sizeof (MAILBOXQ
));
4913 if (hba
->sli_mode
== EMLXS_HBA_SLI4_MODE
) {
4914 if (emlxs_fm_check_dma_handle(hba
,
4915 hba
->sli
.sli4
.dump_region
.dma_handle
) != DDI_FM_OK
) {
4916 EMLXS_MSGF(EMLXS_CONTEXT
,
4917 &emlxs_invalid_dma_handle_msg
,
4918 "emlxs_get_max_sram: hdl=%p",
4919 hba
->sli
.sli4
.dump_region
.dma_handle
);
4923 #endif /* FMA_SUPPORT */
4927 } /* emlxs_get_max_sram() */
4931 emlxs_kern_check(emlxs_hba_t
*hba
, uint32_t version
)
4936 ver
= version
& 0xff;
4937 ptr
= hba
->model_info
.pt_FF
;
4940 if (*ptr
++ == ver
) {
4947 } /* emlxs_kern_check() */
4950 emlxs_stub_check(emlxs_hba_t
*hba
, uint32_t version
)
4955 ver
= version
& 0xff;
4956 ptr
= hba
->model_info
.pt_2
;
4959 if (*ptr
++ == ver
) {
4966 } /* emlxs_stub_check() */
4969 emlxs_bios_check(emlxs_hba_t
*hba
, uint32_t version
)
4974 ver
= version
& 0xff;
4975 ptr
= hba
->model_info
.pt_3
;
4978 if (*ptr
++ == ver
) {
4985 } /* emlxs_bios_check() */
4988 emlxs_sli1_check(emlxs_hba_t
*hba
, uint32_t version
)
4993 ver
= version
& 0xff;
4994 ptr
= hba
->model_info
.pt_6
;
4997 if (*ptr
++ == ver
) {
5004 } /* emlxs_sli1_check() */
5007 emlxs_sli2_check(emlxs_hba_t
*hba
, uint32_t version
)
5012 ver
= version
& 0xff;
5013 ptr
= hba
->model_info
.pt_7
;
5016 if (*ptr
++ == ver
) {
5023 } /* emlxs_sli2_check() */
5026 emlxs_sli3_check(emlxs_hba_t
*hba
, uint32_t version
)
5031 ver
= version
& 0xff;
5032 ptr
= hba
->model_info
.pt_B
;
5035 if (*ptr
++ == ver
) {
5042 } /* emlxs_sli3_check() */
5046 emlxs_sli4_check(emlxs_hba_t
*hba
, uint32_t version
)
5051 ver
= version
& 0xff;
5052 ptr
= hba
->model_info
.pt_E
;
5055 if (*ptr
++ == ver
) {
5062 } /* emlxs_sli4_check() */
5066 emlxs_sbus_fcode_check(emlxs_hba_t
*hba
, uint32_t version
)
5071 ver
= version
& 0xff;
5072 ptr
= hba
->model_info
.pt_A
;
5075 if (*ptr
++ == ver
) {
5082 } /* emlxs_sbus_fcode_check() */
5086 emlxs_type_check(uint32_t type
)
5089 return (KERNEL_CODE
);
5092 if (type
>= MAX_PROG_TYPES
) {
5093 return (RESERVED_D
);
5098 } /* emlxs_type_check() */
5102 emlxs_boot_code_disable(emlxs_hba_t
*hba
)
5104 emlxs_port_t
*port
= &PPORT
;
5110 if ((hba
->model_info
.chip
== EMLXS_BE2_CHIP
) ||
5111 (hba
->model_info
.chip
== EMLXS_BE3_CHIP
)) {
5112 return (EMLXS_OP_NOT_SUP
);
5115 if (emlxs_read_wakeup_parms(hba
, &hba
->wakeup_parms
, 0)) {
5116 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sfs_debug_msg
,
5117 "emlxs_boot_code_disable: Unable to read wake up parms.");
5119 return (FC_FAILURE
);
5122 /* Check if boot code is already disabled */
5123 if (hba
->wakeup_parms
.u0
.boot_bios_wd
[0] == 0) {
5124 return (FC_SUCCESS
);
5127 /* Make sure EROM entry has copy of boot bios entry */
5128 if (!(hba
->model_info
.chip
&
5129 (EMLXS_DRAGONFLY_CHIP
| EMLXS_CENTAUR_CHIP
)) &&
5130 (hba
->wakeup_parms
.u0
.boot_bios_wd
[0] !=
5131 hba
->wakeup_parms
.u1
.EROM_prog_wd
[0]) &&
5132 (hba
->wakeup_parms
.u0
.boot_bios_wd
[1] !=
5133 hba
->wakeup_parms
.u1
.EROM_prog_wd
[1])) {
5134 (void) emlxs_update_boot_wakeup_parms(hba
, &hba
->wakeup_parms
,
5135 &hba
->wakeup_parms
.u0
.boot_bios_id
, 1);
5138 /* Update the bios id with a zero id */
5139 /* Don't load the EROM this time */
5140 bzero(&Id
, sizeof (PROG_ID
));
5141 (void) emlxs_update_boot_wakeup_parms(hba
, &hba
->wakeup_parms
, &Id
, 0);
5143 /* Now read the parms again to verify */
5144 (void) emlxs_read_wakeup_parms(hba
, &hba
->wakeup_parms
, 1);
5145 emlxs_decode_version(hba
->wakeup_parms
.u0
.boot_bios_wd
[0],
5147 /* (void) strcpy(vpd->fcode_version, vpd->boot_version); */
5149 /* Return the result */
5150 return ((hba
->wakeup_parms
.u0
.boot_bios_wd
[0] == 0) ?
5151 FC_SUCCESS
: FC_FAILURE
);
5153 } /* emlxs_boot_code_disable() */
5157 emlxs_boot_code_enable(emlxs_hba_t
*hba
)
5159 emlxs_port_t
*port
= &PPORT
;
5161 PROG_ID load_list
[MAX_LOAD_ENTRY
];
5167 if ((hba
->model_info
.chip
== EMLXS_BE2_CHIP
) ||
5168 (hba
->model_info
.chip
== EMLXS_BE3_CHIP
)) {
5169 return (FC_SUCCESS
);
5172 /* Read the wakeup parms */
5173 if (emlxs_read_wakeup_parms(hba
, &hba
->wakeup_parms
, 0)) {
5174 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sfs_debug_msg
,
5175 "emlxs_boot_code_enable: Unable to read wake up parms.");
5177 return (FC_FAILURE
);
5180 /* Check if boot code is already enabled */
5181 if (hba
->wakeup_parms
.u0
.boot_bios_id
.Type
== BOOT_BIOS
) {
5182 return (FC_SUCCESS
);
5185 if (!(hba
->model_info
.chip
&
5186 (EMLXS_DRAGONFLY_CHIP
| EMLXS_CENTAUR_CHIP
))) {
5187 if (hba
->wakeup_parms
.u1
.EROM_prog_id
.Type
!= BOOT_BIOS
) {
5188 return (EMLXS_NO_BOOT_CODE
);
5191 /* Update the parms with the boot image id */
5192 /* Don't load the EROM this time */
5193 (void) emlxs_update_boot_wakeup_parms(hba
, &hba
->wakeup_parms
,
5194 &hba
->wakeup_parms
.u1
.EROM_prog_id
, 0);
5195 } else { /* (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP) */
5197 count
= emlxs_get_load_list(hba
, load_list
);
5200 return (FC_FAILURE
);
5203 /* Scan load list for a boot image */
5204 for (i
= 0; i
< count
; i
++) {
5205 if (load_list
[i
].Type
== BOOT_BIOS
) {
5206 /* Update the parms with the boot image id */
5207 /* Don't load the EROM this time */
5208 (void) emlxs_update_boot_wakeup_parms(hba
,
5209 &hba
->wakeup_parms
, &load_list
[i
], 0);
5216 return (EMLXS_NO_BOOT_CODE
);
5220 /* Now read the parms again to verify */
5221 (void) emlxs_read_wakeup_parms(hba
, &hba
->wakeup_parms
, 1);
5222 emlxs_decode_version(hba
->wakeup_parms
.u0
.boot_bios_wd
[0],
5224 /* (void) strcpy(vpd->fcode_version, vpd->boot_version); */
5226 /* return the result */
5227 return ((hba
->wakeup_parms
.u0
.boot_bios_wd
[0] != 0) ?
5228 FC_SUCCESS
: FC_FAILURE
);
5230 } /* emlxs_boot_code_enable() */
5235 emlxs_boot_code_state(emlxs_hba_t
*hba
)
5237 emlxs_port_t
*port
= &PPORT
;
5239 if ((hba
->model_info
.chip
== EMLXS_BE2_CHIP
) ||
5240 (hba
->model_info
.chip
== EMLXS_BE3_CHIP
)) {
5241 return (FC_SUCCESS
);
5244 /* Read the wakeup parms */
5245 if (emlxs_read_wakeup_parms(hba
, &hba
->wakeup_parms
, 1)) {
5246 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sfs_debug_msg
,
5247 "emlxs_boot_code_state: Unable to read wake up parms.");
5249 return (FC_FAILURE
);
5252 /* return the result */
5253 return ((hba
->wakeup_parms
.u0
.boot_bios_wd
[0] != 0) ?
5254 FC_SUCCESS
: FC_FAILURE
);
5256 } /* emlxs_boot_code_state() */