1fcf3ce44SJohn Forte /* 2fcf3ce44SJohn Forte * CDDL HEADER START 3fcf3ce44SJohn Forte * 4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7fcf3ce44SJohn Forte * 8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11fcf3ce44SJohn Forte * and limitations under the License. 12fcf3ce44SJohn Forte * 13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18fcf3ce44SJohn Forte * 19fcf3ce44SJohn Forte * CDDL HEADER END 20fcf3ce44SJohn Forte */ 21fcf3ce44SJohn Forte 22fcf3ce44SJohn Forte /* 236a573d82SSukumar Swaminathan * Copyright 2010 Emulex. All rights reserved. 2482527734SSukumar Swaminathan * Use is subject to license terms. 25fcf3ce44SJohn Forte */ 26fcf3ce44SJohn Forte 2782527734SSukumar Swaminathan 28291a2b48SSukumar Swaminathan #include <emlxs.h> 29fcf3ce44SJohn Forte 30fcf3ce44SJohn Forte /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 31fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_DOWNLOAD_C); 32fcf3ce44SJohn Forte 33fcf3ce44SJohn Forte #define MAX_BOOTID 10 34fcf3ce44SJohn Forte 35291a2b48SSukumar Swaminathan static uint32_t emlxs_erase_fcode_flash(emlxs_hba_t *hba); 3682527734SSukumar Swaminathan 37291a2b48SSukumar Swaminathan static uint32_t emlxs_write_fcode_flash(emlxs_hba_t *hba, 38291a2b48SSukumar Swaminathan PIMAGE_HDR ImageHdr, caddr_t Buffer); 39fcf3ce44SJohn Forte 40291a2b48SSukumar Swaminathan static int32_t emlxs_build_parms(caddr_t Buffer, PWAKE_UP_PARMS AbsWakeUpParms, 416a573d82SSukumar Swaminathan uint32_t BufferSize, PAIF_HDR AifHeader); 42291a2b48SSukumar Swaminathan static uint32_t emlxs_validate_image(emlxs_hba_t *hba, caddr_t Buffer, 43291a2b48SSukumar Swaminathan uint32_t Size, emlxs_fw_image_t *fw_image); 4482527734SSukumar Swaminathan static void emlxs_format_dump(emlxs_hba_t *hba, MAILBOXQ *mbq, 4582527734SSukumar Swaminathan uint32_t Type, uint32_t RegionId, uint32_t WordCnt, 4682527734SSukumar Swaminathan uint32_t BaseAddr); 47291a2b48SSukumar Swaminathan static uint32_t emlxs_start_abs_download(emlxs_hba_t *hba, PAIF_HDR AifHdr, 486a573d82SSukumar Swaminathan caddr_t Buffer, uint32_t len, 496a573d82SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms); 50291a2b48SSukumar Swaminathan static uint32_t emlxs_start_abs_download_2mb(emlxs_hba_t *hba, caddr_t buffer, 51291a2b48SSukumar Swaminathan uint32_t len, uint32_t offline, 52291a2b48SSukumar Swaminathan emlxs_fw_image_t *fw_image); 536a573d82SSukumar Swaminathan static uint32_t emlxs_proc_abs_2mb(emlxs_hba_t *hba, 54291a2b48SSukumar Swaminathan caddr_t EntireBuffer, uint32_t FileType, 556a573d82SSukumar Swaminathan uint32_t extType); 5682527734SSukumar Swaminathan static void emlxs_format_load_area_cmd(MAILBOXQ *mbq, uint32_t Base, 57291a2b48SSukumar Swaminathan uint32_t DlByteCount, uint32_t Function, 58291a2b48SSukumar Swaminathan uint32_t Complete, uint32_t DataOffset, uint32_t AreaId, 59291a2b48SSukumar Swaminathan uint8_t MbxCmd, uint32_t StepCmd); 60291a2b48SSukumar Swaminathan static uint32_t emlxs_build_parms_2mb_bwc(emlxs_hba_t *hba, PAIF_HDR AifHdr, 61291a2b48SSukumar Swaminathan uint32_t extType, PWAKE_UP_PARMS AbsWakeUpParms); 62291a2b48SSukumar Swaminathan static uint32_t emlxs_update_exp_rom(emlxs_hba_t *hba, 63291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms); 64291a2b48SSukumar Swaminathan extern uint32_t emlxs_get_max_sram(emlxs_hba_t *hba, uint32_t *MaxRbusSize, 65291a2b48SSukumar Swaminathan uint32_t *MaxIbusSize); 6682527734SSukumar Swaminathan static void emlxs_format_prog_flash(MAILBOXQ *mbq, uint32_t Base, 67291a2b48SSukumar Swaminathan uint32_t DlByteCount, uint32_t Function, 68291a2b48SSukumar Swaminathan uint32_t Complete, uint32_t BdeAddress, 696a573d82SSukumar Swaminathan uint32_t BdeSize, PROG_ID *ProgId, uint32_t keep); 7082527734SSukumar Swaminathan static void emlxs_format_update_parms(MAILBOXQ *mbq, 71291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms); 7282527734SSukumar Swaminathan static void emlxs_format_update_pci_cfg(emlxs_hba_t *hba, MAILBOXQ *mbq, 73291a2b48SSukumar Swaminathan uint32_t region_id, uint32_t size); 74291a2b48SSukumar Swaminathan static uint32_t emlxs_update_wakeup_parms(emlxs_hba_t *hba, 75291a2b48SSukumar Swaminathan PWAKE_UP_PARMS AbsWakeUpParms, 76291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms); 77291a2b48SSukumar Swaminathan static uint32_t emlxs_update_boot_wakeup_parms(emlxs_hba_t *hba, 78291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, PROG_ID *id, 79291a2b48SSukumar Swaminathan uint32_t proc_erom); 80291a2b48SSukumar Swaminathan static uint32_t emlxs_update_ff_wakeup_parms(emlxs_hba_t *hba, 81291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 82291a2b48SSukumar Swaminathan static uint32_t emlxs_update_sli1_wakeup_parms(emlxs_hba_t *hba, 83291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 84291a2b48SSukumar Swaminathan static uint32_t emlxs_update_sli2_wakeup_parms(emlxs_hba_t *hba, 85291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 86291a2b48SSukumar Swaminathan static uint32_t emlxs_update_sli3_wakeup_parms(emlxs_hba_t *hba, 87291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 88291a2b48SSukumar Swaminathan static uint32_t emlxs_update_sli4_wakeup_parms(emlxs_hba_t *hba, 89291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 90291a2b48SSukumar Swaminathan static uint32_t emlxs_start_rel_download(emlxs_hba_t *hba, PIMAGE_HDR ImageHdr, 91291a2b48SSukumar Swaminathan caddr_t Buffer, PWAKE_UP_PARMS WakeUpParms, 926a573d82SSukumar Swaminathan uint32_t dwc_flag); 93291a2b48SSukumar Swaminathan static uint32_t emlxs_read_load_list(emlxs_hba_t *hba, LOAD_LIST *LoadList); 94fcf3ce44SJohn Forte 95291a2b48SSukumar Swaminathan static uint32_t emlxs_valid_cksum(uint32_t *StartAddr, uint32_t *EndAddr); 9682527734SSukumar Swaminathan 97291a2b48SSukumar Swaminathan static void emlxs_disp_aif_header(emlxs_hba_t *hba, PAIF_HDR AifHdr); 9882527734SSukumar Swaminathan 99291a2b48SSukumar Swaminathan static void emlxs_dump_image_header(emlxs_hba_t *hba, PIMAGE_HDR image); 10082527734SSukumar Swaminathan 101*a9800bebSGarrett D'Amore 102291a2b48SSukumar Swaminathan static uint32_t emlxs_type_check(uint32_t type); 10382527734SSukumar Swaminathan 104291a2b48SSukumar Swaminathan static uint32_t emlxs_kern_check(emlxs_hba_t *hba, uint32_t version); 10582527734SSukumar Swaminathan 106291a2b48SSukumar Swaminathan static uint32_t emlxs_stub_check(emlxs_hba_t *hba, uint32_t version); 10782527734SSukumar Swaminathan 108291a2b48SSukumar Swaminathan static uint32_t emlxs_sli1_check(emlxs_hba_t *hba, uint32_t version); 10982527734SSukumar Swaminathan 110291a2b48SSukumar Swaminathan static uint32_t emlxs_sli2_check(emlxs_hba_t *hba, uint32_t version); 11182527734SSukumar Swaminathan 112291a2b48SSukumar Swaminathan static uint32_t emlxs_sli3_check(emlxs_hba_t *hba, uint32_t version); 11382527734SSukumar Swaminathan 114291a2b48SSukumar Swaminathan static uint32_t emlxs_sli4_check(emlxs_hba_t *hba, uint32_t version); 11582527734SSukumar Swaminathan 116291a2b48SSukumar Swaminathan static uint32_t emlxs_bios_check(emlxs_hba_t *hba, uint32_t version); 11782527734SSukumar Swaminathan 118291a2b48SSukumar Swaminathan static uint32_t emlxs_sbus_fcode_check(emlxs_hba_t *hba, uint32_t version); 11982527734SSukumar Swaminathan 120291a2b48SSukumar Swaminathan static uint32_t emlxs_validate_version(emlxs_hba_t *hba, 121291a2b48SSukumar Swaminathan emlxs_fw_file_t *file, uint32_t id, uint32_t type, 122291a2b48SSukumar Swaminathan char *file_type); 123*a9800bebSGarrett D'Amore static uint32_t emlxs_be2_validate_image(emlxs_hba_t *hba, caddr_t buffer, 12482527734SSukumar Swaminathan uint32_t len, emlxs_be_fw_image_t *fw_image); 125*a9800bebSGarrett D'Amore static uint32_t emlxs_be3_validate_image(emlxs_hba_t *hba, caddr_t buffer, 126*a9800bebSGarrett D'Amore uint32_t len, emlxs_be_fw_image_t *fw_image); 127*a9800bebSGarrett D'Amore 128*a9800bebSGarrett D'Amore 12982527734SSukumar Swaminathan static int32_t emlxs_sli4_verify_crc(emlxs_hba_t *hba, 13082527734SSukumar Swaminathan emlxs_be_fw_file_t *file, 13182527734SSukumar Swaminathan MAILBOXQ *mbq, MATCHMAP *mp); 13282527734SSukumar Swaminathan static int32_t emlxs_sli4_flash_image(emlxs_hba_t *hba, caddr_t buffer, 13382527734SSukumar Swaminathan emlxs_be_fw_file_t *file, MAILBOXQ *mbq, MATCHMAP *mp); 13482527734SSukumar Swaminathan static int32_t emlxs_sli4_fw_download(emlxs_hba_t *hba, caddr_t buffer, 13582527734SSukumar Swaminathan uint32_t len, uint32_t offline); 136*a9800bebSGarrett D'Amore static uint32_t emlxs_be_version(caddr_t buffer, uint32_t size, 137*a9800bebSGarrett D'Amore uint32_t *plus_flag); 1386a573d82SSukumar Swaminathan static uint32_t emlxs_proc_rel_2mb(emlxs_hba_t *hba, caddr_t buffer, 1396a573d82SSukumar Swaminathan emlxs_fw_image_t *fw_image); 1406a573d82SSukumar Swaminathan static uint32_t emlxs_delete_load_entry(emlxs_hba_t *hba, PROG_ID *progId); 1416a573d82SSukumar Swaminathan 1426a573d82SSukumar Swaminathan static void emlxs_verify_image(emlxs_hba_t *hba, emlxs_fw_image_t *image); 1436a573d82SSukumar Swaminathan 1446a573d82SSukumar Swaminathan static uint32_t emlxs_clean_flash(emlxs_hba_t *hba, 1456a573d82SSukumar Swaminathan PWAKE_UP_PARMS OldWakeUpParms, 1466a573d82SSukumar Swaminathan PWAKE_UP_PARMS NewWakeUpParms); 1476a573d82SSukumar Swaminathan 148291a2b48SSukumar Swaminathan /* ************************************************************************* */ 149fcf3ce44SJohn Forte 150fcf3ce44SJohn Forte extern int32_t 151fcf3ce44SJohn Forte emlxs_fw_download(emlxs_hba_t *hba, caddr_t buffer, uint32_t len, 152fcf3ce44SJohn Forte uint32_t offline) 153fcf3ce44SJohn Forte { 154fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 155fcf3ce44SJohn Forte uint32_t *Uptr; 156fcf3ce44SJohn Forte IMAGE_HDR ImageHdr; 157fcf3ce44SJohn Forte AIF_HDR AifHdr; 158fcf3ce44SJohn Forte uint32_t ImageType; 159fcf3ce44SJohn Forte WAKE_UP_PARMS WakeUpParms; 160fcf3ce44SJohn Forte uint32_t rval = 0; 161fcf3ce44SJohn Forte emlxs_fw_image_t fw_image; 162fcf3ce44SJohn Forte uint32_t i; 163fcf3ce44SJohn Forte 16482527734SSukumar Swaminathan #ifdef EMLXS_LITTLE_ENDIAN 165fcf3ce44SJohn Forte caddr_t local_buffer; 166fcf3ce44SJohn Forte uint32_t *bptr1; 167fcf3ce44SJohn Forte uint32_t *bptr2; 16882527734SSukumar Swaminathan #endif /* EMLXS_LITTLE_ENDIAN */ 16982527734SSukumar Swaminathan 17082527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 17182527734SSukumar Swaminathan rval = emlxs_sli4_fw_download(hba, buffer, len, offline); 17282527734SSukumar Swaminathan return (rval); 17382527734SSukumar Swaminathan } 174fcf3ce44SJohn Forte 175fcf3ce44SJohn Forte if (buffer == NULL || len == 0) { 176fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 177fcf3ce44SJohn Forte } 17882527734SSukumar Swaminathan 17982527734SSukumar Swaminathan #ifdef EMLXS_LITTLE_ENDIAN 180fcf3ce44SJohn Forte /* We need to swap the image buffer before we start */ 181fcf3ce44SJohn Forte 182fcf3ce44SJohn Forte /* 183fcf3ce44SJohn Forte * Use KM_SLEEP to allocate a temporary buffer 184fcf3ce44SJohn Forte */ 185fcf3ce44SJohn Forte local_buffer = (caddr_t)kmem_zalloc(len, KM_SLEEP); 186fcf3ce44SJohn Forte 187fcf3ce44SJohn Forte /* Perform a 32 bit swap of the image */ 188fcf3ce44SJohn Forte bptr1 = (uint32_t *)local_buffer; 189fcf3ce44SJohn Forte bptr2 = (uint32_t *)buffer; 190fcf3ce44SJohn Forte for (i = 0; i < (len / 4); i++) { 19182527734SSukumar Swaminathan *bptr1 = LE_SWAP32(*bptr2); 192fcf3ce44SJohn Forte bptr1++; 193fcf3ce44SJohn Forte bptr2++; 194fcf3ce44SJohn Forte } 195fcf3ce44SJohn Forte 196fcf3ce44SJohn Forte /* Replace the original buffer */ 197fcf3ce44SJohn Forte buffer = local_buffer; 19882527734SSukumar Swaminathan #endif /* EMLXS_LITTLE_ENDIAN */ 199fcf3ce44SJohn Forte 200fcf3ce44SJohn Forte bzero(&fw_image, sizeof (emlxs_fw_image_t)); 201fcf3ce44SJohn Forte for (i = 0; i < MAX_PROG_TYPES; i++) { 202fcf3ce44SJohn Forte (void) strcpy(fw_image.prog[i].label, "none"); 203fcf3ce44SJohn Forte } 204fcf3ce44SJohn Forte 205fcf3ce44SJohn Forte /* Validate image */ 206fcf3ce44SJohn Forte if ((rval = emlxs_validate_image(hba, buffer, len, &fw_image))) { 207fcf3ce44SJohn Forte goto done; 208fcf3ce44SJohn Forte } 209291a2b48SSukumar Swaminathan 2106a573d82SSukumar Swaminathan /* Verify image */ 2116a573d82SSukumar Swaminathan emlxs_verify_image(hba, &fw_image); 2126a573d82SSukumar Swaminathan 213fcf3ce44SJohn Forte /* Get image type */ 214fcf3ce44SJohn Forte Uptr = (uint32_t *)buffer; 215fcf3ce44SJohn Forte ImageType = *Uptr; 216fcf3ce44SJohn Forte 217fcf3ce44SJohn Forte /* 218291a2b48SSukumar Swaminathan * Pegasus and beyond FW download is done differently 219291a2b48SSukumar Swaminathan * for absolute download. 220fcf3ce44SJohn Forte */ 221fcf3ce44SJohn Forte 222fcf3ce44SJohn Forte /* Check for absolute image */ 223fcf3ce44SJohn Forte if ((ImageType == NOP_IMAGE_TYPE) && 224fcf3ce44SJohn Forte !(hba->model_info.chip & 225fcf3ce44SJohn Forte (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 226fcf3ce44SJohn Forte /* 227fcf3ce44SJohn Forte * Because 2Mb flash download file format is different from 228fcf3ce44SJohn Forte * 512k, it needs to be handled differently 229fcf3ce44SJohn Forte */ 230fcf3ce44SJohn Forte if (rval = emlxs_start_abs_download_2mb(hba, buffer, len, 231fcf3ce44SJohn Forte offline, &fw_image)) { 232fcf3ce44SJohn Forte goto done; 233fcf3ce44SJohn Forte } 234291a2b48SSukumar Swaminathan 235fcf3ce44SJohn Forte /* Offline already handled */ 236fcf3ce44SJohn Forte offline = 0; 237fcf3ce44SJohn Forte 238fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 239fcf3ce44SJohn Forte } 240291a2b48SSukumar Swaminathan 241fcf3ce44SJohn Forte /* Pre-pegasus adapters only */ 242fcf3ce44SJohn Forte 2436a573d82SSukumar Swaminathan /* Initialize headers */ 2446a573d82SSukumar Swaminathan if (ImageType == NOP_IMAGE_TYPE) { 245fcf3ce44SJohn Forte bcopy(buffer, &AifHdr, sizeof (AIF_HDR)); 246fcf3ce44SJohn Forte bzero((void *)&ImageHdr, sizeof (IMAGE_HDR)); 2476a573d82SSukumar Swaminathan } else { /* PRG file */ 248fcf3ce44SJohn Forte bzero((void *)&AifHdr, sizeof (AIF_HDR)); 249fcf3ce44SJohn Forte bcopy(buffer, &ImageHdr, sizeof (IMAGE_HDR)); 250fcf3ce44SJohn Forte } 251fcf3ce44SJohn Forte 2526a573d82SSukumar Swaminathan /* Everything checks out, now to just do it */ 253fcf3ce44SJohn Forte 254fcf3ce44SJohn Forte if (offline) { 255fcf3ce44SJohn Forte if (emlxs_offline(hba) != FC_SUCCESS) { 256fcf3ce44SJohn Forte offline = 0; 257fcf3ce44SJohn Forte 258fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 259fcf3ce44SJohn Forte "Unable to take adapter offline."); 260fcf3ce44SJohn Forte 261fcf3ce44SJohn Forte rval = EMLXS_OFFLINE_FAILED; 262fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 263fcf3ce44SJohn Forte } 264291a2b48SSukumar Swaminathan 26582527734SSukumar Swaminathan if (EMLXS_SLI_HBA_RESET(hba, 1, 1, 0) != FC_SUCCESS) { 266fcf3ce44SJohn Forte offline = 0; 267fcf3ce44SJohn Forte 268fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 269fcf3ce44SJohn Forte "Unable to restart adapter."); 270fcf3ce44SJohn Forte 271fcf3ce44SJohn Forte rval = EMLXS_OFFLINE_FAILED; 272fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 273fcf3ce44SJohn Forte } 274fcf3ce44SJohn Forte } 275291a2b48SSukumar Swaminathan 2766a573d82SSukumar Swaminathan /* Pre-pegasus adapters */ 2776a573d82SSukumar Swaminathan 278fcf3ce44SJohn Forte if (ImageHdr.Id.Type == SBUS_FCODE) { 279fcf3ce44SJohn Forte /* Erase Flash */ 280fcf3ce44SJohn Forte if (emlxs_erase_fcode_flash(hba)) { 281fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 282fcf3ce44SJohn Forte "Unable to erase flash."); 283fcf3ce44SJohn Forte 284fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 285fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 286fcf3ce44SJohn Forte } 287291a2b48SSukumar Swaminathan 288fcf3ce44SJohn Forte /* Write FCODE */ 289fcf3ce44SJohn Forte if (emlxs_write_fcode_flash(hba, &ImageHdr, buffer)) { 290fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 291fcf3ce44SJohn Forte "Unable to write flash."); 292fcf3ce44SJohn Forte 293fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 294fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 295fcf3ce44SJohn Forte } 296291a2b48SSukumar Swaminathan 2976a573d82SSukumar Swaminathan goto SLI_DOWNLOAD_EXIT; 2986a573d82SSukumar Swaminathan } 299fcf3ce44SJohn Forte 3006a573d82SSukumar Swaminathan /* Pre-pegasus PCI adapters */ 301291a2b48SSukumar Swaminathan 3026a573d82SSukumar Swaminathan if (emlxs_read_wakeup_parms(hba, &WakeUpParms, 1)) { 3036a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3046a573d82SSukumar Swaminathan "Unable to get parameters."); 305fcf3ce44SJohn Forte 3066a573d82SSukumar Swaminathan rval = EMLXS_IMAGE_FAILED; 307fcf3ce44SJohn Forte 3086a573d82SSukumar Swaminathan goto SLI_DOWNLOAD_EXIT; 3096a573d82SSukumar Swaminathan } 310291a2b48SSukumar Swaminathan 3116a573d82SSukumar Swaminathan if (ImageType == NOP_IMAGE_TYPE) { 3126a573d82SSukumar Swaminathan if (emlxs_start_abs_download(hba, &AifHdr, 3136a573d82SSukumar Swaminathan buffer, len, &WakeUpParms)) { 3146a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 3156a573d82SSukumar Swaminathan &emlxs_download_failed_msg, 3166a573d82SSukumar Swaminathan "Failed to program flash."); 317fcf3ce44SJohn Forte 318fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 319fcf3ce44SJohn Forte 320fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 321fcf3ce44SJohn Forte } 322291a2b48SSukumar Swaminathan 3236a573d82SSukumar Swaminathan } else { /* Relative PRG file */ 3246a573d82SSukumar Swaminathan if (emlxs_start_rel_download(hba, &ImageHdr, buffer, 3256a573d82SSukumar Swaminathan &WakeUpParms, 0)) { 3266a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 3276a573d82SSukumar Swaminathan &emlxs_download_failed_msg, 3286a573d82SSukumar Swaminathan "Failed to program flash."); 329fcf3ce44SJohn Forte 3306a573d82SSukumar Swaminathan rval = EMLXS_IMAGE_FAILED; 331fcf3ce44SJohn Forte 3326a573d82SSukumar Swaminathan goto SLI_DOWNLOAD_EXIT; 333fcf3ce44SJohn Forte } 3346a573d82SSukumar Swaminathan } 335fcf3ce44SJohn Forte 336fcf3ce44SJohn Forte SLI_DOWNLOAD_EXIT: 337fcf3ce44SJohn Forte 338fcf3ce44SJohn Forte if (offline) { 339fcf3ce44SJohn Forte (void) emlxs_online(hba); 340fcf3ce44SJohn Forte } 341291a2b48SSukumar Swaminathan 342fcf3ce44SJohn Forte if (rval == 0) { 343fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_complete_msg, 344fcf3ce44SJohn Forte "Status good."); 345fcf3ce44SJohn Forte } 346291a2b48SSukumar Swaminathan 347fcf3ce44SJohn Forte done: 348fcf3ce44SJohn Forte 34982527734SSukumar Swaminathan #ifdef EMLXS_LITTLE_ENDIAN 350fcf3ce44SJohn Forte /* Free the local buffer */ 351fcf3ce44SJohn Forte kmem_free(local_buffer, len); 35282527734SSukumar Swaminathan #endif /* EMLXS_LITTLE_ENDIAN */ 35382527734SSukumar Swaminathan 35482527734SSukumar Swaminathan return (rval); 35582527734SSukumar Swaminathan 35682527734SSukumar Swaminathan } /* emlxs_fw_download */ 35782527734SSukumar Swaminathan 35882527734SSukumar Swaminathan 359*a9800bebSGarrett D'Amore extern void 36082527734SSukumar Swaminathan emlxs_memset(uint8_t *buffer, uint8_t value, uint32_t size) 36182527734SSukumar Swaminathan { 36282527734SSukumar Swaminathan while (size--) { 36382527734SSukumar Swaminathan *buffer++ = value; 36482527734SSukumar Swaminathan } 36582527734SSukumar Swaminathan 36682527734SSukumar Swaminathan } /* emlxs_memset () */ 36782527734SSukumar Swaminathan 36882527734SSukumar Swaminathan 36982527734SSukumar Swaminathan static int32_t 37082527734SSukumar Swaminathan emlxs_sli4_flash_image(emlxs_hba_t *hba, caddr_t buffer, 37182527734SSukumar Swaminathan emlxs_be_fw_file_t *file, MAILBOXQ *mbq, MATCHMAP *mp) 37282527734SSukumar Swaminathan { 37382527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 37482527734SSukumar Swaminathan uint8_t *image_ptr; 37582527734SSukumar Swaminathan uint32_t *wptr; 37682527734SSukumar Swaminathan uint8_t *payload; 37782527734SSukumar Swaminathan MAILBOX4 *mb; 37882527734SSukumar Swaminathan IOCTL_COMMON_FLASHROM *flashrom; 37982527734SSukumar Swaminathan mbox_req_hdr_t *hdr_req; 38082527734SSukumar Swaminathan uint32_t image_size; 38182527734SSukumar Swaminathan uint32_t block_size; 38282527734SSukumar Swaminathan uint32_t xfer_size; 38382527734SSukumar Swaminathan uint32_t block_offset; 38482527734SSukumar Swaminathan uint32_t count; 38582527734SSukumar Swaminathan uint32_t rval = 0; 38682527734SSukumar Swaminathan 38782527734SSukumar Swaminathan if (file->image_size == 0) { 38882527734SSukumar Swaminathan return (0); 38982527734SSukumar Swaminathan } 39082527734SSukumar Swaminathan 39182527734SSukumar Swaminathan image_ptr = (uint8_t *)buffer + file->image_offset; 39282527734SSukumar Swaminathan image_size = file->image_size; 39382527734SSukumar Swaminathan block_size = file->block_size; 39482527734SSukumar Swaminathan block_offset = 0; 39582527734SSukumar Swaminathan mb = (MAILBOX4*)mbq; 39682527734SSukumar Swaminathan 39782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 39882527734SSukumar Swaminathan "%s: Downloading...", file->label); 39982527734SSukumar Swaminathan 40082527734SSukumar Swaminathan while (block_size) { 40182527734SSukumar Swaminathan bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 40282527734SSukumar Swaminathan bzero((void *) mp->virt, mp->size); 40382527734SSukumar Swaminathan 40482527734SSukumar Swaminathan xfer_size = min(BE_MAX_XFER_SIZE, block_size); 40582527734SSukumar Swaminathan 40682527734SSukumar Swaminathan mb->un.varSLIConfig.be.embedded = 0; 407*a9800bebSGarrett D'Amore mbq->nonembed = (void *)mp; 40882527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 40982527734SSukumar Swaminathan 41082527734SSukumar Swaminathan mb->mbxCommand = MBX_SLI_CONFIG; 41182527734SSukumar Swaminathan mb->mbxOwner = OWN_HOST; 41282527734SSukumar Swaminathan 41382527734SSukumar Swaminathan hdr_req = (mbox_req_hdr_t *)mp->virt; 41482527734SSukumar Swaminathan hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON; 41582527734SSukumar Swaminathan hdr_req->opcode = COMMON_OPCODE_WRITE_FLASHROM; 41682527734SSukumar Swaminathan hdr_req->timeout = 0; 41782527734SSukumar Swaminathan hdr_req->req_length = sizeof (IOCTL_COMMON_FLASHROM) + 41882527734SSukumar Swaminathan xfer_size; 41982527734SSukumar Swaminathan 42082527734SSukumar Swaminathan flashrom = (IOCTL_COMMON_FLASHROM *)(hdr_req + 1); 42182527734SSukumar Swaminathan flashrom->params.opcode = ((block_size == xfer_size)? 42282527734SSukumar Swaminathan MGMT_FLASHROM_OPCODE_FLASH:MGMT_FLASHROM_OPCODE_SAVE); 42382527734SSukumar Swaminathan flashrom->params.optype = file->type; 42482527734SSukumar Swaminathan flashrom->params.data_buffer_size = xfer_size; 42582527734SSukumar Swaminathan flashrom->params.offset = block_offset; 42682527734SSukumar Swaminathan 42782527734SSukumar Swaminathan /* Build data buffer payload */ 42882527734SSukumar Swaminathan payload = (uint8_t *)(&flashrom->params.data_buffer); 42982527734SSukumar Swaminathan emlxs_memset(payload, 0xff, xfer_size); 43082527734SSukumar Swaminathan 43182527734SSukumar Swaminathan /* Copy remaining image into payload */ 43282527734SSukumar Swaminathan if (image_size) { 43382527734SSukumar Swaminathan count = min(image_size, xfer_size); 43482527734SSukumar Swaminathan BE_SWAP32_BCOPY(image_ptr, payload, count); 43582527734SSukumar Swaminathan image_size -= count; 43682527734SSukumar Swaminathan image_ptr += count; 43782527734SSukumar Swaminathan } 43882527734SSukumar Swaminathan 43982527734SSukumar Swaminathan if (flashrom->params.opcode == MGMT_FLASHROM_OPCODE_FLASH) { 4406a573d82SSukumar Swaminathan wptr = (uint32_t *)&payload[(xfer_size - 12)]; 441*a9800bebSGarrett D'Amore 4426a573d82SSukumar Swaminathan wptr[0] = file->load_address; 4436a573d82SSukumar Swaminathan wptr[1] = file->image_size; 4446a573d82SSukumar Swaminathan wptr[2] = file->block_crc; 44582527734SSukumar Swaminathan } 44682527734SSukumar Swaminathan 44782527734SSukumar Swaminathan /* Send write request */ 44882527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 44982527734SSukumar Swaminathan MBX_SUCCESS) { 45082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 45182527734SSukumar Swaminathan "%s: Unable to download image. status=%x", 45282527734SSukumar Swaminathan file->label, mb->mbxStatus); 45382527734SSukumar Swaminathan rval = EMLXS_IMAGE_FAILED; 45482527734SSukumar Swaminathan goto done; 45582527734SSukumar Swaminathan } 45682527734SSukumar Swaminathan 45782527734SSukumar Swaminathan block_size -= xfer_size; 45882527734SSukumar Swaminathan block_offset += xfer_size; 45982527734SSukumar Swaminathan } 46082527734SSukumar Swaminathan 46182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 46282527734SSukumar Swaminathan "%s: Download complete.", file->label); 46382527734SSukumar Swaminathan done: 46482527734SSukumar Swaminathan 46582527734SSukumar Swaminathan return (rval); 46682527734SSukumar Swaminathan 46782527734SSukumar Swaminathan } /* emlxs_sli4_flash_image() */ 46882527734SSukumar Swaminathan 46982527734SSukumar Swaminathan 47082527734SSukumar Swaminathan 47182527734SSukumar Swaminathan 47282527734SSukumar Swaminathan static int32_t 47382527734SSukumar Swaminathan emlxs_sli4_verify_crc(emlxs_hba_t *hba, 47482527734SSukumar Swaminathan emlxs_be_fw_file_t *file, MAILBOXQ *mbq, MATCHMAP *mp) 47582527734SSukumar Swaminathan { 47682527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 47782527734SSukumar Swaminathan uint32_t *wptr; 47882527734SSukumar Swaminathan uint8_t *payload; 47982527734SSukumar Swaminathan MAILBOX4 *mb; 48082527734SSukumar Swaminathan IOCTL_COMMON_FLASHROM *flashrom; 48182527734SSukumar Swaminathan mbox_req_hdr_t *hdr_req; 48282527734SSukumar Swaminathan uint32_t xfer_size; 48382527734SSukumar Swaminathan uint32_t block_offset; 48482527734SSukumar Swaminathan uint32_t rval = 0; 48582527734SSukumar Swaminathan uint32_t value; 48682527734SSukumar Swaminathan 48782527734SSukumar Swaminathan xfer_size = 8; 48882527734SSukumar Swaminathan block_offset = file->block_size - xfer_size; 48982527734SSukumar Swaminathan mb = (MAILBOX4*)mbq; 49082527734SSukumar Swaminathan 49182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 49282527734SSukumar Swaminathan "%s: Verifying CRC...", file->label); 49382527734SSukumar Swaminathan 49482527734SSukumar Swaminathan bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 49582527734SSukumar Swaminathan bzero((void *) mp->virt, mp->size); 49682527734SSukumar Swaminathan 49782527734SSukumar Swaminathan mb->un.varSLIConfig.be.embedded = 0; 498*a9800bebSGarrett D'Amore mbq->nonembed = (void *)mp; 49982527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 50082527734SSukumar Swaminathan 50182527734SSukumar Swaminathan mb->mbxCommand = MBX_SLI_CONFIG; 50282527734SSukumar Swaminathan mb->mbxOwner = OWN_HOST; 50382527734SSukumar Swaminathan 50482527734SSukumar Swaminathan hdr_req = (mbox_req_hdr_t *)mp->virt; 50582527734SSukumar Swaminathan hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON; 50682527734SSukumar Swaminathan hdr_req->opcode = COMMON_OPCODE_READ_FLASHROM; 50782527734SSukumar Swaminathan hdr_req->timeout = 0; 50882527734SSukumar Swaminathan hdr_req->req_length = sizeof (IOCTL_COMMON_FLASHROM) + 50982527734SSukumar Swaminathan xfer_size; 51082527734SSukumar Swaminathan 51182527734SSukumar Swaminathan flashrom = (IOCTL_COMMON_FLASHROM *)(hdr_req + 1); 51282527734SSukumar Swaminathan flashrom->params.opcode = MGMT_FLASHROM_OPCODE_REPORT; 51382527734SSukumar Swaminathan flashrom->params.optype = file->type; 51482527734SSukumar Swaminathan flashrom->params.data_buffer_size = xfer_size; 51582527734SSukumar Swaminathan flashrom->params.offset = block_offset; 51682527734SSukumar Swaminathan 51782527734SSukumar Swaminathan /* Send read request */ 51882527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 51982527734SSukumar Swaminathan MBX_SUCCESS) { 52082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 52182527734SSukumar Swaminathan "%s: Unable to read CRC. status=%x", 52282527734SSukumar Swaminathan file->label, mb->mbxStatus); 52382527734SSukumar Swaminathan 524*a9800bebSGarrett D'Amore rval = 2; 52582527734SSukumar Swaminathan goto done; 52682527734SSukumar Swaminathan } 52782527734SSukumar Swaminathan 52882527734SSukumar Swaminathan payload = (uint8_t *)(&flashrom->params.data_buffer); 52982527734SSukumar Swaminathan wptr = (uint32_t *)(payload + xfer_size - 8); 53082527734SSukumar Swaminathan 53182527734SSukumar Swaminathan /* Verify image size */ 53282527734SSukumar Swaminathan value = *wptr++; 53382527734SSukumar Swaminathan if (value != file->image_size) { 53482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 53582527734SSukumar Swaminathan "%s: Image size mismatch. %08x != %08x", 53682527734SSukumar Swaminathan file->label, value, file->image_size); 53782527734SSukumar Swaminathan 538*a9800bebSGarrett D'Amore rval = 1; 53982527734SSukumar Swaminathan goto done; 54082527734SSukumar Swaminathan } 54182527734SSukumar Swaminathan 54282527734SSukumar Swaminathan /* Verify block crc */ 54382527734SSukumar Swaminathan value = *wptr; 54482527734SSukumar Swaminathan if (value != file->block_crc) { 54582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 54682527734SSukumar Swaminathan "%s: CRC mismatch. %08x != %08x", 54782527734SSukumar Swaminathan file->label, value, file->block_crc); 548*a9800bebSGarrett D'Amore rval = 1; 54982527734SSukumar Swaminathan } 55082527734SSukumar Swaminathan 55182527734SSukumar Swaminathan done: 55282527734SSukumar Swaminathan 55382527734SSukumar Swaminathan if (rval == 0) { 55482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 55582527734SSukumar Swaminathan "%s: CRC verified.", file->label); 55682527734SSukumar Swaminathan } 55782527734SSukumar Swaminathan 55882527734SSukumar Swaminathan return (rval); 55982527734SSukumar Swaminathan 56082527734SSukumar Swaminathan } /* emlxs_sli4_verify_crc() */ 56182527734SSukumar Swaminathan 56282527734SSukumar Swaminathan 56382527734SSukumar Swaminathan extern int32_t 56482527734SSukumar Swaminathan emlxs_sli4_read_fw_version(emlxs_hba_t *hba, emlxs_firmware_t *fw) 56582527734SSukumar Swaminathan { 56682527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 56782527734SSukumar Swaminathan MAILBOXQ *mbq = NULL; 56882527734SSukumar Swaminathan MATCHMAP *mp = NULL; 56982527734SSukumar Swaminathan MAILBOX4 *mb; 57082527734SSukumar Swaminathan uint32_t *wptr; 57182527734SSukumar Swaminathan uint8_t *payload; 57282527734SSukumar Swaminathan IOCTL_COMMON_FLASHROM *flashrom; 57382527734SSukumar Swaminathan mbox_req_hdr_t *hdr_req; 57482527734SSukumar Swaminathan uint32_t xfer_size; 57582527734SSukumar Swaminathan uint32_t block_offset; 57682527734SSukumar Swaminathan uint32_t rval = 0; 57782527734SSukumar Swaminathan 57882527734SSukumar Swaminathan bzero((void *) fw, sizeof (emlxs_firmware_t)); 57982527734SSukumar Swaminathan 58082527734SSukumar Swaminathan if ((mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 58182527734SSukumar Swaminathan KM_SLEEP)) == NULL) { 58282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 58382527734SSukumar Swaminathan "read_fw_version: Unable to allocate mailbox buffer."); 58482527734SSukumar Swaminathan 58582527734SSukumar Swaminathan rval = 1; 58682527734SSukumar Swaminathan goto done; 58782527734SSukumar Swaminathan } 58882527734SSukumar Swaminathan 58982527734SSukumar Swaminathan if ((mp = emlxs_mem_buf_alloc(hba, (sizeof (mbox_req_hdr_t) + 59082527734SSukumar Swaminathan sizeof (IOCTL_COMMON_FLASHROM) + 32))) == NULL) { 59182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 59282527734SSukumar Swaminathan "read_fw_version: Unable to allocate payload buffer."); 59382527734SSukumar Swaminathan 59482527734SSukumar Swaminathan rval = EMLXS_IMAGE_FAILED; 59582527734SSukumar Swaminathan goto done; 59682527734SSukumar Swaminathan } 59782527734SSukumar Swaminathan 59882527734SSukumar Swaminathan mb = (MAILBOX4*)mbq; 59982527734SSukumar Swaminathan 60082527734SSukumar Swaminathan /* Read CRC and size */ 60182527734SSukumar Swaminathan xfer_size = 8; 60282527734SSukumar Swaminathan block_offset = 0x140000 - xfer_size; 60382527734SSukumar Swaminathan 60482527734SSukumar Swaminathan bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 60582527734SSukumar Swaminathan bzero((void *) mp->virt, mp->size); 60682527734SSukumar Swaminathan 60782527734SSukumar Swaminathan mb->un.varSLIConfig.be.embedded = 0; 608*a9800bebSGarrett D'Amore mbq->nonembed = (void *)mp; 60982527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 61082527734SSukumar Swaminathan 61182527734SSukumar Swaminathan mb->mbxCommand = MBX_SLI_CONFIG; 61282527734SSukumar Swaminathan mb->mbxOwner = OWN_HOST; 61382527734SSukumar Swaminathan 61482527734SSukumar Swaminathan hdr_req = (mbox_req_hdr_t *)mp->virt; 61582527734SSukumar Swaminathan hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON; 61682527734SSukumar Swaminathan hdr_req->opcode = COMMON_OPCODE_READ_FLASHROM; 61782527734SSukumar Swaminathan hdr_req->timeout = 0; 61882527734SSukumar Swaminathan hdr_req->req_length = sizeof (IOCTL_COMMON_FLASHROM) + 61982527734SSukumar Swaminathan xfer_size; 62082527734SSukumar Swaminathan 62182527734SSukumar Swaminathan flashrom = (IOCTL_COMMON_FLASHROM *)(hdr_req + 1); 62282527734SSukumar Swaminathan flashrom->params.opcode = MGMT_FLASHROM_OPCODE_REPORT; 62382527734SSukumar Swaminathan flashrom->params.optype = MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE; 62482527734SSukumar Swaminathan flashrom->params.data_buffer_size = xfer_size; 62582527734SSukumar Swaminathan flashrom->params.offset = block_offset; 62682527734SSukumar Swaminathan 62782527734SSukumar Swaminathan /* Send read request */ 62882527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 62982527734SSukumar Swaminathan MBX_SUCCESS) { 63082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 63182527734SSukumar Swaminathan "read_fw_version: Unable to read CRC. status=%x", 63282527734SSukumar Swaminathan mb->mbxStatus); 63382527734SSukumar Swaminathan 63482527734SSukumar Swaminathan rval = 1; 63582527734SSukumar Swaminathan goto done; 63682527734SSukumar Swaminathan } 63782527734SSukumar Swaminathan 63882527734SSukumar Swaminathan payload = (uint8_t *)(&flashrom->params.data_buffer); 63982527734SSukumar Swaminathan 64082527734SSukumar Swaminathan wptr = (uint32_t *)payload; 64182527734SSukumar Swaminathan fw->size = *wptr++; /* image size */ 64282527734SSukumar Swaminathan fw->sli4 = *wptr; /* block crc */ 64382527734SSukumar Swaminathan fw->kern = *wptr; 64482527734SSukumar Swaminathan fw->stub = *wptr; 64582527734SSukumar Swaminathan 64682527734SSukumar Swaminathan /* Read version label */ 64782527734SSukumar Swaminathan xfer_size = 32; 64882527734SSukumar Swaminathan block_offset = 0x30; 64982527734SSukumar Swaminathan 65082527734SSukumar Swaminathan bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 65182527734SSukumar Swaminathan bzero((void *) mp->virt, mp->size); 65282527734SSukumar Swaminathan 65382527734SSukumar Swaminathan mb->un.varSLIConfig.be.embedded = 0; 654*a9800bebSGarrett D'Amore mbq->nonembed = (void *)mp; 65582527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 65682527734SSukumar Swaminathan 65782527734SSukumar Swaminathan mb->mbxCommand = MBX_SLI_CONFIG; 65882527734SSukumar Swaminathan mb->mbxOwner = OWN_HOST; 65982527734SSukumar Swaminathan 66082527734SSukumar Swaminathan hdr_req = (mbox_req_hdr_t *)mp->virt; 66182527734SSukumar Swaminathan hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON; 66282527734SSukumar Swaminathan hdr_req->opcode = COMMON_OPCODE_READ_FLASHROM; 66382527734SSukumar Swaminathan hdr_req->timeout = 0; 66482527734SSukumar Swaminathan hdr_req->req_length = sizeof (IOCTL_COMMON_FLASHROM) + 66582527734SSukumar Swaminathan xfer_size; 66682527734SSukumar Swaminathan 66782527734SSukumar Swaminathan flashrom = (IOCTL_COMMON_FLASHROM *)(hdr_req + 1); 66882527734SSukumar Swaminathan flashrom->params.opcode = MGMT_FLASHROM_OPCODE_REPORT; 66982527734SSukumar Swaminathan flashrom->params.optype = MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE; 67082527734SSukumar Swaminathan flashrom->params.data_buffer_size = xfer_size; 67182527734SSukumar Swaminathan flashrom->params.offset = block_offset; 67282527734SSukumar Swaminathan 67382527734SSukumar Swaminathan /* Send read request */ 67482527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 67582527734SSukumar Swaminathan MBX_SUCCESS) { 67682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 67782527734SSukumar Swaminathan "read_fw_version: Unable to read version string. status=%x", 67882527734SSukumar Swaminathan mb->mbxStatus); 67982527734SSukumar Swaminathan 68082527734SSukumar Swaminathan rval = 1; 68182527734SSukumar Swaminathan goto done; 68282527734SSukumar Swaminathan } 68382527734SSukumar Swaminathan 68482527734SSukumar Swaminathan payload = (uint8_t *)(&flashrom->params.data_buffer); 68582527734SSukumar Swaminathan BE_SWAP32_BCOPY(payload, (uint8_t *)fw->label, 32); 68682527734SSukumar Swaminathan 68782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 68882527734SSukumar Swaminathan "FCOE FIRMWARE: size=%x version=%s (0x%08x)", 68982527734SSukumar Swaminathan fw->size, fw->label, fw->sli4); 69082527734SSukumar Swaminathan 69182527734SSukumar Swaminathan done: 69282527734SSukumar Swaminathan 69382527734SSukumar Swaminathan if (mbq) { 694*a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 69582527734SSukumar Swaminathan } 69682527734SSukumar Swaminathan 69782527734SSukumar Swaminathan if (mp) { 698*a9800bebSGarrett D'Amore emlxs_mem_buf_free(hba, mp); 69982527734SSukumar Swaminathan } 70082527734SSukumar Swaminathan 70182527734SSukumar Swaminathan return (rval); 70282527734SSukumar Swaminathan 70382527734SSukumar Swaminathan } /* emlxs_sli4_read_fw_version() */ 70482527734SSukumar Swaminathan 70582527734SSukumar Swaminathan 70682527734SSukumar Swaminathan static uint32_t 707*a9800bebSGarrett D'Amore emlxs_be_version(caddr_t buffer, uint32_t size, uint32_t *plus_flag) 708*a9800bebSGarrett D'Amore { 709*a9800bebSGarrett D'Amore emlxs_be2_ufi_header_t *ufi_hdr; 710*a9800bebSGarrett D'Amore char signature[BE2_SIGNATURE_SIZE]; 711*a9800bebSGarrett D'Amore uint32_t be_version = 0; 712*a9800bebSGarrett D'Amore 713*a9800bebSGarrett D'Amore if (size < sizeof (emlxs_be2_ufi_header_t)) { 714*a9800bebSGarrett D'Amore return (0); 715*a9800bebSGarrett D'Amore } 716*a9800bebSGarrett D'Amore ufi_hdr = (emlxs_be2_ufi_header_t *)buffer; 717*a9800bebSGarrett D'Amore 718*a9800bebSGarrett D'Amore (void) sprintf(signature, "%s+", BE_SIGNATURE); 719*a9800bebSGarrett D'Amore 720*a9800bebSGarrett D'Amore /* Check if this is a UFI image */ 721*a9800bebSGarrett D'Amore if (strncmp(signature, (char *)ufi_hdr->signature, 722*a9800bebSGarrett D'Amore strlen(BE_SIGNATURE)) != 0) { 723*a9800bebSGarrett D'Amore return (0); 724*a9800bebSGarrett D'Amore } 725*a9800bebSGarrett D'Amore 726*a9800bebSGarrett D'Amore /* Check if this is a UFI plus image */ 727*a9800bebSGarrett D'Amore if (plus_flag) { 728*a9800bebSGarrett D'Amore /* Check if this is a UFI plus image */ 729*a9800bebSGarrett D'Amore if (strncmp(signature, (char *)ufi_hdr->signature, 730*a9800bebSGarrett D'Amore strlen(BE_SIGNATURE)+1) == 0) { 731*a9800bebSGarrett D'Amore *plus_flag = 1; 732*a9800bebSGarrett D'Amore } else { 733*a9800bebSGarrett D'Amore *plus_flag = 0; 734*a9800bebSGarrett D'Amore } 735*a9800bebSGarrett D'Amore } 736*a9800bebSGarrett D'Amore 737*a9800bebSGarrett D'Amore if ((ufi_hdr->build[0] >= '1') && (ufi_hdr->build[0] <= '9')) { 738*a9800bebSGarrett D'Amore be_version = ufi_hdr->build[0] - '0'; 739*a9800bebSGarrett D'Amore } 740*a9800bebSGarrett D'Amore 741*a9800bebSGarrett D'Amore return (be_version); 742*a9800bebSGarrett D'Amore 743*a9800bebSGarrett D'Amore } /* emlxs_be_version() */ 744*a9800bebSGarrett D'Amore 745*a9800bebSGarrett D'Amore 746*a9800bebSGarrett D'Amore static uint32_t 747*a9800bebSGarrett D'Amore emlxs_be2_validate_image(emlxs_hba_t *hba, caddr_t buffer, 74882527734SSukumar Swaminathan uint32_t len, emlxs_be_fw_image_t *fw_image) 74982527734SSukumar Swaminathan { 75082527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 751*a9800bebSGarrett D'Amore emlxs_be2_ufi_header_t *ufi_hdr; 752*a9800bebSGarrett D'Amore emlxs_be2_flash_dir_t *flash_dir; 753*a9800bebSGarrett D'Amore emlxs_be2_flash_entry_t *entry; 75482527734SSukumar Swaminathan uint8_t *bptr; 75582527734SSukumar Swaminathan uint32_t *wptr; 75682527734SSukumar Swaminathan uint32_t i; 75782527734SSukumar Swaminathan uint32_t k; 75882527734SSukumar Swaminathan uint32_t mask; 75982527734SSukumar Swaminathan uint32_t value; 76082527734SSukumar Swaminathan uint32_t image_size; 76182527734SSukumar Swaminathan emlxs_be_fw_file_t *file; 76282527734SSukumar Swaminathan emlxs_be_fw_file_t *file2; 76382527734SSukumar Swaminathan uint32_t ufi_plus = 0; 764*a9800bebSGarrett D'Amore uint32_t be_version = 0; 765*a9800bebSGarrett D'Amore uint32_t found; 76682527734SSukumar Swaminathan 76782527734SSukumar Swaminathan bzero(fw_image, sizeof (emlxs_be_fw_image_t)); 76882527734SSukumar Swaminathan 769*a9800bebSGarrett D'Amore if (hba->model_info.chip != EMLXS_BE2_CHIP) { 77082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 77182527734SSukumar Swaminathan "Invalid adapter model."); 77282527734SSukumar Swaminathan return (EMLXS_IMAGE_INCOMPATIBLE); 77382527734SSukumar Swaminathan } 77482527734SSukumar Swaminathan 775*a9800bebSGarrett D'Amore if (len < (sizeof (emlxs_be2_ufi_header_t) + 776*a9800bebSGarrett D'Amore sizeof (emlxs_be2_flash_dir_t))) { 77782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 77882527734SSukumar Swaminathan "Image too small. (%d < %d)", 779*a9800bebSGarrett D'Amore len, (sizeof (emlxs_be2_ufi_header_t) + 780*a9800bebSGarrett D'Amore sizeof (emlxs_be2_flash_dir_t))); 78182527734SSukumar Swaminathan return (EMLXS_IMAGE_BAD); 78282527734SSukumar Swaminathan } 78382527734SSukumar Swaminathan 784*a9800bebSGarrett D'Amore be_version = emlxs_be_version(buffer, len, &ufi_plus); 785*a9800bebSGarrett D'Amore 786*a9800bebSGarrett D'Amore /* Check if this is a standard BE2 image */ 787*a9800bebSGarrett D'Amore if (be_version != 2) { 78882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 78982527734SSukumar Swaminathan "Invalid image provided."); 79082527734SSukumar Swaminathan return (EMLXS_IMAGE_INCOMPATIBLE); 79182527734SSukumar Swaminathan } 79282527734SSukumar Swaminathan 793*a9800bebSGarrett D'Amore ufi_hdr = (emlxs_be2_ufi_header_t *)buffer; 79482527734SSukumar Swaminathan 79582527734SSukumar Swaminathan #ifdef EMLXS_BIG_ENDIAN 79682527734SSukumar Swaminathan /* Big Endian Swapping */ 79782527734SSukumar Swaminathan /* Swap ufi header */ 79882527734SSukumar Swaminathan ufi_hdr->checksum = 79982527734SSukumar Swaminathan SWAP32(ufi_hdr->checksum); 80082527734SSukumar Swaminathan ufi_hdr->antidote = 80182527734SSukumar Swaminathan SWAP32(ufi_hdr->antidote); 80282527734SSukumar Swaminathan ufi_hdr->controller.vendor_id = 80382527734SSukumar Swaminathan SWAP32(ufi_hdr->controller.vendor_id); 80482527734SSukumar Swaminathan ufi_hdr->controller.device_id = 80582527734SSukumar Swaminathan SWAP32(ufi_hdr->controller.device_id); 80682527734SSukumar Swaminathan ufi_hdr->controller.sub_vendor_id = 80782527734SSukumar Swaminathan SWAP32(ufi_hdr->controller.sub_vendor_id); 80882527734SSukumar Swaminathan ufi_hdr->controller.sub_device_id = 80982527734SSukumar Swaminathan SWAP32(ufi_hdr->controller.sub_device_id); 81082527734SSukumar Swaminathan ufi_hdr->file_length = 81182527734SSukumar Swaminathan SWAP32(ufi_hdr->file_length); 81282527734SSukumar Swaminathan ufi_hdr->chunk_num = 81382527734SSukumar Swaminathan SWAP32(ufi_hdr->chunk_num); 81482527734SSukumar Swaminathan ufi_hdr->chunk_cnt = 81582527734SSukumar Swaminathan SWAP32(ufi_hdr->chunk_cnt); 81682527734SSukumar Swaminathan ufi_hdr->image_cnt = 81782527734SSukumar Swaminathan SWAP32(ufi_hdr->image_cnt); 81882527734SSukumar Swaminathan #endif /* EMLXS_BIG_ENDIAN */ 81982527734SSukumar Swaminathan 82082527734SSukumar Swaminathan if (len != ufi_hdr->file_length) { 82182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 82282527734SSukumar Swaminathan "Invalid image size (%d != %d)", 82382527734SSukumar Swaminathan len, ufi_hdr->file_length); 82482527734SSukumar Swaminathan 82582527734SSukumar Swaminathan return (EMLXS_IMAGE_BAD); 82682527734SSukumar Swaminathan } 82782527734SSukumar Swaminathan 82882527734SSukumar Swaminathan /* Scan for flash dir signature */ 82982527734SSukumar Swaminathan bptr = (uint8_t *)buffer; 83082527734SSukumar Swaminathan flash_dir = NULL; 83182527734SSukumar Swaminathan for (i = 0; i < len; i++, bptr++) { 83282527734SSukumar Swaminathan if (strncmp((char *)bptr, BE_DIR_SIGNATURE, 83382527734SSukumar Swaminathan sizeof (BE_DIR_SIGNATURE)) == 0) { 834*a9800bebSGarrett D'Amore flash_dir = (emlxs_be2_flash_dir_t *)bptr; 83582527734SSukumar Swaminathan break; 83682527734SSukumar Swaminathan } 83782527734SSukumar Swaminathan } 83882527734SSukumar Swaminathan 83982527734SSukumar Swaminathan if (!flash_dir) { 84082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 84182527734SSukumar Swaminathan "Unable to find flash directory."); 84282527734SSukumar Swaminathan 84382527734SSukumar Swaminathan return (EMLXS_IMAGE_BAD); 84482527734SSukumar Swaminathan } 84582527734SSukumar Swaminathan 84682527734SSukumar Swaminathan #ifdef EMLXS_BIG_ENDIAN 84782527734SSukumar Swaminathan /* Big Endian Swapping */ 84882527734SSukumar Swaminathan /* Swap flash dir */ 84982527734SSukumar Swaminathan flash_dir->header.format_rev = 85082527734SSukumar Swaminathan SWAP32(flash_dir->header.format_rev); 85182527734SSukumar Swaminathan flash_dir->header.checksum = 85282527734SSukumar Swaminathan SWAP32(flash_dir->header.checksum); 85382527734SSukumar Swaminathan flash_dir->header.antidote = 85482527734SSukumar Swaminathan SWAP32(flash_dir->header.antidote); 85582527734SSukumar Swaminathan flash_dir->header.build_num = 85682527734SSukumar Swaminathan SWAP32(flash_dir->header.build_num); 85782527734SSukumar Swaminathan flash_dir->header.active_entry_mask = 85882527734SSukumar Swaminathan SWAP32(flash_dir->header.active_entry_mask); 85982527734SSukumar Swaminathan flash_dir->header.valid_entry_mask = 86082527734SSukumar Swaminathan SWAP32(flash_dir->header.valid_entry_mask); 86182527734SSukumar Swaminathan flash_dir->header.orig_content_mask = 86282527734SSukumar Swaminathan SWAP32(flash_dir->header.orig_content_mask); 86382527734SSukumar Swaminathan flash_dir->header.resv0 = SWAP32(flash_dir->header.resv0); 86482527734SSukumar Swaminathan flash_dir->header.resv1 = SWAP32(flash_dir->header.resv1); 86582527734SSukumar Swaminathan flash_dir->header.resv2 = SWAP32(flash_dir->header.resv2); 86682527734SSukumar Swaminathan flash_dir->header.resv3 = SWAP32(flash_dir->header.resv3); 86782527734SSukumar Swaminathan flash_dir->header.resv4 = SWAP32(flash_dir->header.resv4); 86882527734SSukumar Swaminathan 86982527734SSukumar Swaminathan for (i = 0; i < BE_CONTROLLER_SIZE; i++) { 87082527734SSukumar Swaminathan flash_dir->header.controller[i].vendor_id = 87182527734SSukumar Swaminathan SWAP32(flash_dir->header.controller[i].vendor_id); 87282527734SSukumar Swaminathan flash_dir->header.controller[i].device_id = 87382527734SSukumar Swaminathan SWAP32(flash_dir->header.controller[i].device_id); 87482527734SSukumar Swaminathan flash_dir->header.controller[i].sub_vendor_id = 87582527734SSukumar Swaminathan SWAP32(flash_dir->header.controller[i].sub_vendor_id); 87682527734SSukumar Swaminathan flash_dir->header.controller[i].sub_device_id = 87782527734SSukumar Swaminathan SWAP32(flash_dir->header.controller[i].sub_device_id); 87882527734SSukumar Swaminathan } 87982527734SSukumar Swaminathan 88082527734SSukumar Swaminathan for (i = 0, mask = 1; i < BE_FLASH_ENTRIES; i++, mask <<= 1) { 88182527734SSukumar Swaminathan 88282527734SSukumar Swaminathan if (!(flash_dir->header.valid_entry_mask & mask)) { 88382527734SSukumar Swaminathan continue; 88482527734SSukumar Swaminathan } 88582527734SSukumar Swaminathan 88682527734SSukumar Swaminathan entry = &flash_dir->entry[i]; 887*a9800bebSGarrett D'Amore 888*a9800bebSGarrett D'Amore if ((entry->type == 0) || 889*a9800bebSGarrett D'Amore (entry->type == (uint32_t)-1) || 890*a9800bebSGarrett D'Amore (entry->image_size == 0)) { 89182527734SSukumar Swaminathan continue; 89282527734SSukumar Swaminathan } 89382527734SSukumar Swaminathan 89482527734SSukumar Swaminathan flash_dir->entry[i].type = 89582527734SSukumar Swaminathan SWAP32(flash_dir->entry[i].type); 89682527734SSukumar Swaminathan flash_dir->entry[i].offset = 89782527734SSukumar Swaminathan SWAP32(flash_dir->entry[i].offset); 89882527734SSukumar Swaminathan flash_dir->entry[i].pad_size = 89982527734SSukumar Swaminathan SWAP32(flash_dir->entry[i].pad_size); 90082527734SSukumar Swaminathan flash_dir->entry[i].image_size = 90182527734SSukumar Swaminathan SWAP32(flash_dir->entry[i].image_size); 90282527734SSukumar Swaminathan flash_dir->entry[i].checksum = 90382527734SSukumar Swaminathan SWAP32(flash_dir->entry[i].checksum); 90482527734SSukumar Swaminathan flash_dir->entry[i].entry_point = 90582527734SSukumar Swaminathan SWAP32(flash_dir->entry[i].entry_point); 90682527734SSukumar Swaminathan flash_dir->entry[i].resv0 = 90782527734SSukumar Swaminathan SWAP32(flash_dir->entry[i].resv0); 90882527734SSukumar Swaminathan flash_dir->entry[i].resv1 = 90982527734SSukumar Swaminathan SWAP32(flash_dir->entry[i].resv1); 91082527734SSukumar Swaminathan } 91182527734SSukumar Swaminathan #endif /* EMLXS_BIG_ENDIAN */ 91282527734SSukumar Swaminathan 913*a9800bebSGarrett D'Amore /* Verify adapter model */ 914*a9800bebSGarrett D'Amore found = 0; 915*a9800bebSGarrett D'Amore for (i = 0; i < BE_CONTROLLER_SIZE; i++) { 916*a9800bebSGarrett D'Amore if (flash_dir->header.controller[i].device_id == 917*a9800bebSGarrett D'Amore hba->model_info.device_id) { 918*a9800bebSGarrett D'Amore found = 1; 919*a9800bebSGarrett D'Amore } 920*a9800bebSGarrett D'Amore } 921*a9800bebSGarrett D'Amore 922*a9800bebSGarrett D'Amore if (!found) { 923*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 924*a9800bebSGarrett D'Amore "Invalid adapter device id=0x%x.", 925*a9800bebSGarrett D'Amore hba->model_info.device_id); 926*a9800bebSGarrett D'Amore return (EMLXS_IMAGE_INCOMPATIBLE); 927*a9800bebSGarrett D'Amore } 928*a9800bebSGarrett D'Amore 92982527734SSukumar Swaminathan /* Build fw_image table */ 930*a9800bebSGarrett D'Amore fw_image->be_version = 2; 931*a9800bebSGarrett D'Amore fw_image->ufi_plus = ufi_plus; 93282527734SSukumar Swaminathan for (i = 0, mask = 1; i < BE_FLASH_ENTRIES; i++, mask <<= 1) { 93382527734SSukumar Swaminathan 93482527734SSukumar Swaminathan if (!(flash_dir->header.valid_entry_mask & mask)) { 93582527734SSukumar Swaminathan continue; 93682527734SSukumar Swaminathan } 93782527734SSukumar Swaminathan 93882527734SSukumar Swaminathan entry = &flash_dir->entry[i]; 939*a9800bebSGarrett D'Amore 940*a9800bebSGarrett D'Amore if ((entry->type == 0) || 941*a9800bebSGarrett D'Amore (entry->type == (uint32_t)-1) || 942*a9800bebSGarrett D'Amore (entry->image_size == 0)) { 94382527734SSukumar Swaminathan continue; 94482527734SSukumar Swaminathan } 94582527734SSukumar Swaminathan 94682527734SSukumar Swaminathan switch (entry->type) { 94782527734SSukumar Swaminathan case BE_FLASHTYPE_REDBOOT: 94882527734SSukumar Swaminathan file = &fw_image->file[REDBOOT_FLASHTYPE]; 94982527734SSukumar Swaminathan (void) strcpy(file->label, "REDBOOT"); 95082527734SSukumar Swaminathan file->type = MGMT_FLASHROM_OPTYPE_REDBOOT; 95182527734SSukumar Swaminathan break; 95282527734SSukumar Swaminathan case BE_FLASHTYPE_ISCSI_BIOS: 95382527734SSukumar Swaminathan file = &fw_image->file[ISCSI_BIOS_FLASHTYPE]; 95482527734SSukumar Swaminathan (void) strcpy(file->label, "ISCSI BIOS"); 95582527734SSukumar Swaminathan file->type = MGMT_FLASHROM_OPTYPE_ISCSI_BIOS; 95682527734SSukumar Swaminathan break; 95782527734SSukumar Swaminathan case BE_FLASHTYPE_PXE_BIOS: 95882527734SSukumar Swaminathan file = &fw_image->file[PXE_BIOS_FLASHTYPE]; 95982527734SSukumar Swaminathan (void) strcpy(file->label, "PXE BIOS"); 96082527734SSukumar Swaminathan file->type = MGMT_FLASHROM_OPTYPE_PXE_BIOS; 96182527734SSukumar Swaminathan break; 96282527734SSukumar Swaminathan case BE_FLASHTYPE_FCOE_BIOS: 96382527734SSukumar Swaminathan file = &fw_image->file[FCOE_BIOS_FLASHTYPE]; 96482527734SSukumar Swaminathan (void) strcpy(file->label, "FCOE BIOS"); 96582527734SSukumar Swaminathan file->type = MGMT_FLASHROM_OPTYPE_FCOE_BIOS; 96682527734SSukumar Swaminathan break; 96782527734SSukumar Swaminathan case BE_FLASHTYPE_ISCSI_FIRMWARE: 96882527734SSukumar Swaminathan file = &fw_image->file[ISCSI_FIRMWARE_FLASHTYPE]; 96982527734SSukumar Swaminathan (void) strcpy(file->label, "ISCSI FIRMWARE"); 97082527734SSukumar Swaminathan file->type = MGMT_FLASHROM_OPTYPE_ISCSI_FIRMWARE; 97182527734SSukumar Swaminathan break; 97282527734SSukumar Swaminathan case BE_FLASHTYPE_FCOE_FIRMWARE: 97382527734SSukumar Swaminathan file = &fw_image->file[FCOE_FIRMWARE_FLASHTYPE]; 97482527734SSukumar Swaminathan (void) strcpy(file->label, "FCOE FIRMWARE"); 97582527734SSukumar Swaminathan file->type = MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE; 97682527734SSukumar Swaminathan break; 97782527734SSukumar Swaminathan case BE_FLASHTYPE_FCOE_BACKUP: 97882527734SSukumar Swaminathan case BE_FLASHTYPE_ISCSI_BACKUP: 97982527734SSukumar Swaminathan continue; 98082527734SSukumar Swaminathan 98182527734SSukumar Swaminathan default: 98282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 98382527734SSukumar Swaminathan "Unknown image type found. type=%x", 98482527734SSukumar Swaminathan entry->type); 98582527734SSukumar Swaminathan continue; 98682527734SSukumar Swaminathan } 98782527734SSukumar Swaminathan 988*a9800bebSGarrett D'Amore file->be_version = fw_image->be_version; 989*a9800bebSGarrett D'Amore file->ufi_plus = fw_image->ufi_plus; 99082527734SSukumar Swaminathan file->image_size = entry->image_size; 99182527734SSukumar Swaminathan image_size = BE_SWAP32(entry->image_size); 99282527734SSukumar Swaminathan 99382527734SSukumar Swaminathan if (ufi_plus) { 99482527734SSukumar Swaminathan file->image_offset = entry->offset; 99582527734SSukumar Swaminathan file->block_size = entry->pad_size; 99682527734SSukumar Swaminathan file->block_crc = entry->checksum; 9976a573d82SSukumar Swaminathan file->load_address = entry->entry_point; 998*a9800bebSGarrett D'Amore 99982527734SSukumar Swaminathan } else { 100082527734SSukumar Swaminathan file->image_offset = entry->offset + 1001*a9800bebSGarrett D'Amore sizeof (emlxs_be2_ufi_header_t); 100282527734SSukumar Swaminathan 100382527734SSukumar Swaminathan /* Get entry block size and crc */ 100482527734SSukumar Swaminathan k = file->image_offset + file->image_size; 100582527734SSukumar Swaminathan k &= 0xFFFFFFFC; 100682527734SSukumar Swaminathan 100782527734SSukumar Swaminathan wptr = (uint32_t *)(buffer + k); 100882527734SSukumar Swaminathan for (; k < len; k += 4) { 100982527734SSukumar Swaminathan if (*wptr++ == image_size) { 101082527734SSukumar Swaminathan /* Calculate block_size */ 101182527734SSukumar Swaminathan file->block_size = (k + 8) - 101282527734SSukumar Swaminathan file->image_offset; 101382527734SSukumar Swaminathan 10146a573d82SSukumar Swaminathan /* Read load_address */ 10156a573d82SSukumar Swaminathan value = *(wptr - 2); 10166a573d82SSukumar Swaminathan file->load_address = BE_SWAP32(value); 10176a573d82SSukumar Swaminathan 101882527734SSukumar Swaminathan /* Read block_crc */ 101982527734SSukumar Swaminathan value = *wptr; 102082527734SSukumar Swaminathan file->block_crc = BE_SWAP32(value); 102182527734SSukumar Swaminathan 102282527734SSukumar Swaminathan break; 102382527734SSukumar Swaminathan } 102482527734SSukumar Swaminathan } 102582527734SSukumar Swaminathan 102682527734SSukumar Swaminathan if (k >= len) { 102782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 102882527734SSukumar Swaminathan "%s: End of block not found. offset=%x", 102982527734SSukumar Swaminathan file->label, file->image_offset); 103082527734SSukumar Swaminathan 103182527734SSukumar Swaminathan bzero(fw_image, sizeof (emlxs_be_fw_image_t)); 103282527734SSukumar Swaminathan return (EMLXS_IMAGE_BAD); 103382527734SSukumar Swaminathan } 103482527734SSukumar Swaminathan } 103582527734SSukumar Swaminathan 103682527734SSukumar Swaminathan /* Make sure image will fit in block specified */ 10376a573d82SSukumar Swaminathan if (file->image_size + 12 > file->block_size) { 103882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 103982527734SSukumar Swaminathan "%s: Image too large for block. image=%x block=%x", 104082527734SSukumar Swaminathan file->label, file->image_size, file->block_size); 104182527734SSukumar Swaminathan 104282527734SSukumar Swaminathan bzero(fw_image, sizeof (emlxs_be_fw_image_t)); 104382527734SSukumar Swaminathan return (EMLXS_IMAGE_BAD); 104482527734SSukumar Swaminathan } 104582527734SSukumar Swaminathan 104682527734SSukumar Swaminathan /* Automatically create a backup file entry for firmware */ 104782527734SSukumar Swaminathan if (file->type == MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE) { 104882527734SSukumar Swaminathan file2 = &fw_image->file[FCOE_BACKUP_FLASHTYPE]; 1049*a9800bebSGarrett D'Amore 1050*a9800bebSGarrett D'Amore bcopy((uint8_t *)file, (uint8_t *)file2, 1051*a9800bebSGarrett D'Amore sizeof (emlxs_be_fw_file_t)); 105282527734SSukumar Swaminathan file2->type = MGMT_FLASHROM_OPTYPE_FCOE_BACKUP; 1053*a9800bebSGarrett D'Amore (void) strcpy(file2->label, "FCOE BACKUP"); 105482527734SSukumar Swaminathan 105582527734SSukumar Swaminathan /* Save FCOE version info */ 105682527734SSukumar Swaminathan bptr = (uint8_t *)buffer + file->image_offset + 0x30; 1057*a9800bebSGarrett D'Amore (void) strncpy(fw_image->fcoe_label, (char *)bptr, 105882527734SSukumar Swaminathan BE_VERSION_SIZE); 1059*a9800bebSGarrett D'Amore fw_image->fcoe_version = file->block_crc; 106082527734SSukumar Swaminathan 106182527734SSukumar Swaminathan } else if (file->type == 106282527734SSukumar Swaminathan MGMT_FLASHROM_OPTYPE_ISCSI_FIRMWARE) { 106382527734SSukumar Swaminathan file2 = &fw_image->file[ISCSI_BACKUP_FLASHTYPE]; 1064*a9800bebSGarrett D'Amore 1065*a9800bebSGarrett D'Amore bcopy((uint8_t *)file, (uint8_t *)file2, 1066*a9800bebSGarrett D'Amore sizeof (emlxs_be_fw_file_t)); 1067*a9800bebSGarrett D'Amore file2->type = MGMT_FLASHROM_OPTYPE_ISCSI_BACKUP; 106882527734SSukumar Swaminathan (void) strcpy(file2->label, "ISCSI BACKUP"); 1069*a9800bebSGarrett D'Amore 1070*a9800bebSGarrett D'Amore /* Save ISCSI version info */ 1071*a9800bebSGarrett D'Amore bptr = (uint8_t *)buffer + file->image_offset + 0x30; 1072*a9800bebSGarrett D'Amore (void) strncpy(fw_image->iscsi_label, (char *)bptr, 1073*a9800bebSGarrett D'Amore BE_VERSION_SIZE); 1074*a9800bebSGarrett D'Amore fw_image->iscsi_version = file->block_crc; 1075*a9800bebSGarrett D'Amore } 1076*a9800bebSGarrett D'Amore } 1077*a9800bebSGarrett D'Amore 1078*a9800bebSGarrett D'Amore if (fw_image->fcoe_version == 0) { 1079*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1080*a9800bebSGarrett D'Amore "Unable to find FCOE firmware component."); 1081*a9800bebSGarrett D'Amore 1082*a9800bebSGarrett D'Amore bzero(fw_image, sizeof (emlxs_be_fw_image_t)); 1083*a9800bebSGarrett D'Amore return (EMLXS_IMAGE_BAD); 1084*a9800bebSGarrett D'Amore } 1085*a9800bebSGarrett D'Amore 1086*a9800bebSGarrett D'Amore /* Display contents */ 1087*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1088*a9800bebSGarrett D'Amore "BE2 UFI Image: %08x, %s", fw_image->fcoe_version, 1089*a9800bebSGarrett D'Amore fw_image->fcoe_label); 1090*a9800bebSGarrett D'Amore 1091*a9800bebSGarrett D'Amore for (i = 0; i < BE_MAX_FLASHTYPES; i++) { 1092*a9800bebSGarrett D'Amore file = &fw_image->file[i]; 1093*a9800bebSGarrett D'Amore 1094*a9800bebSGarrett D'Amore if (file->image_size == 0) { 1095*a9800bebSGarrett D'Amore continue; 1096*a9800bebSGarrett D'Amore } 1097*a9800bebSGarrett D'Amore 1098*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1099*a9800bebSGarrett D'Amore "%s: be=%x%s type=%x block=%x image=%x offset=%x crc=%x " 1100*a9800bebSGarrett D'Amore "load=%x", 1101*a9800bebSGarrett D'Amore file->label, file->be_version, (file->ufi_plus)?"+":"", 1102*a9800bebSGarrett D'Amore file->type, file->block_size, file->image_size, 1103*a9800bebSGarrett D'Amore file->image_offset, file->block_crc, file->load_address); 1104*a9800bebSGarrett D'Amore } 1105*a9800bebSGarrett D'Amore 1106*a9800bebSGarrett D'Amore return (0); 1107*a9800bebSGarrett D'Amore 1108*a9800bebSGarrett D'Amore } /* emlxs_be2_validate_image() */ 1109*a9800bebSGarrett D'Amore 1110*a9800bebSGarrett D'Amore 1111*a9800bebSGarrett D'Amore static uint32_t 1112*a9800bebSGarrett D'Amore emlxs_be3_validate_image(emlxs_hba_t *hba, caddr_t buffer, 1113*a9800bebSGarrett D'Amore uint32_t len, emlxs_be_fw_image_t *fw_image) 1114*a9800bebSGarrett D'Amore { 1115*a9800bebSGarrett D'Amore emlxs_port_t *port = &PPORT; 1116*a9800bebSGarrett D'Amore emlxs_be3_ufi_header_t *ufi_hdr; 1117*a9800bebSGarrett D'Amore emlxs_be3_flash_dir_t *flash_dir; 1118*a9800bebSGarrett D'Amore emlxs_be3_flash_entry_t *entry; 1119*a9800bebSGarrett D'Amore emlxs_be3_image_header_t *flash_image_hdr; 1120*a9800bebSGarrett D'Amore emlxs_be3_image_header_t *image_hdr; 1121*a9800bebSGarrett D'Amore uint8_t *bptr; 1122*a9800bebSGarrett D'Amore uint32_t *wptr; 1123*a9800bebSGarrett D'Amore uint32_t i; 1124*a9800bebSGarrett D'Amore uint32_t value; 1125*a9800bebSGarrett D'Amore emlxs_be_fw_file_t *file; 1126*a9800bebSGarrett D'Amore emlxs_be_fw_file_t *file2; 1127*a9800bebSGarrett D'Amore uint32_t ufi_plus = 0; 1128*a9800bebSGarrett D'Amore uint32_t be_version = 0; 1129*a9800bebSGarrett D'Amore uint32_t found; 1130*a9800bebSGarrett D'Amore 1131*a9800bebSGarrett D'Amore bzero(fw_image, sizeof (emlxs_be_fw_image_t)); 1132*a9800bebSGarrett D'Amore 1133*a9800bebSGarrett D'Amore if (hba->model_info.chip != EMLXS_BE3_CHIP) { 1134*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 1135*a9800bebSGarrett D'Amore "Invalid adapter model."); 1136*a9800bebSGarrett D'Amore return (EMLXS_IMAGE_INCOMPATIBLE); 1137*a9800bebSGarrett D'Amore } 1138*a9800bebSGarrett D'Amore 1139*a9800bebSGarrett D'Amore if (len < (sizeof (emlxs_be3_ufi_header_t) + 1140*a9800bebSGarrett D'Amore sizeof (emlxs_be3_flash_dir_t))) { 1141*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1142*a9800bebSGarrett D'Amore "Image too small. (%d < %d)", 1143*a9800bebSGarrett D'Amore len, (sizeof (emlxs_be3_ufi_header_t) + 1144*a9800bebSGarrett D'Amore sizeof (emlxs_be3_flash_dir_t))); 1145*a9800bebSGarrett D'Amore return (EMLXS_IMAGE_BAD); 1146*a9800bebSGarrett D'Amore } 1147*a9800bebSGarrett D'Amore 1148*a9800bebSGarrett D'Amore be_version = emlxs_be_version(buffer, len, &ufi_plus); 1149*a9800bebSGarrett D'Amore 1150*a9800bebSGarrett D'Amore /* Check if this is a standard BE3 image */ 1151*a9800bebSGarrett D'Amore if (be_version != 3) { 1152*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 1153*a9800bebSGarrett D'Amore "Invalid image provided."); 1154*a9800bebSGarrett D'Amore return (EMLXS_IMAGE_INCOMPATIBLE); 1155*a9800bebSGarrett D'Amore } 1156*a9800bebSGarrett D'Amore 1157*a9800bebSGarrett D'Amore ufi_hdr = (emlxs_be3_ufi_header_t *)buffer; 1158*a9800bebSGarrett D'Amore 1159*a9800bebSGarrett D'Amore #ifdef EMLXS_BIG_ENDIAN 1160*a9800bebSGarrett D'Amore /* Big Endian Swapping */ 1161*a9800bebSGarrett D'Amore /* Swap ufi header */ 1162*a9800bebSGarrett D'Amore ufi_hdr->ufi_version = 1163*a9800bebSGarrett D'Amore SWAP32(ufi_hdr->ufi_version); 1164*a9800bebSGarrett D'Amore ufi_hdr->file_length = 1165*a9800bebSGarrett D'Amore SWAP32(ufi_hdr->file_length); 1166*a9800bebSGarrett D'Amore ufi_hdr->checksum = 1167*a9800bebSGarrett D'Amore SWAP32(ufi_hdr->checksum); 1168*a9800bebSGarrett D'Amore ufi_hdr->antidote = 1169*a9800bebSGarrett D'Amore SWAP32(ufi_hdr->antidote); 1170*a9800bebSGarrett D'Amore ufi_hdr->image_cnt = 1171*a9800bebSGarrett D'Amore SWAP32(ufi_hdr->image_cnt); 1172*a9800bebSGarrett D'Amore #endif /* EMLXS_BIG_ENDIAN */ 1173*a9800bebSGarrett D'Amore 1174*a9800bebSGarrett D'Amore if (len != ufi_hdr->file_length) { 1175*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1176*a9800bebSGarrett D'Amore "Invalid image size (%d != %d)", 1177*a9800bebSGarrett D'Amore len, ufi_hdr->file_length); 1178*a9800bebSGarrett D'Amore 1179*a9800bebSGarrett D'Amore return (EMLXS_IMAGE_BAD); 1180*a9800bebSGarrett D'Amore } 1181*a9800bebSGarrett D'Amore 1182*a9800bebSGarrett D'Amore flash_image_hdr = NULL; 1183*a9800bebSGarrett D'Amore image_hdr = (emlxs_be3_image_header_t *)(buffer + 1184*a9800bebSGarrett D'Amore sizeof (emlxs_be3_ufi_header_t)); 1185*a9800bebSGarrett D'Amore for (i = 0; i < ufi_hdr->image_cnt; i++, image_hdr++) { 1186*a9800bebSGarrett D'Amore #ifdef EMLXS_BIG_ENDIAN 1187*a9800bebSGarrett D'Amore image_hdr->id = SWAP32(image_hdr->id); 1188*a9800bebSGarrett D'Amore image_hdr->offset = SWAP32(image_hdr->offset); 1189*a9800bebSGarrett D'Amore image_hdr->length = SWAP32(image_hdr->length); 1190*a9800bebSGarrett D'Amore image_hdr->checksum = SWAP32(image_hdr->checksum); 1191*a9800bebSGarrett D'Amore #endif /* EMLXS_BIG_ENDIAN */ 1192*a9800bebSGarrett D'Amore 1193*a9800bebSGarrett D'Amore if (image_hdr->id == UFI_BE3_FLASH_ID) { 1194*a9800bebSGarrett D'Amore flash_image_hdr = image_hdr; 1195*a9800bebSGarrett D'Amore } 1196*a9800bebSGarrett D'Amore } 1197*a9800bebSGarrett D'Amore 1198*a9800bebSGarrett D'Amore if (!flash_image_hdr) { 1199*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1200*a9800bebSGarrett D'Amore "No flash image found."); 1201*a9800bebSGarrett D'Amore 1202*a9800bebSGarrett D'Amore return (EMLXS_IMAGE_BAD); 1203*a9800bebSGarrett D'Amore } 1204*a9800bebSGarrett D'Amore 1205*a9800bebSGarrett D'Amore /* Scan for flash dir signature */ 1206*a9800bebSGarrett D'Amore bptr = (uint8_t *)buffer + flash_image_hdr->offset; 1207*a9800bebSGarrett D'Amore flash_dir = NULL; 1208*a9800bebSGarrett D'Amore for (i = 0; i < flash_image_hdr->length; i++, bptr++) { 1209*a9800bebSGarrett D'Amore if (strncmp((char *)bptr, BE_DIR_SIGNATURE, 1210*a9800bebSGarrett D'Amore sizeof (BE_DIR_SIGNATURE)) == 0) { 1211*a9800bebSGarrett D'Amore flash_dir = (emlxs_be3_flash_dir_t *)bptr; 1212*a9800bebSGarrett D'Amore break; 1213*a9800bebSGarrett D'Amore } 1214*a9800bebSGarrett D'Amore } 1215*a9800bebSGarrett D'Amore 1216*a9800bebSGarrett D'Amore if (!flash_dir) { 1217*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1218*a9800bebSGarrett D'Amore "Unable to find flash directory."); 1219*a9800bebSGarrett D'Amore 1220*a9800bebSGarrett D'Amore return (EMLXS_IMAGE_BAD); 1221*a9800bebSGarrett D'Amore } 1222*a9800bebSGarrett D'Amore 1223*a9800bebSGarrett D'Amore #ifdef EMLXS_BIG_ENDIAN 1224*a9800bebSGarrett D'Amore /* Big Endian Swapping */ 1225*a9800bebSGarrett D'Amore /* Swap flash dir */ 1226*a9800bebSGarrett D'Amore flash_dir->header.format_rev = 1227*a9800bebSGarrett D'Amore SWAP32(flash_dir->header.format_rev); 1228*a9800bebSGarrett D'Amore flash_dir->header.checksum = 1229*a9800bebSGarrett D'Amore SWAP32(flash_dir->header.checksum); 1230*a9800bebSGarrett D'Amore flash_dir->header.antidote = 1231*a9800bebSGarrett D'Amore SWAP32(flash_dir->header.antidote); 1232*a9800bebSGarrett D'Amore flash_dir->header.entry_count = 1233*a9800bebSGarrett D'Amore SWAP32(flash_dir->header.entry_count); 1234*a9800bebSGarrett D'Amore flash_dir->header.resv0 = SWAP32(flash_dir->header.resv0); 1235*a9800bebSGarrett D'Amore flash_dir->header.resv1 = SWAP32(flash_dir->header.resv1); 1236*a9800bebSGarrett D'Amore flash_dir->header.resv2 = SWAP32(flash_dir->header.resv2); 1237*a9800bebSGarrett D'Amore flash_dir->header.resv3 = SWAP32(flash_dir->header.resv3); 1238*a9800bebSGarrett D'Amore 1239*a9800bebSGarrett D'Amore for (i = 0; i < BE_CONTROLLER_SIZE; i++) { 1240*a9800bebSGarrett D'Amore flash_dir->header.controller[i].vendor_id = 1241*a9800bebSGarrett D'Amore SWAP32(flash_dir->header.controller[i].vendor_id); 1242*a9800bebSGarrett D'Amore flash_dir->header.controller[i].device_id = 1243*a9800bebSGarrett D'Amore SWAP32(flash_dir->header.controller[i].device_id); 1244*a9800bebSGarrett D'Amore flash_dir->header.controller[i].sub_vendor_id = 1245*a9800bebSGarrett D'Amore SWAP32(flash_dir->header.controller[i].sub_vendor_id); 1246*a9800bebSGarrett D'Amore flash_dir->header.controller[i].sub_device_id = 1247*a9800bebSGarrett D'Amore SWAP32(flash_dir->header.controller[i].sub_device_id); 1248*a9800bebSGarrett D'Amore } 1249*a9800bebSGarrett D'Amore 1250*a9800bebSGarrett D'Amore for (i = 0; i < flash_dir->header.entry_count; i++) { 1251*a9800bebSGarrett D'Amore entry = &flash_dir->entry[i]; 1252*a9800bebSGarrett D'Amore 1253*a9800bebSGarrett D'Amore if ((entry->type == 0) || 1254*a9800bebSGarrett D'Amore (entry->type == (uint32_t)-1) || 1255*a9800bebSGarrett D'Amore (entry->image_size == 0)) { 1256*a9800bebSGarrett D'Amore continue; 1257*a9800bebSGarrett D'Amore } 1258*a9800bebSGarrett D'Amore 1259*a9800bebSGarrett D'Amore flash_dir->entry[i].type = 1260*a9800bebSGarrett D'Amore SWAP32(flash_dir->entry[i].type); 1261*a9800bebSGarrett D'Amore flash_dir->entry[i].offset = 1262*a9800bebSGarrett D'Amore SWAP32(flash_dir->entry[i].offset); 1263*a9800bebSGarrett D'Amore flash_dir->entry[i].block_size = 1264*a9800bebSGarrett D'Amore SWAP32(flash_dir->entry[i].block_size); 1265*a9800bebSGarrett D'Amore flash_dir->entry[i].image_size = 1266*a9800bebSGarrett D'Amore SWAP32(flash_dir->entry[i].image_size); 1267*a9800bebSGarrett D'Amore flash_dir->entry[i].checksum = 1268*a9800bebSGarrett D'Amore SWAP32(flash_dir->entry[i].checksum); 1269*a9800bebSGarrett D'Amore flash_dir->entry[i].entry_point = 1270*a9800bebSGarrett D'Amore SWAP32(flash_dir->entry[i].entry_point); 1271*a9800bebSGarrett D'Amore flash_dir->entry[i].resv0 = 1272*a9800bebSGarrett D'Amore SWAP32(flash_dir->entry[i].resv0); 1273*a9800bebSGarrett D'Amore flash_dir->entry[i].resv1 = 1274*a9800bebSGarrett D'Amore SWAP32(flash_dir->entry[i].resv1); 1275*a9800bebSGarrett D'Amore } 1276*a9800bebSGarrett D'Amore #endif /* EMLXS_BIG_ENDIAN */ 1277*a9800bebSGarrett D'Amore 1278*a9800bebSGarrett D'Amore /* Verify image checksum */ 1279*a9800bebSGarrett D'Amore if (flash_dir->header.checksum != flash_image_hdr->checksum) { 1280*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1281*a9800bebSGarrett D'Amore "Invalid flash directory checksum. (%x != %x)\n", 1282*a9800bebSGarrett D'Amore flash_dir->header.checksum, flash_image_hdr->checksum); 1283*a9800bebSGarrett D'Amore return (EMLXS_IMAGE_BAD); 1284*a9800bebSGarrett D'Amore } 1285*a9800bebSGarrett D'Amore 1286*a9800bebSGarrett D'Amore /* Verify adapter model */ 1287*a9800bebSGarrett D'Amore found = 0; 1288*a9800bebSGarrett D'Amore for (i = 0; i < BE_CONTROLLER_SIZE; i++) { 1289*a9800bebSGarrett D'Amore if (flash_dir->header.controller[i].device_id == 1290*a9800bebSGarrett D'Amore hba->model_info.device_id) { 1291*a9800bebSGarrett D'Amore found = 1; 1292*a9800bebSGarrett D'Amore } 1293*a9800bebSGarrett D'Amore } 1294*a9800bebSGarrett D'Amore 1295*a9800bebSGarrett D'Amore if (!found) { 1296*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 1297*a9800bebSGarrett D'Amore "Invalid adapter device id=0x%x.", 1298*a9800bebSGarrett D'Amore hba->model_info.device_id); 1299*a9800bebSGarrett D'Amore return (EMLXS_IMAGE_INCOMPATIBLE); 1300*a9800bebSGarrett D'Amore } 1301*a9800bebSGarrett D'Amore 1302*a9800bebSGarrett D'Amore /* Build fw_image table */ 1303*a9800bebSGarrett D'Amore fw_image->be_version = 3; 1304*a9800bebSGarrett D'Amore fw_image->ufi_plus = ufi_plus; 1305*a9800bebSGarrett D'Amore for (i = 0; i < flash_dir->header.entry_count; i++) { 1306*a9800bebSGarrett D'Amore entry = &flash_dir->entry[i]; 1307*a9800bebSGarrett D'Amore 1308*a9800bebSGarrett D'Amore if ((entry->type == 0) || 1309*a9800bebSGarrett D'Amore (entry->type == (uint32_t)-1) || 1310*a9800bebSGarrett D'Amore (entry->image_size == 0)) { 1311*a9800bebSGarrett D'Amore continue; 1312*a9800bebSGarrett D'Amore } 1313*a9800bebSGarrett D'Amore 1314*a9800bebSGarrett D'Amore switch (entry->type) { 1315*a9800bebSGarrett D'Amore case BE_FLASHTYPE_REDBOOT: 1316*a9800bebSGarrett D'Amore file = &fw_image->file[REDBOOT_FLASHTYPE]; 1317*a9800bebSGarrett D'Amore (void) strcpy(file->label, "REDBOOT"); 1318*a9800bebSGarrett D'Amore file->type = MGMT_FLASHROM_OPTYPE_REDBOOT; 1319*a9800bebSGarrett D'Amore break; 1320*a9800bebSGarrett D'Amore case BE_FLASHTYPE_ISCSI_BIOS: 1321*a9800bebSGarrett D'Amore file = &fw_image->file[ISCSI_BIOS_FLASHTYPE]; 1322*a9800bebSGarrett D'Amore (void) strcpy(file->label, "ISCSI BIOS"); 1323*a9800bebSGarrett D'Amore file->type = MGMT_FLASHROM_OPTYPE_ISCSI_BIOS; 1324*a9800bebSGarrett D'Amore break; 1325*a9800bebSGarrett D'Amore case BE_FLASHTYPE_PXE_BIOS: 1326*a9800bebSGarrett D'Amore file = &fw_image->file[PXE_BIOS_FLASHTYPE]; 1327*a9800bebSGarrett D'Amore (void) strcpy(file->label, "PXE BIOS"); 1328*a9800bebSGarrett D'Amore file->type = MGMT_FLASHROM_OPTYPE_PXE_BIOS; 1329*a9800bebSGarrett D'Amore break; 1330*a9800bebSGarrett D'Amore case BE_FLASHTYPE_FCOE_BIOS: 1331*a9800bebSGarrett D'Amore file = &fw_image->file[FCOE_BIOS_FLASHTYPE]; 1332*a9800bebSGarrett D'Amore (void) strcpy(file->label, "FCOE BIOS"); 1333*a9800bebSGarrett D'Amore file->type = MGMT_FLASHROM_OPTYPE_FCOE_BIOS; 1334*a9800bebSGarrett D'Amore break; 1335*a9800bebSGarrett D'Amore case BE_FLASHTYPE_ISCSI_FIRMWARE: 1336*a9800bebSGarrett D'Amore file = &fw_image->file[ISCSI_FIRMWARE_FLASHTYPE]; 1337*a9800bebSGarrett D'Amore (void) strcpy(file->label, "ISCSI FIRMWARE"); 1338*a9800bebSGarrett D'Amore file->type = MGMT_FLASHROM_OPTYPE_ISCSI_FIRMWARE; 1339*a9800bebSGarrett D'Amore break; 1340*a9800bebSGarrett D'Amore case BE_FLASHTYPE_FCOE_FIRMWARE: 1341*a9800bebSGarrett D'Amore file = &fw_image->file[FCOE_FIRMWARE_FLASHTYPE]; 1342*a9800bebSGarrett D'Amore (void) strcpy(file->label, "FCOE FIRMWARE"); 1343*a9800bebSGarrett D'Amore file->type = MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE; 1344*a9800bebSGarrett D'Amore break; 1345*a9800bebSGarrett D'Amore case BE_FLASHTYPE_NCSI_FIRMWARE: 1346*a9800bebSGarrett D'Amore file = &fw_image->file[NCSI_FIRMWARE_FLASHTYPE]; 1347*a9800bebSGarrett D'Amore (void) strcpy(file->label, "NCSI FIRMWARE"); 1348*a9800bebSGarrett D'Amore file->type = MGMT_FLASHROM_OPTYPE_NCSI_FIRMWARE; 1349*a9800bebSGarrett D'Amore break; 1350*a9800bebSGarrett D'Amore case BE_FLASHTYPE_FLASH_ISM: 1351*a9800bebSGarrett D'Amore case BE_FLASHTYPE_FCOE_BACKUP: 1352*a9800bebSGarrett D'Amore case BE_FLASHTYPE_ISCSI_BACKUP: 1353*a9800bebSGarrett D'Amore continue; 1354*a9800bebSGarrett D'Amore 1355*a9800bebSGarrett D'Amore default: 1356*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1357*a9800bebSGarrett D'Amore "Unknown image type found. type=%x", 1358*a9800bebSGarrett D'Amore entry->type); 1359*a9800bebSGarrett D'Amore continue; 1360*a9800bebSGarrett D'Amore } 1361*a9800bebSGarrett D'Amore 1362*a9800bebSGarrett D'Amore file->be_version = fw_image->be_version; 1363*a9800bebSGarrett D'Amore file->ufi_plus = fw_image->ufi_plus; 1364*a9800bebSGarrett D'Amore file->image_size = entry->image_size; 1365*a9800bebSGarrett D'Amore 1366*a9800bebSGarrett D'Amore if (ufi_plus) { 1367*a9800bebSGarrett D'Amore file->image_offset = entry->offset; 1368*a9800bebSGarrett D'Amore file->block_size = entry->block_size; 1369*a9800bebSGarrett D'Amore file->block_crc = entry->checksum; 1370*a9800bebSGarrett D'Amore file->load_address = entry->entry_point; 1371*a9800bebSGarrett D'Amore } else { 1372*a9800bebSGarrett D'Amore file->image_offset = entry->offset + 1373*a9800bebSGarrett D'Amore flash_image_hdr->offset; 1374*a9800bebSGarrett D'Amore file->block_size = entry->block_size; 1375*a9800bebSGarrett D'Amore 1376*a9800bebSGarrett D'Amore wptr = (uint32_t *)(buffer + file->image_offset + 1377*a9800bebSGarrett D'Amore file->block_size); 1378*a9800bebSGarrett D'Amore 1379*a9800bebSGarrett D'Amore /* Read load address */ 1380*a9800bebSGarrett D'Amore value = *(wptr - 3); 1381*a9800bebSGarrett D'Amore file->load_address = BE_SWAP32(value); 1382*a9800bebSGarrett D'Amore 1383*a9800bebSGarrett D'Amore /* Read block_crc */ 1384*a9800bebSGarrett D'Amore value = *(wptr - 1); 1385*a9800bebSGarrett D'Amore file->block_crc = BE_SWAP32(value); 1386*a9800bebSGarrett D'Amore } 1387*a9800bebSGarrett D'Amore 1388*a9800bebSGarrett D'Amore /* Make sure image will fit in block specified */ 1389*a9800bebSGarrett D'Amore if (file->image_size + 12 > file->block_size) { 1390*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1391*a9800bebSGarrett D'Amore "%s: Image too large for block. image=%x block=%x", 1392*a9800bebSGarrett D'Amore file->label, file->image_size, file->block_size); 1393*a9800bebSGarrett D'Amore 1394*a9800bebSGarrett D'Amore bzero(fw_image, sizeof (emlxs_be_fw_image_t)); 1395*a9800bebSGarrett D'Amore return (EMLXS_IMAGE_BAD); 1396*a9800bebSGarrett D'Amore } 1397*a9800bebSGarrett D'Amore 1398*a9800bebSGarrett D'Amore /* Automatically create a backup file entry for firmware */ 1399*a9800bebSGarrett D'Amore if (file->type == MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE) { 1400*a9800bebSGarrett D'Amore file2 = &fw_image->file[FCOE_BACKUP_FLASHTYPE]; 1401*a9800bebSGarrett D'Amore 1402*a9800bebSGarrett D'Amore bcopy((uint8_t *)file, (uint8_t *)file2, 1403*a9800bebSGarrett D'Amore sizeof (emlxs_be_fw_file_t)); 1404*a9800bebSGarrett D'Amore file2->type = MGMT_FLASHROM_OPTYPE_FCOE_BACKUP; 1405*a9800bebSGarrett D'Amore (void) strcpy(file2->label, "FCOE BACKUP"); 1406*a9800bebSGarrett D'Amore 1407*a9800bebSGarrett D'Amore /* Save FCOE version info */ 1408*a9800bebSGarrett D'Amore bptr = (uint8_t *)buffer + file->image_offset + 0x30; 1409*a9800bebSGarrett D'Amore (void) strncpy(fw_image->fcoe_label, (char *)bptr, 1410*a9800bebSGarrett D'Amore BE_VERSION_SIZE); 1411*a9800bebSGarrett D'Amore fw_image->fcoe_version = file->block_crc; 1412*a9800bebSGarrett D'Amore 1413*a9800bebSGarrett D'Amore } else if (file->type == 1414*a9800bebSGarrett D'Amore MGMT_FLASHROM_OPTYPE_ISCSI_FIRMWARE) { 1415*a9800bebSGarrett D'Amore file2 = &fw_image->file[ISCSI_BACKUP_FLASHTYPE]; 1416*a9800bebSGarrett D'Amore 1417*a9800bebSGarrett D'Amore bcopy((uint8_t *)file, (uint8_t *)file2, 1418*a9800bebSGarrett D'Amore sizeof (emlxs_be_fw_file_t)); 141982527734SSukumar Swaminathan file2->type = MGMT_FLASHROM_OPTYPE_ISCSI_BACKUP; 1420*a9800bebSGarrett D'Amore (void) strcpy(file2->label, "ISCSI BACKUP"); 1421*a9800bebSGarrett D'Amore 1422*a9800bebSGarrett D'Amore /* Save ISCSI version info */ 1423*a9800bebSGarrett D'Amore bptr = (uint8_t *)buffer + file->image_offset + 0x30; 1424*a9800bebSGarrett D'Amore (void) strncpy(fw_image->iscsi_label, (char *)bptr, 1425*a9800bebSGarrett D'Amore BE_VERSION_SIZE); 1426*a9800bebSGarrett D'Amore fw_image->iscsi_version = file->block_crc; 142782527734SSukumar Swaminathan } 142882527734SSukumar Swaminathan } 142982527734SSukumar Swaminathan 1430*a9800bebSGarrett D'Amore if (fw_image->fcoe_version == 0) { 143182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 143282527734SSukumar Swaminathan "Unable to find FCOE firmware component."); 143382527734SSukumar Swaminathan 143482527734SSukumar Swaminathan bzero(fw_image, sizeof (emlxs_be_fw_image_t)); 143582527734SSukumar Swaminathan return (EMLXS_IMAGE_BAD); 143682527734SSukumar Swaminathan } 143782527734SSukumar Swaminathan 143882527734SSukumar Swaminathan /* Display contents */ 143982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1440*a9800bebSGarrett D'Amore "BE3 UFI Image: %08x, %s", fw_image->fcoe_version, 1441*a9800bebSGarrett D'Amore fw_image->fcoe_label); 144282527734SSukumar Swaminathan 144382527734SSukumar Swaminathan for (i = 0; i < BE_MAX_FLASHTYPES; i++) { 144482527734SSukumar Swaminathan file = &fw_image->file[i]; 144582527734SSukumar Swaminathan 144682527734SSukumar Swaminathan if (file->image_size == 0) { 144782527734SSukumar Swaminathan continue; 144882527734SSukumar Swaminathan } 144982527734SSukumar Swaminathan 145082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1451*a9800bebSGarrett D'Amore "%s: be=%x%s type=%x block=%x image=%x offset=%x crc=%x " 1452*a9800bebSGarrett D'Amore "load=%x", 1453*a9800bebSGarrett D'Amore file->label, file->be_version, (file->ufi_plus)? "+":"", 1454*a9800bebSGarrett D'Amore file->type, file->block_size, file->image_size, 1455*a9800bebSGarrett D'Amore file->image_offset, file->block_crc, file->load_address); 145682527734SSukumar Swaminathan } 145782527734SSukumar Swaminathan 145882527734SSukumar Swaminathan return (0); 145982527734SSukumar Swaminathan 1460*a9800bebSGarrett D'Amore } /* emlxs_be3_validate_image() */ 146182527734SSukumar Swaminathan 146282527734SSukumar Swaminathan 146382527734SSukumar Swaminathan static int32_t 146482527734SSukumar Swaminathan emlxs_sli4_fw_download(emlxs_hba_t *hba, caddr_t buffer, uint32_t len, 146582527734SSukumar Swaminathan uint32_t offline) 146682527734SSukumar Swaminathan { 146782527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 146882527734SSukumar Swaminathan uint32_t i; 146982527734SSukumar Swaminathan uint32_t update = 0; 147082527734SSukumar Swaminathan uint32_t rval = 0; 147182527734SSukumar Swaminathan MAILBOXQ *mbq = NULL; 147282527734SSukumar Swaminathan MATCHMAP *mp = NULL; 147382527734SSukumar Swaminathan emlxs_be_fw_image_t fw_image; 147482527734SSukumar Swaminathan emlxs_be_fw_file_t *file; 1475*a9800bebSGarrett D'Amore uint32_t be_version; 147682527734SSukumar Swaminathan 147782527734SSukumar Swaminathan /* For now we will not take the driver offline during a download */ 147882527734SSukumar Swaminathan offline = 0; 147982527734SSukumar Swaminathan 148082527734SSukumar Swaminathan if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) { 148182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 148282527734SSukumar Swaminathan "Invalid sli_mode. mode=%d", hba->sli_mode); 148382527734SSukumar Swaminathan return (EMLXS_IMAGE_INCOMPATIBLE); 148482527734SSukumar Swaminathan } 148582527734SSukumar Swaminathan 148682527734SSukumar Swaminathan if (buffer == NULL || len == 0) { 148782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 148882527734SSukumar Swaminathan "Empty buffer provided. buf=%p size=%d", buffer, len); 148982527734SSukumar Swaminathan return (EMLXS_IMAGE_BAD); 149082527734SSukumar Swaminathan } 149182527734SSukumar Swaminathan 1492*a9800bebSGarrett D'Amore be_version = emlxs_be_version(buffer, len, 0); 1493*a9800bebSGarrett D'Amore 1494*a9800bebSGarrett D'Amore switch (be_version) { 1495*a9800bebSGarrett D'Amore case 0: 1496*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 1497*a9800bebSGarrett D'Amore "Invalid image provided. Non-UFI format."); 1498*a9800bebSGarrett D'Amore return (EMLXS_IMAGE_INCOMPATIBLE); 1499*a9800bebSGarrett D'Amore case 2: 1500*a9800bebSGarrett D'Amore rval = emlxs_be2_validate_image(hba, buffer, len, &fw_image); 1501*a9800bebSGarrett D'Amore if (rval) { 1502*a9800bebSGarrett D'Amore return (rval); 1503*a9800bebSGarrett D'Amore } 1504*a9800bebSGarrett D'Amore break; 1505*a9800bebSGarrett D'Amore case 3: 1506*a9800bebSGarrett D'Amore rval = emlxs_be3_validate_image(hba, buffer, len, &fw_image); 1507*a9800bebSGarrett D'Amore if (rval) { 1508*a9800bebSGarrett D'Amore return (rval); 1509*a9800bebSGarrett D'Amore } 1510*a9800bebSGarrett D'Amore break; 1511*a9800bebSGarrett D'Amore default: 1512*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 1513*a9800bebSGarrett D'Amore "Invalid image provided. Unknown BE version. (%x)", 1514*a9800bebSGarrett D'Amore be_version); 1515*a9800bebSGarrett D'Amore return (EMLXS_IMAGE_INCOMPATIBLE); 151682527734SSukumar Swaminathan } 151782527734SSukumar Swaminathan 151882527734SSukumar Swaminathan /* Allocate resources */ 151982527734SSukumar Swaminathan 152082527734SSukumar Swaminathan if ((mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 152182527734SSukumar Swaminathan KM_SLEEP)) == NULL) { 152282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 152382527734SSukumar Swaminathan "Unable to allocate mailbox buffer."); 152482527734SSukumar Swaminathan 152582527734SSukumar Swaminathan offline = 0; 152682527734SSukumar Swaminathan rval = EMLXS_IMAGE_FAILED; 152782527734SSukumar Swaminathan goto done; 152882527734SSukumar Swaminathan } 152982527734SSukumar Swaminathan 153082527734SSukumar Swaminathan if ((mp = emlxs_mem_buf_alloc(hba, (sizeof (mbox_req_hdr_t) + 153182527734SSukumar Swaminathan sizeof (IOCTL_COMMON_FLASHROM) + BE_MAX_XFER_SIZE))) == NULL) { 153282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 153382527734SSukumar Swaminathan "Unable to allocate flash buffer."); 153482527734SSukumar Swaminathan 153582527734SSukumar Swaminathan offline = 0; 153682527734SSukumar Swaminathan rval = EMLXS_IMAGE_FAILED; 153782527734SSukumar Swaminathan goto done; 153882527734SSukumar Swaminathan } 153982527734SSukumar Swaminathan 154082527734SSukumar Swaminathan /* Check if update is required */ 154182527734SSukumar Swaminathan for (i = 0; i < BE_MAX_FLASHTYPES; i++) { 154282527734SSukumar Swaminathan file = &fw_image.file[i]; 154382527734SSukumar Swaminathan 154482527734SSukumar Swaminathan if (file->image_size == 0) { 154582527734SSukumar Swaminathan continue; 154682527734SSukumar Swaminathan } 154782527734SSukumar Swaminathan 154882527734SSukumar Swaminathan rval = emlxs_sli4_verify_crc(hba, file, mbq, mp); 1549fcf3ce44SJohn Forte 155082527734SSukumar Swaminathan if (rval == 0) { 1551*a9800bebSGarrett D'Amore /* Do not update */ 155282527734SSukumar Swaminathan file->image_size = 0; 155382527734SSukumar Swaminathan continue; 155482527734SSukumar Swaminathan } 155582527734SSukumar Swaminathan 155682527734SSukumar Swaminathan update++; 155782527734SSukumar Swaminathan } 155882527734SSukumar Swaminathan 155982527734SSukumar Swaminathan if (!update) { 156082527734SSukumar Swaminathan offline = 0; 1561*a9800bebSGarrett D'Amore rval = 0; 156282527734SSukumar Swaminathan goto done; 156382527734SSukumar Swaminathan } 156482527734SSukumar Swaminathan 156582527734SSukumar Swaminathan /* 156682527734SSukumar Swaminathan * Everything checks out, now to just do it 156782527734SSukumar Swaminathan */ 156882527734SSukumar Swaminathan if (offline) { 156982527734SSukumar Swaminathan if (emlxs_offline(hba) != FC_SUCCESS) { 157082527734SSukumar Swaminathan 157182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 157282527734SSukumar Swaminathan "Unable to take adapter offline."); 157382527734SSukumar Swaminathan 157482527734SSukumar Swaminathan offline = 0; 157582527734SSukumar Swaminathan rval = EMLXS_OFFLINE_FAILED; 157682527734SSukumar Swaminathan goto done; 157782527734SSukumar Swaminathan } 157882527734SSukumar Swaminathan } 157982527734SSukumar Swaminathan 158082527734SSukumar Swaminathan /* Download entries which require update */ 158182527734SSukumar Swaminathan for (i = 0; i < BE_MAX_FLASHTYPES; i++) { 158282527734SSukumar Swaminathan file = &fw_image.file[i]; 158382527734SSukumar Swaminathan 158482527734SSukumar Swaminathan if (file->image_size == 0) { 158582527734SSukumar Swaminathan continue; 158682527734SSukumar Swaminathan } 158782527734SSukumar Swaminathan 158882527734SSukumar Swaminathan rval = emlxs_sli4_flash_image(hba, buffer, file, mbq, mp); 158982527734SSukumar Swaminathan 159082527734SSukumar Swaminathan if (rval != 0) { 159182527734SSukumar Swaminathan goto done; 159282527734SSukumar Swaminathan } 159382527734SSukumar Swaminathan } 159482527734SSukumar Swaminathan 159582527734SSukumar Swaminathan done: 159682527734SSukumar Swaminathan if (mbq) { 1597*a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 159882527734SSukumar Swaminathan } 159982527734SSukumar Swaminathan 160082527734SSukumar Swaminathan if (mp) { 1601*a9800bebSGarrett D'Amore emlxs_mem_buf_free(hba, mp); 160282527734SSukumar Swaminathan } 160382527734SSukumar Swaminathan 160482527734SSukumar Swaminathan if (offline) { 160582527734SSukumar Swaminathan (void) emlxs_online(hba); 160682527734SSukumar Swaminathan } 160782527734SSukumar Swaminathan 160882527734SSukumar Swaminathan if (rval == 0) { 160982527734SSukumar Swaminathan if (update) { 161082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_complete_msg, 161182527734SSukumar Swaminathan "Status good."); 161282527734SSukumar Swaminathan 161382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_updated_msg, 161482527734SSukumar Swaminathan "Please reboot system or power cycle adapter " 1615*a9800bebSGarrett D'Amore "to activate new firmware: %s", 1616*a9800bebSGarrett D'Amore fw_image.fcoe_label); 161782527734SSukumar Swaminathan 161882527734SSukumar Swaminathan } else { 161982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 162082527734SSukumar Swaminathan "No firmware update required."); 162182527734SSukumar Swaminathan } 162282527734SSukumar Swaminathan } 162382527734SSukumar Swaminathan 162482527734SSukumar Swaminathan return (rval); 162582527734SSukumar Swaminathan 162682527734SSukumar Swaminathan } /* emlxs_sli4_fw_download() */ 1627fcf3ce44SJohn Forte 1628fcf3ce44SJohn Forte 1629fcf3ce44SJohn Forte extern int32_t 1630fcf3ce44SJohn Forte emlxs_cfl_download(emlxs_hba_t *hba, uint32_t region, caddr_t buffer, 1631fcf3ce44SJohn Forte uint32_t len) 1632fcf3ce44SJohn Forte { 1633fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1634fcf3ce44SJohn Forte MAILBOXQ *mbox = NULL; 1635fcf3ce44SJohn Forte MAILBOX *mb; 1636fcf3ce44SJohn Forte uint32_t rval = 0; 1637fcf3ce44SJohn Forte uint32_t region_id; 1638fcf3ce44SJohn Forte uint32_t id; 163982527734SSukumar Swaminathan #ifdef EMLXS_BIG_ENDIAN 1640fcf3ce44SJohn Forte caddr_t local_buffer; 1641fcf3ce44SJohn Forte uint32_t *bptr1; 1642fcf3ce44SJohn Forte uint32_t *bptr2; 1643fcf3ce44SJohn Forte uint32_t i; 164482527734SSukumar Swaminathan #endif /* EMLXS_BIG_ENDIAN */ 1645fcf3ce44SJohn Forte 1646fcf3ce44SJohn Forte if (buffer == NULL || len == 0) { 1647fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 1648fcf3ce44SJohn Forte } 164982527734SSukumar Swaminathan 165082527734SSukumar Swaminathan #ifdef EMLXS_BIG_ENDIAN 1651fcf3ce44SJohn Forte /* We need to swap the image buffer before we start */ 1652fcf3ce44SJohn Forte 1653fcf3ce44SJohn Forte /* 1654fcf3ce44SJohn Forte * Use KM_SLEEP to allocate a temporary buffer 1655fcf3ce44SJohn Forte */ 1656fcf3ce44SJohn Forte local_buffer = (caddr_t)kmem_zalloc(len, KM_SLEEP); 1657fcf3ce44SJohn Forte 1658fcf3ce44SJohn Forte /* Perform a 32 bit swap of the image */ 1659fcf3ce44SJohn Forte bptr1 = (uint32_t *)local_buffer; 1660fcf3ce44SJohn Forte bptr2 = (uint32_t *)buffer; 1661fcf3ce44SJohn Forte 1662fcf3ce44SJohn Forte for (i = 0; i < (len / 4); i++) { 166382527734SSukumar Swaminathan *bptr1 = SWAP32(*bptr2); 1664fcf3ce44SJohn Forte bptr1++; 1665fcf3ce44SJohn Forte bptr2++; 1666fcf3ce44SJohn Forte } 1667fcf3ce44SJohn Forte 1668fcf3ce44SJohn Forte /* Replace the original buffer */ 1669fcf3ce44SJohn Forte buffer = local_buffer; 1670fcf3ce44SJohn Forte 167182527734SSukumar Swaminathan #endif /* EMLXS_BIG_ENDIAN */ 1672fcf3ce44SJohn Forte 1673fcf3ce44SJohn Forte if (len > 128) { 1674fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1675291a2b48SSukumar Swaminathan "Invalid image length: 0x%x > 128", len); 1676fcf3ce44SJohn Forte 1677fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 1678fcf3ce44SJohn Forte } 1679291a2b48SSukumar Swaminathan 1680fcf3ce44SJohn Forte /* Check the region number */ 1681fcf3ce44SJohn Forte if ((region > 2) && (region != 0xff)) { 1682fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1683291a2b48SSukumar Swaminathan "Invalid region id: 0x%x", region); 1684fcf3ce44SJohn Forte 1685fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 1686fcf3ce44SJohn Forte 1687fcf3ce44SJohn Forte } 1688291a2b48SSukumar Swaminathan 1689fcf3ce44SJohn Forte /* Check the image vendor id */ 1690fcf3ce44SJohn Forte id = *(int32_t *)buffer; 1691fcf3ce44SJohn Forte if ((id & 0xffff) != 0x10df) { 1692fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1693291a2b48SSukumar Swaminathan "Invalid image id: 0x%x", id); 1694fcf3ce44SJohn Forte 1695fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 1696fcf3ce44SJohn Forte } 1697291a2b48SSukumar Swaminathan 1698291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1699291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 1700fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1701fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 1702fcf3ce44SJohn Forte 1703fcf3ce44SJohn Forte rval = 1; 1704fcf3ce44SJohn Forte 1705fcf3ce44SJohn Forte goto done; 1706fcf3ce44SJohn Forte } 1707291a2b48SSukumar Swaminathan 1708fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 1709fcf3ce44SJohn Forte 1710fcf3ce44SJohn Forte /* 1711fcf3ce44SJohn Forte * Everything checks out, now to just do it 1712fcf3ce44SJohn Forte */ 1713fcf3ce44SJohn Forte if (emlxs_offline(hba) != FC_SUCCESS) { 1714fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1715fcf3ce44SJohn Forte "Unable to take HBA offline."); 1716fcf3ce44SJohn Forte 1717fcf3ce44SJohn Forte rval = EMLXS_OFFLINE_FAILED; 1718fcf3ce44SJohn Forte 1719fcf3ce44SJohn Forte goto done; 1720fcf3ce44SJohn Forte } 1721291a2b48SSukumar Swaminathan 172282527734SSukumar Swaminathan if (EMLXS_SLI_HBA_RESET(hba, 1, 1, 0) != FC_SUCCESS) { 1723fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1724fcf3ce44SJohn Forte "Unable to restart adapter."); 1725fcf3ce44SJohn Forte 1726fcf3ce44SJohn Forte rval = EMLXS_OFFLINE_FAILED; 1727fcf3ce44SJohn Forte 1728fcf3ce44SJohn Forte goto done; 1729fcf3ce44SJohn Forte } 1730291a2b48SSukumar Swaminathan 1731fcf3ce44SJohn Forte /* Check if default region is requested */ 1732fcf3ce44SJohn Forte if (region == 0xff) { 1733fcf3ce44SJohn Forte /* 1734291a2b48SSukumar Swaminathan * Sun-branded Helios and Zypher have different 1735291a2b48SSukumar Swaminathan * default PCI region 1736fcf3ce44SJohn Forte */ 1737fcf3ce44SJohn Forte if ((hba->model_info.flags & EMLXS_SUN_BRANDED) && 1738fcf3ce44SJohn Forte (hba->model_info.chip & 1739fcf3ce44SJohn Forte (EMLXS_HELIOS_CHIP | EMLXS_ZEPHYR_CHIP))) { 1740fcf3ce44SJohn Forte region = 2; 1741fcf3ce44SJohn Forte } else { 1742fcf3ce44SJohn Forte region = 0; 1743fcf3ce44SJohn Forte } 1744fcf3ce44SJohn Forte } 1745291a2b48SSukumar Swaminathan 1746fcf3ce44SJohn Forte /* Set region id based on PCI region requested */ 1747fcf3ce44SJohn Forte region_id = DEF_PCI_CFG_REGION_ID + region; 1748fcf3ce44SJohn Forte 1749fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1750291a2b48SSukumar Swaminathan "PCI configuration: PCI%d region=%d id=0x%x size=%d", region, 1751291a2b48SSukumar Swaminathan region_id, id, len); 1752fcf3ce44SJohn Forte 1753fcf3ce44SJohn Forte /* Copy the data buffer to SLIM */ 1754fcf3ce44SJohn Forte WRITE_SLIM_COPY(hba, (uint32_t *)buffer, 175582527734SSukumar Swaminathan (volatile uint32_t *)((volatile char *)hba->sli.sli3.slim_addr + 1756291a2b48SSukumar Swaminathan sizeof (MAILBOX)), (len / sizeof (uint32_t))); 1757fcf3ce44SJohn Forte 17584baa2c25SSukumar Swaminathan #ifdef FMA_SUPPORT 175982527734SSukumar Swaminathan if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle) 17604baa2c25SSukumar Swaminathan != DDI_FM_OK) { 17614baa2c25SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 17624baa2c25SSukumar Swaminathan &emlxs_invalid_access_handle_msg, NULL); 17634baa2c25SSukumar Swaminathan rval = 1; 17644baa2c25SSukumar Swaminathan } 17654baa2c25SSukumar Swaminathan #endif /* FMA_SUPPORT */ 17664baa2c25SSukumar Swaminathan 176782527734SSukumar Swaminathan emlxs_format_update_pci_cfg(hba, mbox, region_id, len); 1768fcf3ce44SJohn Forte 176982527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 1770fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1771291a2b48SSukumar Swaminathan "Unable to update PCI configuration: Mailbox cmd=%x " 1772291a2b48SSukumar Swaminathan "status=%x info=%d", mb->mbxCommand, mb->mbxStatus, 1773fcf3ce44SJohn Forte mb->un.varUpdateCfg.rsp_info); 1774fcf3ce44SJohn Forte 1775fcf3ce44SJohn Forte rval = 1; 1776fcf3ce44SJohn Forte } 1777291a2b48SSukumar Swaminathan 1778fcf3ce44SJohn Forte (void) emlxs_online(hba); 1779fcf3ce44SJohn Forte 1780fcf3ce44SJohn Forte if (rval == 0) { 1781fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_complete_msg, 1782fcf3ce44SJohn Forte "Status good."); 1783fcf3ce44SJohn Forte } 1784291a2b48SSukumar Swaminathan 1785fcf3ce44SJohn Forte done: 1786fcf3ce44SJohn Forte 1787fcf3ce44SJohn Forte if (mbox) { 1788fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 1789fcf3ce44SJohn Forte } 179082527734SSukumar Swaminathan 179182527734SSukumar Swaminathan #ifdef EMLXS_BIG_ENDIAN 1792fcf3ce44SJohn Forte /* Free the local buffer */ 1793fcf3ce44SJohn Forte kmem_free(local_buffer, len); 179482527734SSukumar Swaminathan #endif /* EMLXS_BIG_ENDIAN */ 1795fcf3ce44SJohn Forte 1796fcf3ce44SJohn Forte return (rval); 1797fcf3ce44SJohn Forte 179882527734SSukumar Swaminathan } /* emlxs_cfl_download */ 1799fcf3ce44SJohn Forte 1800fcf3ce44SJohn Forte 1801fcf3ce44SJohn Forte static uint32_t 1802fcf3ce44SJohn Forte emlxs_valid_cksum(uint32_t *StartAddr, uint32_t *EndAddr) 1803fcf3ce44SJohn Forte { 1804fcf3ce44SJohn Forte uint32_t Temp; 1805fcf3ce44SJohn Forte uint32_t CkSum; 1806fcf3ce44SJohn Forte 1807fcf3ce44SJohn Forte EndAddr++; 1808fcf3ce44SJohn Forte CkSum = SLI_CKSUM_SEED; 1809fcf3ce44SJohn Forte 1810fcf3ce44SJohn Forte CkSum = (CkSum >> 1) | (CkSum << 31); 1811fcf3ce44SJohn Forte while (StartAddr != EndAddr) { 1812fcf3ce44SJohn Forte CkSum = (CkSum << 1) | (CkSum >> 31); 1813fcf3ce44SJohn Forte Temp = *StartAddr; 1814fcf3ce44SJohn Forte 1815fcf3ce44SJohn Forte CkSum ^= Temp; 1816fcf3ce44SJohn Forte StartAddr++; 1817fcf3ce44SJohn Forte } 1818fcf3ce44SJohn Forte 1819fcf3ce44SJohn Forte return (CkSum << 1) | (CkSum >> 31); 1820fcf3ce44SJohn Forte 182182527734SSukumar Swaminathan } /* emlxs_valid_cksum() */ 1822fcf3ce44SJohn Forte 1823fcf3ce44SJohn Forte 1824fcf3ce44SJohn Forte static void 1825fcf3ce44SJohn Forte emlxs_disp_aif_header(emlxs_hba_t *hba, PAIF_HDR AifHdr) 1826fcf3ce44SJohn Forte { 1827fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1828fcf3ce44SJohn Forte 1829291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "AIF Header: "); 1830fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1831fcf3ce44SJohn Forte "AIF Header: compress_br = 0x%x", AifHdr->CompressBr); 1832fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1833fcf3ce44SJohn Forte "AIF Header: reloc_br = 0x%x", AifHdr->RelocBr); 1834fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1835fcf3ce44SJohn Forte "AIF Header: zinit_br = 0x%x", AifHdr->ZinitBr); 1836fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1837fcf3ce44SJohn Forte "AIF Header: entry_br = 0x%x", AifHdr->EntryBr); 1838fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1839fcf3ce44SJohn Forte "AIF Header: area_id = 0x%x", AifHdr->Area_ID); 1840fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1841fcf3ce44SJohn Forte "AIF Header: rosize = 0x%x", AifHdr->RoSize); 1842fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1843fcf3ce44SJohn Forte "AIF Header: dbgsize = 0x%x", AifHdr->DbgSize); 1844fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1845fcf3ce44SJohn Forte "AIF Header: zinitsize = 0x%x", AifHdr->ZinitSize); 1846fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1847fcf3ce44SJohn Forte "AIF Header: dbgtype = 0x%x", AifHdr->DbgType); 1848fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1849fcf3ce44SJohn Forte "AIF Header: imagebase = 0x%x", AifHdr->ImageBase); 1850fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1851fcf3ce44SJohn Forte "AIF Header: area_size = 0x%x", AifHdr->Area_Size); 1852fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1853fcf3ce44SJohn Forte "AIF Header: address_mode = 0x%x", AifHdr->AddressMode); 1854fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1855fcf3ce44SJohn Forte "AIF Header: database = 0x%x", AifHdr->DataBase); 1856fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1857fcf3ce44SJohn Forte "AIF Header: aversion = 0x%x", AifHdr->AVersion); 1858fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1859fcf3ce44SJohn Forte "AIF Header: spare2 = 0x%x", AifHdr->Spare2); 1860fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1861fcf3ce44SJohn Forte "AIF Header: debug_swi = 0x%x", AifHdr->DebugSwi); 1862fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1863fcf3ce44SJohn Forte "AIF Header: zinitcode[0] = 0x%x", AifHdr->ZinitCode[0]); 1864fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1865fcf3ce44SJohn Forte "AIF Header: zinitcode[1] = 0x%x", AifHdr->ZinitCode[1]); 1866fcf3ce44SJohn Forte 186782527734SSukumar Swaminathan } /* emlxs_disp_aif_header() */ 1868fcf3ce44SJohn Forte 1869fcf3ce44SJohn Forte 1870fcf3ce44SJohn Forte 1871fcf3ce44SJohn Forte static void 1872fcf3ce44SJohn Forte emlxs_dump_image_header(emlxs_hba_t *hba, PIMAGE_HDR image) 1873fcf3ce44SJohn Forte { 1874fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1875fcf3ce44SJohn Forte 1876291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "Img Header: "); 1877fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1878fcf3ce44SJohn Forte "Img Header: BlockSize = 0x%x", image->BlockSize); 1879fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1880fcf3ce44SJohn Forte "Img Header: PROG_ID Type = 0x%x", image->Id.Type); 1881fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1882fcf3ce44SJohn Forte "Img Header: PROG_ID Id = 0x%x", image->Id.Id); 1883fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1884fcf3ce44SJohn Forte "Img Header: PROG_ID Ver = 0x%x", image->Id.Ver); 1885fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1886fcf3ce44SJohn Forte "Img Header: PROG_ID Rev = 0x%x", image->Id.Rev); 1887fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1888fcf3ce44SJohn Forte "Img Header: PROG_ID revcomp = 0x%x", image->Id.un.revcomp); 1889fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1890fcf3ce44SJohn Forte "Img Header: Flags = 0x%x", image->Flags); 1891fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1892fcf3ce44SJohn Forte "Img Header: EntryAdr = 0x%x", image->EntryAdr); 1893fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1894fcf3ce44SJohn Forte "Img Header: InitAdr = 0x%x", image->InitAdr); 1895fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1896fcf3ce44SJohn Forte "Img Header: ExitAdr = 0x%x", image->ExitAdr); 1897fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1898fcf3ce44SJohn Forte "Img Header: ImageBase = 0x%x", image->ImageBase); 1899fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1900fcf3ce44SJohn Forte "Img Header: ImageSize = 0x%x", image->ImageSize); 1901fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1902fcf3ce44SJohn Forte "Img Header: ZinitSize = 0x%x", image->ZinitSize); 1903fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1904fcf3ce44SJohn Forte "Img Header: RelocSize = 0x%x", image->RelocSize); 1905fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1906fcf3ce44SJohn Forte "Img Header: HdrCks = 0x%x", image->HdrCks); 1907fcf3ce44SJohn Forte 190882527734SSukumar Swaminathan } /* emlxs_dump_image_header() */ 1909fcf3ce44SJohn Forte 1910fcf3ce44SJohn Forte 1911fcf3ce44SJohn Forte static void 191282527734SSukumar Swaminathan emlxs_format_dump(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t Type, 191382527734SSukumar Swaminathan uint32_t RegionId, uint32_t WordCount, uint32_t BaseAddr) 1914fcf3ce44SJohn Forte { 1915fcf3ce44SJohn Forte 191682527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 191782527734SSukumar Swaminathan MAILBOX4 *mb = (MAILBOX4 *)mbq; 191882527734SSukumar Swaminathan 191982527734SSukumar Swaminathan /* Clear the local dump_region */ 192082527734SSukumar Swaminathan bzero(hba->sli.sli4.dump_region.virt, 192182527734SSukumar Swaminathan hba->sli.sli4.dump_region.size); 192282527734SSukumar Swaminathan 192382527734SSukumar Swaminathan bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 192482527734SSukumar Swaminathan 192582527734SSukumar Swaminathan mb->mbxCommand = MBX_DUMP_MEMORY; 192682527734SSukumar Swaminathan mb->un.varDmp4.type = Type; 192782527734SSukumar Swaminathan mb->un.varDmp4.entry_index = BaseAddr; 192882527734SSukumar Swaminathan mb->un.varDmp4.region_id = RegionId; 192982527734SSukumar Swaminathan 193082527734SSukumar Swaminathan mb->un.varDmp4.available_cnt = min((WordCount*4), 193182527734SSukumar Swaminathan hba->sli.sli4.dump_region.size); 193282527734SSukumar Swaminathan mb->un.varDmp4.addrHigh = 193382527734SSukumar Swaminathan PADDR_HI(hba->sli.sli4.dump_region.phys); 193482527734SSukumar Swaminathan mb->un.varDmp4.addrLow = 193582527734SSukumar Swaminathan PADDR_LO(hba->sli.sli4.dump_region.phys); 193682527734SSukumar Swaminathan mb->un.varDmp4.rsp_cnt = 0; 193782527734SSukumar Swaminathan 193882527734SSukumar Swaminathan mb->mbxOwner = OWN_HOST; 193982527734SSukumar Swaminathan 194082527734SSukumar Swaminathan } else { 194182527734SSukumar Swaminathan MAILBOX *mb = (MAILBOX *)mbq; 194282527734SSukumar Swaminathan 194382527734SSukumar Swaminathan bzero((void *)mb, MAILBOX_CMD_BSIZE); 194482527734SSukumar Swaminathan 194582527734SSukumar Swaminathan mb->mbxCommand = MBX_DUMP_MEMORY; 194682527734SSukumar Swaminathan mb->un.varDmp.type = Type; 194782527734SSukumar Swaminathan mb->un.varDmp.region_id = RegionId; 194882527734SSukumar Swaminathan mb->un.varDmp.word_cnt = WordCount; 194982527734SSukumar Swaminathan mb->un.varDmp.base_adr = BaseAddr; 195082527734SSukumar Swaminathan mb->mbxOwner = OWN_HOST; 195182527734SSukumar Swaminathan } 195282527734SSukumar Swaminathan 195382527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; /* no cmpl needed */ 1954fcf3ce44SJohn Forte 1955fcf3ce44SJohn Forte return; 1956fcf3ce44SJohn Forte 195782527734SSukumar Swaminathan } /* emlxs_format_dump() */ 1958fcf3ce44SJohn Forte 1959fcf3ce44SJohn Forte 1960fcf3ce44SJohn Forte /* ARGSUSED */ 1961fcf3ce44SJohn Forte static uint32_t 1962291a2b48SSukumar Swaminathan emlxs_start_abs_download(emlxs_hba_t *hba, 1963291a2b48SSukumar Swaminathan PAIF_HDR AifHdr, 1964291a2b48SSukumar Swaminathan caddr_t Buffer, 19656a573d82SSukumar Swaminathan uint32_t len, 19666a573d82SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms) 1967fcf3ce44SJohn Forte { 1968fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1969fcf3ce44SJohn Forte uint32_t DlByteCount = AifHdr->RoSize + AifHdr->RwSize; 1970fcf3ce44SJohn Forte uint32_t *Src; 1971fcf3ce44SJohn Forte uint32_t *Dst; 1972fcf3ce44SJohn Forte caddr_t DataBuffer = NULL; 1973fcf3ce44SJohn Forte MAILBOXQ *mbox; 1974fcf3ce44SJohn Forte MAILBOX *mb; 1975fcf3ce44SJohn Forte uint32_t rval = 1; 1976fcf3ce44SJohn Forte uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT; 1977fcf3ce44SJohn Forte uint32_t DlToAddr = AifHdr->ImageBase; 1978fcf3ce44SJohn Forte uint32_t DlCount; 1979fcf3ce44SJohn Forte uint32_t i; 19806a573d82SSukumar Swaminathan WAKE_UP_PARMS AbsWakeUpParms; 19816a573d82SSukumar Swaminathan int32_t AbsChangeParams; 1982fcf3ce44SJohn Forte 19836a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1984fcf3ce44SJohn Forte "Performing absolute download..."); 1985fcf3ce44SJohn Forte 1986291a2b48SSukumar Swaminathan if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT, 1987291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 1988fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1989fcf3ce44SJohn Forte "Unable to allocate data buffer."); 1990fcf3ce44SJohn Forte 1991fcf3ce44SJohn Forte return (rval); 1992fcf3ce44SJohn Forte } 1993291a2b48SSukumar Swaminathan 1994291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1995291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 1996fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1997fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 1998fcf3ce44SJohn Forte 1999fcf3ce44SJohn Forte kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 2000fcf3ce44SJohn Forte 2001fcf3ce44SJohn Forte return (rval); 2002fcf3ce44SJohn Forte } 2003fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 2004fcf3ce44SJohn Forte 20056a573d82SSukumar Swaminathan AbsChangeParams = emlxs_build_parms(Buffer, 20066a573d82SSukumar Swaminathan &AbsWakeUpParms, len, AifHdr); 20076a573d82SSukumar Swaminathan 2008fcf3ce44SJohn Forte Buffer += sizeof (AIF_HDR); 2009fcf3ce44SJohn Forte 20106a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "Erasing flash..."); 2011fcf3ce44SJohn Forte 20126a573d82SSukumar Swaminathan if (AifHdr->ImageBase == 0x20000) { 20136a573d82SSukumar Swaminathan /* DWC File */ 201482527734SSukumar Swaminathan emlxs_format_prog_flash(mbox, 0x20000, 0x50000, ERASE_FLASH, 0, 20156a573d82SSukumar Swaminathan 0, 0, NULL, 0); 2016fcf3ce44SJohn Forte } else { 201782527734SSukumar Swaminathan emlxs_format_prog_flash(mbox, DlToAddr, DlByteCount, 20186a573d82SSukumar Swaminathan ERASE_FLASH, 0, 0, 0, NULL, 0); 2019fcf3ce44SJohn Forte } 2020fcf3ce44SJohn Forte 202182527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2022fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2023fcf3ce44SJohn Forte "Unable to erase Flash: Mailbox cmd=%x status=%x", 2024fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 2025fcf3ce44SJohn Forte 2026fcf3ce44SJohn Forte rval = 1; 2027fcf3ce44SJohn Forte 2028fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 2029fcf3ce44SJohn Forte } 2030291a2b48SSukumar Swaminathan 20316a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 2032291a2b48SSukumar Swaminathan "Programming flash..."); 2033fcf3ce44SJohn Forte 2034fcf3ce44SJohn Forte while (DlByteCount) { 2035fcf3ce44SJohn Forte 2036fcf3ce44SJohn Forte if (DlByteCount > SegSize) { 2037fcf3ce44SJohn Forte DlCount = SegSize; 2038fcf3ce44SJohn Forte } else { 2039fcf3ce44SJohn Forte DlCount = DlByteCount; 2040fcf3ce44SJohn Forte } 2041fcf3ce44SJohn Forte DlByteCount -= DlCount; 2042fcf3ce44SJohn Forte 2043fcf3ce44SJohn Forte Dst = (uint32_t *)DataBuffer; 2044fcf3ce44SJohn Forte Src = (uint32_t *)Buffer; 2045fcf3ce44SJohn Forte 2046fcf3ce44SJohn Forte for (i = 0; i < (DlCount / 4); i++) { 2047fcf3ce44SJohn Forte *Dst = *Src; 2048fcf3ce44SJohn Forte Dst++; 2049fcf3ce44SJohn Forte Src++; 2050fcf3ce44SJohn Forte } 2051fcf3ce44SJohn Forte 2052fcf3ce44SJohn Forte WRITE_SLIM_COPY(hba, (uint32_t *)DataBuffer, 205382527734SSukumar Swaminathan (volatile uint32_t *) 205482527734SSukumar Swaminathan ((volatile char *)hba->sli.sli3.slim_addr + 2055291a2b48SSukumar Swaminathan sizeof (MAILBOX)), (DlCount / sizeof (uint32_t))); 2056fcf3ce44SJohn Forte 205782527734SSukumar Swaminathan emlxs_format_prog_flash(mbox, DlToAddr, DlCount, 20586a573d82SSukumar Swaminathan PROGRAM_FLASH, (DlByteCount) ? 0 : 1, 0, DlCount, NULL, 0); 2059fcf3ce44SJohn Forte 206082527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 2061291a2b48SSukumar Swaminathan MBX_SUCCESS) { 2062fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2063fcf3ce44SJohn Forte "Unable to program Flash: Mailbox cmd=%x status=%x", 2064fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 2065fcf3ce44SJohn Forte 2066fcf3ce44SJohn Forte rval = 1; 2067fcf3ce44SJohn Forte 2068fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 2069fcf3ce44SJohn Forte } 2070291a2b48SSukumar Swaminathan 2071fcf3ce44SJohn Forte Buffer += DlCount; 2072fcf3ce44SJohn Forte DlToAddr += DlCount; 2073fcf3ce44SJohn Forte } 2074fcf3ce44SJohn Forte 20754baa2c25SSukumar Swaminathan #ifdef FMA_SUPPORT 207682527734SSukumar Swaminathan if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle) 20774baa2c25SSukumar Swaminathan != DDI_FM_OK) { 20784baa2c25SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 20794baa2c25SSukumar Swaminathan &emlxs_invalid_access_handle_msg, NULL); 20804baa2c25SSukumar Swaminathan 20814baa2c25SSukumar Swaminathan rval = 1; 20824baa2c25SSukumar Swaminathan 20834baa2c25SSukumar Swaminathan goto EXIT_ABS_DOWNLOAD; 20844baa2c25SSukumar Swaminathan } 20854baa2c25SSukumar Swaminathan #endif /* FMA_SUPPORT */ 20864baa2c25SSukumar Swaminathan 2087fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, "Updating params..."); 2088fcf3ce44SJohn Forte 20896a573d82SSukumar Swaminathan if (AbsChangeParams) { 2090291a2b48SSukumar Swaminathan rval = 20916a573d82SSukumar Swaminathan emlxs_update_wakeup_parms(hba, &AbsWakeUpParms, 2092fcf3ce44SJohn Forte WakeUpParms); 2093fcf3ce44SJohn Forte } 2094fcf3ce44SJohn Forte 2095fcf3ce44SJohn Forte EXIT_ABS_DOWNLOAD: 2096fcf3ce44SJohn Forte if (DataBuffer) { 2097fcf3ce44SJohn Forte kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 2098fcf3ce44SJohn Forte } 2099291a2b48SSukumar Swaminathan 2100fcf3ce44SJohn Forte if (mbox) { 2101fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 2102fcf3ce44SJohn Forte } 2103291a2b48SSukumar Swaminathan 2104fcf3ce44SJohn Forte return (rval); 2105fcf3ce44SJohn Forte 210682527734SSukumar Swaminathan } /* emlxs_start_abs_download() */ 2107fcf3ce44SJohn Forte 2108fcf3ce44SJohn Forte 2109fcf3ce44SJohn Forte /* ARGSUSED */ 2110fcf3ce44SJohn Forte static void 211182527734SSukumar Swaminathan emlxs_format_prog_flash(MAILBOXQ *mbq, 2112291a2b48SSukumar Swaminathan uint32_t Base, 2113291a2b48SSukumar Swaminathan uint32_t DlByteCount, 2114291a2b48SSukumar Swaminathan uint32_t Function, 2115291a2b48SSukumar Swaminathan uint32_t Complete, 21166a573d82SSukumar Swaminathan uint32_t BdeAddress, 21176a573d82SSukumar Swaminathan uint32_t BdeSize, 21186a573d82SSukumar Swaminathan PROG_ID *ProgId, 21196a573d82SSukumar Swaminathan uint32_t keep) 2120fcf3ce44SJohn Forte { 212182527734SSukumar Swaminathan MAILBOX *mb = (MAILBOX *)mbq; 212282527734SSukumar Swaminathan 2123291a2b48SSukumar Swaminathan bzero((void *)mb, MAILBOX_CMD_BSIZE); 2124fcf3ce44SJohn Forte 21256a573d82SSukumar Swaminathan if (ProgId) { 2126fcf3ce44SJohn Forte mb->mbxCommand = MBX_DOWN_LOAD; 21276a573d82SSukumar Swaminathan } else { 2128fcf3ce44SJohn Forte mb->mbxCommand = MBX_LOAD_SM; 21296a573d82SSukumar Swaminathan } 2130fcf3ce44SJohn Forte 2131fcf3ce44SJohn Forte mb->un.varLdSM.load_cmplt = Complete; 2132fcf3ce44SJohn Forte mb->un.varLdSM.method = DL_FROM_SLIM; 2133fcf3ce44SJohn Forte mb->un.varLdSM.update_flash = 1; 2134fcf3ce44SJohn Forte mb->un.varLdSM.erase_or_prog = Function; 2135fcf3ce44SJohn Forte mb->un.varLdSM.dl_to_adr = Base; 2136fcf3ce44SJohn Forte mb->un.varLdSM.dl_len = DlByteCount; 21376a573d82SSukumar Swaminathan mb->un.varLdSM.keep = keep; 2138fcf3ce44SJohn Forte 2139fcf3ce44SJohn Forte if (BdeSize) { 2140fcf3ce44SJohn Forte mb->un.varLdSM.un.dl_from_slim_offset = DL_FROM_SLIM_OFFSET; 2141fcf3ce44SJohn Forte } else if (ProgId) { 2142fcf3ce44SJohn Forte mb->un.varLdSM.un.prog_id = *ProgId; 2143fcf3ce44SJohn Forte } else { 2144fcf3ce44SJohn Forte mb->un.varLdSM.un.dl_from_slim_offset = 0; 2145fcf3ce44SJohn Forte } 2146fcf3ce44SJohn Forte 2147fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 214882527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 2149fcf3ce44SJohn Forte 215082527734SSukumar Swaminathan } /* emlxs_format_prog_flash() */ 2151fcf3ce44SJohn Forte 2152fcf3ce44SJohn Forte 2153fcf3ce44SJohn Forte static void 215482527734SSukumar Swaminathan emlxs_format_update_parms(MAILBOXQ *mbq, PWAKE_UP_PARMS WakeUpParms) 2155fcf3ce44SJohn Forte { 215682527734SSukumar Swaminathan MAILBOX *mb = (MAILBOX *)mbq; 215782527734SSukumar Swaminathan 2158fcf3ce44SJohn Forte bzero((void *)mb, MAILBOX_CMD_BSIZE); 2159fcf3ce44SJohn Forte 2160fcf3ce44SJohn Forte mb->mbxCommand = MBX_UPDATE_CFG; 2161fcf3ce44SJohn Forte mb->un.varUpdateCfg.req_type = UPDATE_DATA; 2162fcf3ce44SJohn Forte mb->un.varUpdateCfg.region_id = WAKE_UP_PARMS_REGION_ID; 2163fcf3ce44SJohn Forte mb->un.varUpdateCfg.entry_len = sizeof (WAKE_UP_PARMS); 2164fcf3ce44SJohn Forte mb->un.varUpdateCfg.byte_len = sizeof (WAKE_UP_PARMS); 2165fcf3ce44SJohn Forte 2166291a2b48SSukumar Swaminathan bcopy((caddr_t)WakeUpParms, 2167291a2b48SSukumar Swaminathan (caddr_t)&(mb->un.varUpdateCfg.cfg_data), 2168fcf3ce44SJohn Forte sizeof (WAKE_UP_PARMS)); 216982527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 2170fcf3ce44SJohn Forte 217182527734SSukumar Swaminathan } /* emlxs_format_update_parms () */ 2172fcf3ce44SJohn Forte 2173fcf3ce44SJohn Forte 2174fcf3ce44SJohn Forte /* ARGSUSED */ 2175fcf3ce44SJohn Forte static void 217682527734SSukumar Swaminathan emlxs_format_update_pci_cfg(emlxs_hba_t *hba, MAILBOXQ *mbq, 2177fcf3ce44SJohn Forte uint32_t region_id, uint32_t size) 2178fcf3ce44SJohn Forte { 217982527734SSukumar Swaminathan MAILBOX *mb = (MAILBOX *)mbq; 218082527734SSukumar Swaminathan 2181fcf3ce44SJohn Forte bzero((void *)mb, MAILBOX_CMD_BSIZE); 2182fcf3ce44SJohn Forte 2183fcf3ce44SJohn Forte mb->mbxCommand = MBX_UPDATE_CFG; 2184fcf3ce44SJohn Forte mb->un.varUpdateCfg.Vbit = 1; 2185fcf3ce44SJohn Forte mb->un.varUpdateCfg.Obit = 1; 2186fcf3ce44SJohn Forte mb->un.varUpdateCfg.cfg_data = DL_FROM_SLIM_OFFSET; 2187fcf3ce44SJohn Forte mb->un.varUpdateCfg.req_type = UPDATE_DATA; 2188fcf3ce44SJohn Forte mb->un.varUpdateCfg.region_id = region_id; 2189fcf3ce44SJohn Forte mb->un.varUpdateCfg.entry_len = size; 2190fcf3ce44SJohn Forte mb->un.varUpdateCfg.byte_len = size; 219182527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 2192fcf3ce44SJohn Forte 219382527734SSukumar Swaminathan } /* emlxs_format_update_pci_cfg() */ 2194fcf3ce44SJohn Forte 2195fcf3ce44SJohn Forte 2196fcf3ce44SJohn Forte 2197fcf3ce44SJohn Forte static uint32_t 2198fcf3ce44SJohn Forte emlxs_update_boot_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 2199fcf3ce44SJohn Forte PROG_ID * prog_id, uint32_t proc_erom) 2200fcf3ce44SJohn Forte { 2201fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2202fcf3ce44SJohn Forte MAILBOX *mb; 2203fcf3ce44SJohn Forte MAILBOXQ *mbox; 2204fcf3ce44SJohn Forte uint32_t rval = 0; 22056a573d82SSukumar Swaminathan PROG_ID old_prog_id; 2206fcf3ce44SJohn Forte 2207291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2208291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2209fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2210fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 2211fcf3ce44SJohn Forte 2212fcf3ce44SJohn Forte return (1); 2213fcf3ce44SJohn Forte } 2214fcf3ce44SJohn Forte 2215291a2b48SSukumar Swaminathan mb = (MAILBOX *)mbox; 2216291a2b48SSukumar Swaminathan 2217291a2b48SSukumar Swaminathan if (proc_erom && !(hba->model_info.chip & 2218fcf3ce44SJohn Forte (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 2219fcf3ce44SJohn Forte WakeUpParms->u1.EROM_prog_id = *prog_id; 2220fcf3ce44SJohn Forte (void) emlxs_update_exp_rom(hba, WakeUpParms); 2221fcf3ce44SJohn Forte } 2222291a2b48SSukumar Swaminathan 22236a573d82SSukumar Swaminathan old_prog_id = WakeUpParms->u0.boot_bios_id; 2224fcf3ce44SJohn Forte WakeUpParms->u0.boot_bios_id = *prog_id; 2225fcf3ce44SJohn Forte 222682527734SSukumar Swaminathan emlxs_format_update_parms(mbox, WakeUpParms); 2227fcf3ce44SJohn Forte 222882527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2229fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2230291a2b48SSukumar Swaminathan "Unable to update boot wakeup parms: Mailbox cmd=%x " 2231291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 2232fcf3ce44SJohn Forte 22336a573d82SSukumar Swaminathan WakeUpParms->u0.boot_bios_id = old_prog_id; 2234fcf3ce44SJohn Forte rval = 1; 2235fcf3ce44SJohn Forte } 2236291a2b48SSukumar Swaminathan 2237fcf3ce44SJohn Forte if (mbox) { 2238fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 2239fcf3ce44SJohn Forte } 2240291a2b48SSukumar Swaminathan 2241fcf3ce44SJohn Forte return (rval); 2242fcf3ce44SJohn Forte 224382527734SSukumar Swaminathan } /* emlxs_update_boot_wakeup_parms() */ 2244fcf3ce44SJohn Forte 2245fcf3ce44SJohn Forte 2246fcf3ce44SJohn Forte 2247fcf3ce44SJohn Forte static uint32_t 2248fcf3ce44SJohn Forte emlxs_update_ff_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 2249fcf3ce44SJohn Forte PROG_ID *prog_id) 2250fcf3ce44SJohn Forte { 2251fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2252fcf3ce44SJohn Forte uint32_t rval = 0; 2253fcf3ce44SJohn Forte MAILBOXQ *mbox; 2254fcf3ce44SJohn Forte MAILBOX *mb; 22556a573d82SSukumar Swaminathan PROG_ID old_prog_id; 2256fcf3ce44SJohn Forte 2257291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2258291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2259fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2260fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 2261fcf3ce44SJohn Forte 2262fcf3ce44SJohn Forte return (1); 2263fcf3ce44SJohn Forte } 2264291a2b48SSukumar Swaminathan 22656a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 22666a573d82SSukumar Swaminathan "FF: Updating parms..."); 22676a573d82SSukumar Swaminathan 2268fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 2269fcf3ce44SJohn Forte 22706a573d82SSukumar Swaminathan old_prog_id = WakeUpParms->prog_id; 2271fcf3ce44SJohn Forte WakeUpParms->prog_id = *prog_id; 2272fcf3ce44SJohn Forte 227382527734SSukumar Swaminathan emlxs_format_update_parms(mbox, WakeUpParms); 2274fcf3ce44SJohn Forte 227582527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2276fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2277291a2b48SSukumar Swaminathan "Unable to update wakeup parameters: Mailbox cmd=%x " 2278291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 2279fcf3ce44SJohn Forte 22806a573d82SSukumar Swaminathan WakeUpParms->prog_id = old_prog_id; 2281fcf3ce44SJohn Forte rval = 1; 2282fcf3ce44SJohn Forte } 2283291a2b48SSukumar Swaminathan 2284fcf3ce44SJohn Forte if (mbox) { 2285fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 2286fcf3ce44SJohn Forte } 2287291a2b48SSukumar Swaminathan 2288fcf3ce44SJohn Forte return (rval); 2289fcf3ce44SJohn Forte 229082527734SSukumar Swaminathan } /* emlxs_update_ff_wakeup_parms() */ 2291fcf3ce44SJohn Forte 2292fcf3ce44SJohn Forte 2293fcf3ce44SJohn Forte static uint32_t 2294fcf3ce44SJohn Forte emlxs_update_sli1_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 2295291a2b48SSukumar Swaminathan PROG_ID * prog_id) 2296fcf3ce44SJohn Forte { 2297fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2298fcf3ce44SJohn Forte uint32_t rval = 0; 2299fcf3ce44SJohn Forte MAILBOXQ *mbox; 2300fcf3ce44SJohn Forte MAILBOX *mb; 23016a573d82SSukumar Swaminathan PROG_ID old_prog_id; 2302fcf3ce44SJohn Forte 2303291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2304291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2305fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2306fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 2307fcf3ce44SJohn Forte 2308fcf3ce44SJohn Forte return (1); 2309fcf3ce44SJohn Forte } 2310291a2b48SSukumar Swaminathan 23116a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 23126a573d82SSukumar Swaminathan "SLI1: Updating parms..."); 23136a573d82SSukumar Swaminathan 2314fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 2315fcf3ce44SJohn Forte 23166a573d82SSukumar Swaminathan old_prog_id = WakeUpParms->sli1_prog_id; 2317fcf3ce44SJohn Forte WakeUpParms->sli1_prog_id = *prog_id; 2318fcf3ce44SJohn Forte 231982527734SSukumar Swaminathan emlxs_format_update_parms(mbox, WakeUpParms); 2320fcf3ce44SJohn Forte 232182527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2322fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2323291a2b48SSukumar Swaminathan "Unable to update wakeup parameters. Mailbox cmd=%x " 2324291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 2325fcf3ce44SJohn Forte 23266a573d82SSukumar Swaminathan WakeUpParms->sli1_prog_id = old_prog_id; 2327fcf3ce44SJohn Forte rval = 1; 2328fcf3ce44SJohn Forte } 2329291a2b48SSukumar Swaminathan 2330fcf3ce44SJohn Forte if (mbox) { 2331fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 2332fcf3ce44SJohn Forte } 2333291a2b48SSukumar Swaminathan 2334fcf3ce44SJohn Forte return (rval); 2335fcf3ce44SJohn Forte 233682527734SSukumar Swaminathan } /* emlxs_update_sli1_wakeup_parms() */ 2337fcf3ce44SJohn Forte 2338fcf3ce44SJohn Forte 2339fcf3ce44SJohn Forte static uint32_t 2340fcf3ce44SJohn Forte emlxs_update_sli2_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 2341291a2b48SSukumar Swaminathan PROG_ID * prog_id) 2342fcf3ce44SJohn Forte { 2343fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2344fcf3ce44SJohn Forte uint32_t rval = 0; 2345fcf3ce44SJohn Forte MAILBOXQ *mbox; 2346fcf3ce44SJohn Forte MAILBOX *mb; 23476a573d82SSukumar Swaminathan PROG_ID old_prog_id; 2348fcf3ce44SJohn Forte 2349291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2350291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2351fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2352fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 2353fcf3ce44SJohn Forte 2354fcf3ce44SJohn Forte return (1); 2355fcf3ce44SJohn Forte } 2356291a2b48SSukumar Swaminathan 23576a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 23586a573d82SSukumar Swaminathan "SLI2: Updating parms..."); 23596a573d82SSukumar Swaminathan 2360fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 2361fcf3ce44SJohn Forte 23626a573d82SSukumar Swaminathan old_prog_id = WakeUpParms->sli2_prog_id; 2363fcf3ce44SJohn Forte WakeUpParms->sli2_prog_id = *prog_id; 2364fcf3ce44SJohn Forte 236582527734SSukumar Swaminathan emlxs_format_update_parms(mbox, WakeUpParms); 2366fcf3ce44SJohn Forte 236782527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2368fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2369291a2b48SSukumar Swaminathan "Unable to update wakeup parameters. Mailbox cmd=%x " 2370291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 2371fcf3ce44SJohn Forte 23726a573d82SSukumar Swaminathan WakeUpParms->sli2_prog_id = old_prog_id; 2373fcf3ce44SJohn Forte rval = 1; 2374fcf3ce44SJohn Forte } 2375291a2b48SSukumar Swaminathan 2376fcf3ce44SJohn Forte if (mbox) { 2377fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 2378fcf3ce44SJohn Forte } 2379291a2b48SSukumar Swaminathan 2380fcf3ce44SJohn Forte return (rval); 2381fcf3ce44SJohn Forte 238282527734SSukumar Swaminathan } /* emlxs_update_sli2_wakeup_parms() */ 2383fcf3ce44SJohn Forte 2384fcf3ce44SJohn Forte 2385fcf3ce44SJohn Forte static uint32_t 2386fcf3ce44SJohn Forte emlxs_update_sli3_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 2387fcf3ce44SJohn Forte PROG_ID *prog_id) 2388fcf3ce44SJohn Forte { 2389fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2390fcf3ce44SJohn Forte uint32_t rval = 0; 2391fcf3ce44SJohn Forte MAILBOXQ *mbox; 2392fcf3ce44SJohn Forte MAILBOX *mb; 23936a573d82SSukumar Swaminathan PROG_ID old_prog_id; 2394fcf3ce44SJohn Forte 2395291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2396291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2397fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2398fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 2399fcf3ce44SJohn Forte 2400fcf3ce44SJohn Forte return (1); 2401fcf3ce44SJohn Forte } 2402291a2b48SSukumar Swaminathan 24036a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 24046a573d82SSukumar Swaminathan "SLI3: Updating parms..."); 24056a573d82SSukumar Swaminathan 2406fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 2407fcf3ce44SJohn Forte 24086a573d82SSukumar Swaminathan old_prog_id = WakeUpParms->sli3_prog_id; 2409fcf3ce44SJohn Forte WakeUpParms->sli3_prog_id = *prog_id; 2410fcf3ce44SJohn Forte 241182527734SSukumar Swaminathan emlxs_format_update_parms(mbox, WakeUpParms); 2412fcf3ce44SJohn Forte 241382527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2414fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2415291a2b48SSukumar Swaminathan "Unable to update wakeup parameters. Mailbox cmd=%x " 2416291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 2417fcf3ce44SJohn Forte 24186a573d82SSukumar Swaminathan WakeUpParms->sli3_prog_id = old_prog_id; 2419fcf3ce44SJohn Forte rval = 1; 2420fcf3ce44SJohn Forte } 2421291a2b48SSukumar Swaminathan 2422fcf3ce44SJohn Forte if (mbox) { 2423fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 2424fcf3ce44SJohn Forte } 2425291a2b48SSukumar Swaminathan 2426fcf3ce44SJohn Forte return (rval); 2427fcf3ce44SJohn Forte 242882527734SSukumar Swaminathan } /* emlxs_update_sli3_wakeup_parms() */ 2429fcf3ce44SJohn Forte 2430fcf3ce44SJohn Forte 2431fcf3ce44SJohn Forte static uint32_t 2432fcf3ce44SJohn Forte emlxs_update_sli4_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 2433fcf3ce44SJohn Forte PROG_ID *prog_id) 2434fcf3ce44SJohn Forte { 2435fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2436fcf3ce44SJohn Forte uint32_t rval = 0; 2437fcf3ce44SJohn Forte MAILBOXQ *mbox; 2438fcf3ce44SJohn Forte MAILBOX *mb; 24396a573d82SSukumar Swaminathan PROG_ID old_prog_id; 2440fcf3ce44SJohn Forte 2441291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2442291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2443fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2444fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 2445fcf3ce44SJohn Forte 2446fcf3ce44SJohn Forte return (1); 2447fcf3ce44SJohn Forte } 2448291a2b48SSukumar Swaminathan 24496a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 24506a573d82SSukumar Swaminathan "SLI4: Updating parms..."); 24516a573d82SSukumar Swaminathan 2452fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 2453fcf3ce44SJohn Forte 24546a573d82SSukumar Swaminathan old_prog_id = WakeUpParms->sli4_prog_id; 2455fcf3ce44SJohn Forte WakeUpParms->sli4_prog_id = *prog_id; 2456fcf3ce44SJohn Forte 245782527734SSukumar Swaminathan emlxs_format_update_parms(mbox, WakeUpParms); 2458fcf3ce44SJohn Forte 245982527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2460fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2461291a2b48SSukumar Swaminathan "Unable to update wakeup parameters. Mailbox cmd=%x " 2462291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 2463fcf3ce44SJohn Forte 24646a573d82SSukumar Swaminathan WakeUpParms->sli4_prog_id = old_prog_id; 2465fcf3ce44SJohn Forte rval = 1; 2466fcf3ce44SJohn Forte } 2467291a2b48SSukumar Swaminathan 2468fcf3ce44SJohn Forte if (mbox) { 2469fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 2470fcf3ce44SJohn Forte } 2471291a2b48SSukumar Swaminathan 2472fcf3ce44SJohn Forte return (rval); 2473fcf3ce44SJohn Forte 247482527734SSukumar Swaminathan } /* emlxs_update_sli4_wakeup_parms() */ 2475fcf3ce44SJohn Forte 2476fcf3ce44SJohn Forte 24776a573d82SSukumar Swaminathan static uint32_t 24786a573d82SSukumar Swaminathan emlxs_clean_flash(emlxs_hba_t *hba, 24796a573d82SSukumar Swaminathan PWAKE_UP_PARMS OldWakeUpParms, PWAKE_UP_PARMS NewWakeUpParms) 24806a573d82SSukumar Swaminathan { 24816a573d82SSukumar Swaminathan emlxs_port_t *port = &PPORT; 24826a573d82SSukumar Swaminathan PROG_ID load_list[MAX_LOAD_ENTRY]; 24836a573d82SSukumar Swaminathan PROG_ID *wakeup_list[MAX_LOAD_ENTRY]; 24846a573d82SSukumar Swaminathan uint32_t count; 24856a573d82SSukumar Swaminathan uint32_t i; 24866a573d82SSukumar Swaminathan uint32_t j; 24876a573d82SSukumar Swaminathan uint32_t k = 0; 24886a573d82SSukumar Swaminathan uint32_t *wptr; 24896a573d82SSukumar Swaminathan 24906a573d82SSukumar Swaminathan if (!NewWakeUpParms) { 24916a573d82SSukumar Swaminathan return (1); 24926a573d82SSukumar Swaminathan } 24936a573d82SSukumar Swaminathan 24946a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 24956a573d82SSukumar Swaminathan "Cleaning flash..."); 24966a573d82SSukumar Swaminathan 24976a573d82SSukumar Swaminathan /* If old wakeup parameter list is available, */ 24986a573d82SSukumar Swaminathan /* then cleanup old entries */ 24996a573d82SSukumar Swaminathan if (OldWakeUpParms) { 25006a573d82SSukumar Swaminathan if (bcmp(&OldWakeUpParms->prog_id, &NewWakeUpParms->prog_id, 25016a573d82SSukumar Swaminathan sizeof (PROG_ID))) { 25026a573d82SSukumar Swaminathan 25036a573d82SSukumar Swaminathan wptr = (uint32_t *)&OldWakeUpParms->prog_id; 25046a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 25056a573d82SSukumar Swaminathan "OLD: prog_id: 0x%08x 0x%08x Removing.", 25066a573d82SSukumar Swaminathan wptr[0], wptr[1]); 25076a573d82SSukumar Swaminathan 25086a573d82SSukumar Swaminathan (void) emlxs_delete_load_entry(hba, 25096a573d82SSukumar Swaminathan &OldWakeUpParms->prog_id); 25106a573d82SSukumar Swaminathan } 25116a573d82SSukumar Swaminathan 25126a573d82SSukumar Swaminathan if (bcmp(&OldWakeUpParms->u0.boot_bios_id, 25136a573d82SSukumar Swaminathan &NewWakeUpParms->u0.boot_bios_id, sizeof (PROG_ID))) { 25146a573d82SSukumar Swaminathan 25156a573d82SSukumar Swaminathan wptr = (uint32_t *)&OldWakeUpParms->u0.boot_bios_id; 25166a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 25176a573d82SSukumar Swaminathan "OLD: boot_bios_id: 0x%08x 0x%08x Removing.", 25186a573d82SSukumar Swaminathan wptr[0], wptr[1]); 25196a573d82SSukumar Swaminathan 25206a573d82SSukumar Swaminathan (void) emlxs_delete_load_entry(hba, 25216a573d82SSukumar Swaminathan &OldWakeUpParms->u0.boot_bios_id); 25226a573d82SSukumar Swaminathan } 25236a573d82SSukumar Swaminathan 25246a573d82SSukumar Swaminathan if (bcmp(&OldWakeUpParms->sli1_prog_id, 25256a573d82SSukumar Swaminathan &NewWakeUpParms->sli1_prog_id, sizeof (PROG_ID))) { 25266a573d82SSukumar Swaminathan 25276a573d82SSukumar Swaminathan wptr = (uint32_t *)&OldWakeUpParms->sli1_prog_id; 25286a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 25296a573d82SSukumar Swaminathan "OLD: sli1_prog_id: 0x%08x 0x%08x Removing.", 25306a573d82SSukumar Swaminathan wptr[0], wptr[1]); 25316a573d82SSukumar Swaminathan 25326a573d82SSukumar Swaminathan (void) emlxs_delete_load_entry(hba, 25336a573d82SSukumar Swaminathan &OldWakeUpParms->sli1_prog_id); 25346a573d82SSukumar Swaminathan } 25356a573d82SSukumar Swaminathan 25366a573d82SSukumar Swaminathan if (bcmp(&OldWakeUpParms->sli2_prog_id, 25376a573d82SSukumar Swaminathan &NewWakeUpParms->sli2_prog_id, sizeof (PROG_ID))) { 25386a573d82SSukumar Swaminathan 25396a573d82SSukumar Swaminathan wptr = (uint32_t *)&OldWakeUpParms->sli2_prog_id; 25406a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 25416a573d82SSukumar Swaminathan "OLD: sli2_prog_id: 0x%08x 0x%08x Removing.", 25426a573d82SSukumar Swaminathan wptr[0], wptr[1]); 25436a573d82SSukumar Swaminathan 25446a573d82SSukumar Swaminathan (void) emlxs_delete_load_entry(hba, 25456a573d82SSukumar Swaminathan &OldWakeUpParms->sli2_prog_id); 25466a573d82SSukumar Swaminathan } 25476a573d82SSukumar Swaminathan 25486a573d82SSukumar Swaminathan if (bcmp(&OldWakeUpParms->sli3_prog_id, 25496a573d82SSukumar Swaminathan &NewWakeUpParms->sli3_prog_id, sizeof (PROG_ID))) { 25506a573d82SSukumar Swaminathan 25516a573d82SSukumar Swaminathan wptr = (uint32_t *)&OldWakeUpParms->sli3_prog_id; 25526a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 25536a573d82SSukumar Swaminathan "OLD: sli3_prog_id: 0x%08x 0x%08x Removing.", 25546a573d82SSukumar Swaminathan wptr[0], wptr[1]); 25556a573d82SSukumar Swaminathan 25566a573d82SSukumar Swaminathan (void) emlxs_delete_load_entry(hba, 25576a573d82SSukumar Swaminathan &OldWakeUpParms->sli3_prog_id); 25586a573d82SSukumar Swaminathan } 25596a573d82SSukumar Swaminathan 25606a573d82SSukumar Swaminathan if (bcmp(&OldWakeUpParms->sli4_prog_id, 25616a573d82SSukumar Swaminathan &NewWakeUpParms->sli4_prog_id, sizeof (PROG_ID))) { 25626a573d82SSukumar Swaminathan 25636a573d82SSukumar Swaminathan wptr = (uint32_t *)&OldWakeUpParms->sli4_prog_id; 25646a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 25656a573d82SSukumar Swaminathan "OLD: sli4_prog_id: 0x%08x 0x%08x Removing.", 25666a573d82SSukumar Swaminathan wptr[0], wptr[1]); 25676a573d82SSukumar Swaminathan 25686a573d82SSukumar Swaminathan (void) emlxs_delete_load_entry(hba, 25696a573d82SSukumar Swaminathan &OldWakeUpParms->sli4_prog_id); 25706a573d82SSukumar Swaminathan } 25716a573d82SSukumar Swaminathan 25726a573d82SSukumar Swaminathan return (0); 25736a573d82SSukumar Swaminathan } 25746a573d82SSukumar Swaminathan 25756a573d82SSukumar Swaminathan /* Otherwise use the current load list */ 25766a573d82SSukumar Swaminathan count = emlxs_get_load_list(hba, load_list); 25776a573d82SSukumar Swaminathan 25786a573d82SSukumar Swaminathan if (!count) { 25796a573d82SSukumar Swaminathan return (1); 25806a573d82SSukumar Swaminathan } 25816a573d82SSukumar Swaminathan 25826a573d82SSukumar Swaminathan /* Init the wakeup list */ 25836a573d82SSukumar Swaminathan wptr = (uint32_t *)&NewWakeUpParms->prog_id; 25846a573d82SSukumar Swaminathan if (*wptr) { 25856a573d82SSukumar Swaminathan wakeup_list[k++] = &NewWakeUpParms->prog_id; 25866a573d82SSukumar Swaminathan } 25876a573d82SSukumar Swaminathan 25886a573d82SSukumar Swaminathan wptr = (uint32_t *)&NewWakeUpParms->u0.boot_bios_id; 25896a573d82SSukumar Swaminathan if (*wptr) { 25906a573d82SSukumar Swaminathan wakeup_list[k++] = &NewWakeUpParms->u0.boot_bios_id; 25916a573d82SSukumar Swaminathan } 25926a573d82SSukumar Swaminathan 25936a573d82SSukumar Swaminathan wptr = (uint32_t *)&NewWakeUpParms->sli1_prog_id; 25946a573d82SSukumar Swaminathan if (*wptr) { 25956a573d82SSukumar Swaminathan wakeup_list[k++] = &NewWakeUpParms->sli1_prog_id; 25966a573d82SSukumar Swaminathan } 25976a573d82SSukumar Swaminathan 25986a573d82SSukumar Swaminathan wptr = (uint32_t *)&NewWakeUpParms->sli2_prog_id; 25996a573d82SSukumar Swaminathan if (*wptr) { 26006a573d82SSukumar Swaminathan wakeup_list[k++] = &NewWakeUpParms->sli2_prog_id; 26016a573d82SSukumar Swaminathan } 26026a573d82SSukumar Swaminathan 26036a573d82SSukumar Swaminathan wptr = (uint32_t *)&NewWakeUpParms->sli3_prog_id; 26046a573d82SSukumar Swaminathan if (*wptr) { 26056a573d82SSukumar Swaminathan wakeup_list[k++] = &NewWakeUpParms->sli3_prog_id; 26066a573d82SSukumar Swaminathan } 26076a573d82SSukumar Swaminathan 26086a573d82SSukumar Swaminathan wptr = (uint32_t *)&NewWakeUpParms->sli4_prog_id; 26096a573d82SSukumar Swaminathan if (*wptr) { 26106a573d82SSukumar Swaminathan wakeup_list[k++] = &NewWakeUpParms->sli4_prog_id; 26116a573d82SSukumar Swaminathan } 26126a573d82SSukumar Swaminathan 26136a573d82SSukumar Swaminathan if (k == 0) { 26146a573d82SSukumar Swaminathan return (0); 26156a573d82SSukumar Swaminathan } 26166a573d82SSukumar Swaminathan 26176a573d82SSukumar Swaminathan /* Match load list to wakeup list */ 26186a573d82SSukumar Swaminathan for (i = 0; i < count; i++) { 26196a573d82SSukumar Swaminathan 26206a573d82SSukumar Swaminathan wptr = (uint32_t *)&load_list[i]; 26216a573d82SSukumar Swaminathan 26226a573d82SSukumar Swaminathan for (j = 0; j < k; j++) { 26236a573d82SSukumar Swaminathan if (bcmp((uint8_t *)wakeup_list[j], 26246a573d82SSukumar Swaminathan (uint8_t *)&load_list[i], sizeof (PROG_ID)) == 0) { 26256a573d82SSukumar Swaminathan break; 26266a573d82SSukumar Swaminathan } 26276a573d82SSukumar Swaminathan } 26286a573d82SSukumar Swaminathan 26296a573d82SSukumar Swaminathan /* No match */ 26306a573d82SSukumar Swaminathan if (j == k) { 26316a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 26326a573d82SSukumar Swaminathan "Load List[%d]: %08x %08x Removing.", 26336a573d82SSukumar Swaminathan i, wptr[0], wptr[1]); 26346a573d82SSukumar Swaminathan 26356a573d82SSukumar Swaminathan (void) emlxs_delete_load_entry(hba, &load_list[i]); 26366a573d82SSukumar Swaminathan } else { 26376a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 26386a573d82SSukumar Swaminathan "Load List[%d]: %08x %08x Preserving.", 26396a573d82SSukumar Swaminathan i, wptr[0], wptr[1]); 26406a573d82SSukumar Swaminathan } 26416a573d82SSukumar Swaminathan } 26426a573d82SSukumar Swaminathan 26436a573d82SSukumar Swaminathan return (0); 26446a573d82SSukumar Swaminathan 26456a573d82SSukumar Swaminathan } /* emlxs_clean_flash() */ 26466a573d82SSukumar Swaminathan 26476a573d82SSukumar Swaminathan 2648fcf3ce44SJohn Forte /* ARGSUSED */ 2649fcf3ce44SJohn Forte static uint32_t 2650291a2b48SSukumar Swaminathan emlxs_start_rel_download(emlxs_hba_t *hba, 2651291a2b48SSukumar Swaminathan PIMAGE_HDR ImageHdr, 2652291a2b48SSukumar Swaminathan caddr_t Buffer, 2653291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, 26546a573d82SSukumar Swaminathan uint32_t dwc_flag) 2655fcf3ce44SJohn Forte { 2656fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2657fcf3ce44SJohn Forte MAILBOXQ *mbox; 2658fcf3ce44SJohn Forte MAILBOX *mb; 2659fcf3ce44SJohn Forte uint32_t *Src; 2660fcf3ce44SJohn Forte uint32_t *Dst; 2661fcf3ce44SJohn Forte caddr_t DataBuffer = NULL; 26626a573d82SSukumar Swaminathan uint32_t rval = 0; 26636a573d82SSukumar Swaminathan uint32_t DlByteCount; 2664fcf3ce44SJohn Forte uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT; 2665fcf3ce44SJohn Forte uint32_t DlCount; 2666fcf3ce44SJohn Forte uint32_t i; 26676a573d82SSukumar Swaminathan uint32_t *wptr; 2668fcf3ce44SJohn Forte 26696a573d82SSukumar Swaminathan wptr = (uint32_t *)&ImageHdr->Id; 26706a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 26716a573d82SSukumar Swaminathan "Relative download: %08x %08x", wptr[0], wptr[1]); 2672fcf3ce44SJohn Forte 2673291a2b48SSukumar Swaminathan if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT, 2674291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2675fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2676fcf3ce44SJohn Forte "Unable to allocate data buffer."); 2677fcf3ce44SJohn Forte 26786a573d82SSukumar Swaminathan return (1); 2679fcf3ce44SJohn Forte } 2680291a2b48SSukumar Swaminathan 2681291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2682291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2683fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2684fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 2685fcf3ce44SJohn Forte 2686fcf3ce44SJohn Forte kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 2687fcf3ce44SJohn Forte 26886a573d82SSukumar Swaminathan return (1); 2689fcf3ce44SJohn Forte } 2690291a2b48SSukumar Swaminathan 2691fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 2692fcf3ce44SJohn Forte 26936a573d82SSukumar Swaminathan DlByteCount = ImageHdr->BlockSize; 26946a573d82SSukumar Swaminathan 269582527734SSukumar Swaminathan emlxs_format_prog_flash(mbox, 0, DlByteCount, ERASE_FLASH, 0, 0, 0, 26966a573d82SSukumar Swaminathan &ImageHdr->Id, 0); 26976a573d82SSukumar Swaminathan 26986a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 26996a573d82SSukumar Swaminathan " Erasing flash..."); 2700fcf3ce44SJohn Forte 27016a573d82SSukumar Swaminathan rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0); 2702fcf3ce44SJohn Forte 27036a573d82SSukumar Swaminathan if (rval) { 2704fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2705fcf3ce44SJohn Forte "Unable to erase flash. Mailbox cmd=%x status=%x", 2706fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 2707fcf3ce44SJohn Forte 2708fcf3ce44SJohn Forte goto EXIT_REL_DOWNLOAD; 2709fcf3ce44SJohn Forte } 2710291a2b48SSukumar Swaminathan 27116a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 27126a573d82SSukumar Swaminathan " Programming flash..."); 2713fcf3ce44SJohn Forte 2714fcf3ce44SJohn Forte while (DlByteCount) { 2715fcf3ce44SJohn Forte if (DlByteCount > SegSize) { 2716fcf3ce44SJohn Forte DlCount = SegSize; 2717fcf3ce44SJohn Forte } else { 2718fcf3ce44SJohn Forte DlCount = DlByteCount; 2719fcf3ce44SJohn Forte } 2720fcf3ce44SJohn Forte DlByteCount -= DlCount; 2721fcf3ce44SJohn Forte 2722fcf3ce44SJohn Forte Dst = (uint32_t *)DataBuffer; 2723fcf3ce44SJohn Forte Src = (uint32_t *)Buffer; 2724fcf3ce44SJohn Forte 2725fcf3ce44SJohn Forte for (i = 0; i < (DlCount / 4); i++) { 2726fcf3ce44SJohn Forte *Dst = *Src; 2727fcf3ce44SJohn Forte Dst++; 2728fcf3ce44SJohn Forte Src++; 2729fcf3ce44SJohn Forte } 2730fcf3ce44SJohn Forte 2731fcf3ce44SJohn Forte WRITE_SLIM_COPY(hba, (uint32_t *)DataBuffer, 273282527734SSukumar Swaminathan (volatile uint32_t *) 273382527734SSukumar Swaminathan ((volatile char *)hba->sli.sli3.slim_addr + 2734291a2b48SSukumar Swaminathan sizeof (MAILBOX)), (DlCount / sizeof (uint32_t))); 2735fcf3ce44SJohn Forte 273682527734SSukumar Swaminathan emlxs_format_prog_flash(mbox, 2737291a2b48SSukumar Swaminathan 0, 2738291a2b48SSukumar Swaminathan DlCount, 2739291a2b48SSukumar Swaminathan PROGRAM_FLASH, 27406a573d82SSukumar Swaminathan (DlByteCount) ? 0 : 1, 27416a573d82SSukumar Swaminathan 0, DlCount, &ImageHdr->Id, dwc_flag); 2742fcf3ce44SJohn Forte 27436a573d82SSukumar Swaminathan rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0); 27446a573d82SSukumar Swaminathan 27456a573d82SSukumar Swaminathan if (rval) { 2746fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2747fcf3ce44SJohn Forte "Unable to program flash. Mailbox cmd=%x status=%x", 2748fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 2749fcf3ce44SJohn Forte 2750fcf3ce44SJohn Forte goto EXIT_REL_DOWNLOAD; 2751fcf3ce44SJohn Forte } 2752291a2b48SSukumar Swaminathan 2753fcf3ce44SJohn Forte Buffer += DlCount; 2754fcf3ce44SJohn Forte } 2755fcf3ce44SJohn Forte 27564baa2c25SSukumar Swaminathan #ifdef FMA_SUPPORT 275782527734SSukumar Swaminathan if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle) 27584baa2c25SSukumar Swaminathan != DDI_FM_OK) { 27594baa2c25SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 27604baa2c25SSukumar Swaminathan &emlxs_invalid_access_handle_msg, NULL); 27614baa2c25SSukumar Swaminathan 27624baa2c25SSukumar Swaminathan rval = 1; 27634baa2c25SSukumar Swaminathan 27644baa2c25SSukumar Swaminathan goto EXIT_REL_DOWNLOAD; 27654baa2c25SSukumar Swaminathan } 27664baa2c25SSukumar Swaminathan #endif /* FMA_SUPPORT */ 27674baa2c25SSukumar Swaminathan 27686a573d82SSukumar Swaminathan /* Update wakeup parameters */ 2769fcf3ce44SJohn Forte switch (ImageHdr->Id.Type) { 2770fcf3ce44SJohn Forte case TEST_PROGRAM: 2771fcf3ce44SJohn Forte break; 2772fcf3ce44SJohn Forte 2773fcf3ce44SJohn Forte case FUNC_FIRMWARE: 27746a573d82SSukumar Swaminathan if (!dwc_flag) { 27756a573d82SSukumar Swaminathan rval = emlxs_update_ff_wakeup_parms(hba, WakeUpParms, 27766a573d82SSukumar Swaminathan &ImageHdr->Id); 27776a573d82SSukumar Swaminathan } else { 27786a573d82SSukumar Swaminathan WakeUpParms->prog_id = ImageHdr->Id; 27796a573d82SSukumar Swaminathan } 2780fcf3ce44SJohn Forte break; 2781fcf3ce44SJohn Forte 2782fcf3ce44SJohn Forte case BOOT_BIOS: 27836a573d82SSukumar Swaminathan if (!dwc_flag) { 27846a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 27856a573d82SSukumar Swaminathan "BOOT: Updating parms..."); 27866a573d82SSukumar Swaminathan 27876a573d82SSukumar Swaminathan rval = emlxs_update_boot_wakeup_parms(hba, WakeUpParms, 27886a573d82SSukumar Swaminathan &ImageHdr->Id, 1); 27896a573d82SSukumar Swaminathan } else { 27906a573d82SSukumar Swaminathan if (hba->wakeup_parms.u0.boot_bios_wd[0]) { 27916a573d82SSukumar Swaminathan WakeUpParms->u0.boot_bios_id = ImageHdr->Id; 27926a573d82SSukumar Swaminathan } 27936a573d82SSukumar Swaminathan 27946a573d82SSukumar Swaminathan if (!(hba->model_info.chip & 27956a573d82SSukumar Swaminathan (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 27966a573d82SSukumar Swaminathan WakeUpParms->u1.EROM_prog_id = ImageHdr->Id; 27976a573d82SSukumar Swaminathan } 27986a573d82SSukumar Swaminathan } 2799fcf3ce44SJohn Forte break; 2800fcf3ce44SJohn Forte 2801fcf3ce44SJohn Forte case SLI1_OVERLAY: 28026a573d82SSukumar Swaminathan if (!dwc_flag) { 28036a573d82SSukumar Swaminathan rval = emlxs_update_sli1_wakeup_parms(hba, WakeUpParms, 28046a573d82SSukumar Swaminathan &ImageHdr->Id); 28056a573d82SSukumar Swaminathan } else { 28066a573d82SSukumar Swaminathan WakeUpParms->sli1_prog_id = ImageHdr->Id; 28076a573d82SSukumar Swaminathan } 2808fcf3ce44SJohn Forte break; 2809fcf3ce44SJohn Forte 2810fcf3ce44SJohn Forte case SLI2_OVERLAY: 28116a573d82SSukumar Swaminathan if (!dwc_flag) { 28126a573d82SSukumar Swaminathan rval = emlxs_update_sli2_wakeup_parms(hba, WakeUpParms, 28136a573d82SSukumar Swaminathan &ImageHdr->Id); 28146a573d82SSukumar Swaminathan } else { 28156a573d82SSukumar Swaminathan WakeUpParms->sli2_prog_id = ImageHdr->Id; 28166a573d82SSukumar Swaminathan } 2817fcf3ce44SJohn Forte break; 2818fcf3ce44SJohn Forte 2819fcf3ce44SJohn Forte case SLI3_OVERLAY: 28206a573d82SSukumar Swaminathan if (!dwc_flag) { 28216a573d82SSukumar Swaminathan rval = emlxs_update_sli3_wakeup_parms(hba, WakeUpParms, 28226a573d82SSukumar Swaminathan &ImageHdr->Id); 28236a573d82SSukumar Swaminathan } else { 28246a573d82SSukumar Swaminathan WakeUpParms->sli3_prog_id = ImageHdr->Id; 28256a573d82SSukumar Swaminathan } 2826fcf3ce44SJohn Forte break; 2827fcf3ce44SJohn Forte 2828fcf3ce44SJohn Forte case SLI4_OVERLAY: 28296a573d82SSukumar Swaminathan if (!dwc_flag) { 28306a573d82SSukumar Swaminathan rval = emlxs_update_sli4_wakeup_parms(hba, WakeUpParms, 28316a573d82SSukumar Swaminathan &ImageHdr->Id); 28326a573d82SSukumar Swaminathan } else { 28336a573d82SSukumar Swaminathan WakeUpParms->sli4_prog_id = ImageHdr->Id; 28346a573d82SSukumar Swaminathan } 2835fcf3ce44SJohn Forte break; 2836fcf3ce44SJohn Forte 2837fcf3ce44SJohn Forte default: 2838fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2839291a2b48SSukumar Swaminathan "Image type not supported. Type=%x", ImageHdr->Id.Type); 2840fcf3ce44SJohn Forte 2841fcf3ce44SJohn Forte break; 2842fcf3ce44SJohn Forte } 2843fcf3ce44SJohn Forte 2844fcf3ce44SJohn Forte EXIT_REL_DOWNLOAD: 2845fcf3ce44SJohn Forte if (DataBuffer) { 2846fcf3ce44SJohn Forte kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 2847fcf3ce44SJohn Forte } 2848291a2b48SSukumar Swaminathan 2849fcf3ce44SJohn Forte if (mbox) { 2850fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 2851fcf3ce44SJohn Forte } 2852291a2b48SSukumar Swaminathan 2853fcf3ce44SJohn Forte return (rval); 2854fcf3ce44SJohn Forte 285582527734SSukumar Swaminathan } /* emlxs_start_rel_download() */ 2856fcf3ce44SJohn Forte 2857fcf3ce44SJohn Forte 28586a573d82SSukumar Swaminathan static uint32_t 28596a573d82SSukumar Swaminathan emlxs_proc_rel_2mb(emlxs_hba_t *hba, caddr_t buffer, emlxs_fw_image_t *fw_image) 2860291a2b48SSukumar Swaminathan { 28616a573d82SSukumar Swaminathan emlxs_port_t *port = &PPORT; 28626a573d82SSukumar Swaminathan uint32_t rval = 0; 28636a573d82SSukumar Swaminathan WAKE_UP_PARMS RelWakeUpParms; 28646a573d82SSukumar Swaminathan WAKE_UP_PARMS WakeUpParms; 28656a573d82SSukumar Swaminathan uint32_t i; 28666a573d82SSukumar Swaminathan IMAGE_HDR ImageHdr; 28676a573d82SSukumar Swaminathan caddr_t bptr; 28686a573d82SSukumar Swaminathan uint32_t flash_cleaned = 0; 28696a573d82SSukumar Swaminathan 28706a573d82SSukumar Swaminathan if (emlxs_read_wakeup_parms(hba, &WakeUpParms, 0)) { 28716a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 28726a573d82SSukumar Swaminathan "Unable to get wakeup parameters."); 28736a573d82SSukumar Swaminathan 28746a573d82SSukumar Swaminathan return (EMLXS_IMAGE_FAILED); 28756a573d82SSukumar Swaminathan } 28766a573d82SSukumar Swaminathan 28776a573d82SSukumar Swaminathan download: 28786a573d82SSukumar Swaminathan 28796a573d82SSukumar Swaminathan bcopy(&WakeUpParms, &RelWakeUpParms, sizeof (WAKE_UP_PARMS)); 28806a573d82SSukumar Swaminathan 28816a573d82SSukumar Swaminathan for (i = 0; i < MAX_PROG_TYPES; i++) { 28826a573d82SSukumar Swaminathan if (!fw_image->prog[i].version) { 28836a573d82SSukumar Swaminathan continue; 28846a573d82SSukumar Swaminathan } 28856a573d82SSukumar Swaminathan 28866a573d82SSukumar Swaminathan bptr = buffer + fw_image->prog[i].offset; 28876a573d82SSukumar Swaminathan 28886a573d82SSukumar Swaminathan bcopy(bptr, &ImageHdr, sizeof (IMAGE_HDR)); 28896a573d82SSukumar Swaminathan 28906a573d82SSukumar Swaminathan rval = emlxs_start_rel_download(hba, &ImageHdr, bptr, 28916a573d82SSukumar Swaminathan &RelWakeUpParms, 1); 28926a573d82SSukumar Swaminathan 28936a573d82SSukumar Swaminathan if (rval) { 28946a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 28956a573d82SSukumar Swaminathan &emlxs_download_failed_msg, 28966a573d82SSukumar Swaminathan "Failed to program flash."); 28976a573d82SSukumar Swaminathan 28986a573d82SSukumar Swaminathan if ((rval == NO_FLASH_MEM_AVAIL) && !flash_cleaned) { 28996a573d82SSukumar Swaminathan /* Cleanup using current load list */ 29006a573d82SSukumar Swaminathan (void) emlxs_clean_flash(hba, 0, &WakeUpParms); 29016a573d82SSukumar Swaminathan 29026a573d82SSukumar Swaminathan flash_cleaned = 1; 29036a573d82SSukumar Swaminathan goto download; 29046a573d82SSukumar Swaminathan } 29056a573d82SSukumar Swaminathan 29066a573d82SSukumar Swaminathan return (EMLXS_IMAGE_FAILED); 29076a573d82SSukumar Swaminathan } 29086a573d82SSukumar Swaminathan } 29096a573d82SSukumar Swaminathan 29106a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 29116a573d82SSukumar Swaminathan "Updating wakeup parameters."); 29126a573d82SSukumar Swaminathan 29136a573d82SSukumar Swaminathan if (emlxs_update_wakeup_parms(hba, &RelWakeUpParms, 29146a573d82SSukumar Swaminathan &RelWakeUpParms)) { 29156a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 29166a573d82SSukumar Swaminathan "Unable to update parameters."); 29176a573d82SSukumar Swaminathan 29186a573d82SSukumar Swaminathan return (EMLXS_IMAGE_FAILED); 29196a573d82SSukumar Swaminathan } 29206a573d82SSukumar Swaminathan 2921*a9800bebSGarrett D'Amore /* Cleanup using old wakeup paramters */ 2922*a9800bebSGarrett D'Amore (void) emlxs_clean_flash(hba, &WakeUpParms, &RelWakeUpParms); 2923*a9800bebSGarrett D'Amore 29246a573d82SSukumar Swaminathan return (0); 29256a573d82SSukumar Swaminathan 29266a573d82SSukumar Swaminathan } /* emlxs_proc_rel_2mb() */ 29276a573d82SSukumar Swaminathan 29286a573d82SSukumar Swaminathan 29296a573d82SSukumar Swaminathan #define FLASH_POLLING_BIT 0x80 29306a573d82SSukumar Swaminathan #define FLASH_ERROR_BIT 0x20 29316a573d82SSukumar Swaminathan 29326a573d82SSukumar Swaminathan typedef struct _flash_t 29336a573d82SSukumar Swaminathan { 29346a573d82SSukumar Swaminathan uint32_t offset; 29356a573d82SSukumar Swaminathan uint8_t val; 29366a573d82SSukumar Swaminathan } flash_t; 29376a573d82SSukumar Swaminathan 29386a573d82SSukumar Swaminathan 2939fcf3ce44SJohn Forte 2940fcf3ce44SJohn Forte static uint32_t 2941291a2b48SSukumar Swaminathan emlxs_write_fcode_flash(emlxs_hba_t *hba, 2942291a2b48SSukumar Swaminathan PIMAGE_HDR ImageHdr, caddr_t Buffer) 2943fcf3ce44SJohn Forte { 2944fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2945fcf3ce44SJohn Forte uint8_t bb; 2946fcf3ce44SJohn Forte uint8_t cc; 2947fcf3ce44SJohn Forte uint8_t *src; 2948fcf3ce44SJohn Forte uint32_t DlByteCount = ImageHdr->BlockSize; 2949fcf3ce44SJohn Forte uint32_t i; 2950fcf3ce44SJohn Forte uint32_t j; 2951fcf3ce44SJohn Forte uint32_t k; 2952fcf3ce44SJohn Forte 2953291a2b48SSukumar Swaminathan flash_t wr[3] = { 2954fcf3ce44SJohn Forte {0x555, 0xaa}, 2955fcf3ce44SJohn Forte {0x2aa, 0x55}, 2956fcf3ce44SJohn Forte {0x555, 0xa0} 2957fcf3ce44SJohn Forte }; 2958fcf3ce44SJohn Forte 2959fcf3ce44SJohn Forte /* Load Fcode */ 2960fcf3ce44SJohn Forte src = (uint8_t *)Buffer + sizeof (IMAGE_HDR); 2961fcf3ce44SJohn Forte for (i = 0; i < DlByteCount; i++) { 2962fcf3ce44SJohn Forte for (k = 0; k < 3; k++) { 2963fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, wr[k].offset, wr[k].val); 2964fcf3ce44SJohn Forte } 2965fcf3ce44SJohn Forte 2966fcf3ce44SJohn Forte /* Reverse Endian word alignment */ 2967fcf3ce44SJohn Forte j = (i & 3) ^ 3; 2968fcf3ce44SJohn Forte 2969fcf3ce44SJohn Forte bb = src[j]; 2970fcf3ce44SJohn Forte 2971fcf3ce44SJohn Forte if (j == 0) { 2972fcf3ce44SJohn Forte src += 4; 2973fcf3ce44SJohn Forte } 2974291a2b48SSukumar Swaminathan 2975fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, i, bb); 2976fcf3ce44SJohn Forte 2977fcf3ce44SJohn Forte /* check for complete */ 2978fcf3ce44SJohn Forte for (;;) { 2979fcf3ce44SJohn Forte DELAYUS(20); 2980fcf3ce44SJohn Forte 2981fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, i); 2982fcf3ce44SJohn Forte 2983fcf3ce44SJohn Forte /* If data matches then continue */ 2984fcf3ce44SJohn Forte if (cc == bb) { 2985fcf3ce44SJohn Forte break; 2986fcf3ce44SJohn Forte } 2987291a2b48SSukumar Swaminathan 2988291a2b48SSukumar Swaminathan /* Polling bit will be inverse final value */ 2989291a2b48SSukumar Swaminathan /* while active */ 2990fcf3ce44SJohn Forte if ((cc ^ bb) & FLASH_POLLING_BIT) { 2991fcf3ce44SJohn Forte /* Still busy */ 2992fcf3ce44SJohn Forte 2993fcf3ce44SJohn Forte /* Check for error bit */ 2994fcf3ce44SJohn Forte if (cc & FLASH_ERROR_BIT) { 2995fcf3ce44SJohn Forte /* Read data one more time */ 2996fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, i); 2997fcf3ce44SJohn Forte 2998fcf3ce44SJohn Forte /* Check if data matches */ 2999fcf3ce44SJohn Forte if (cc == bb) { 3000fcf3ce44SJohn Forte break; 3001fcf3ce44SJohn Forte } 3002291a2b48SSukumar Swaminathan 3003fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3004fcf3ce44SJohn Forte &emlxs_download_failed_msg, 3005fcf3ce44SJohn Forte "FCode write error: offset:%x " 3006291a2b48SSukumar Swaminathan "wrote:%x read:%x\n", i, bb, cc); 3007fcf3ce44SJohn Forte 3008fcf3ce44SJohn Forte return (1); 3009fcf3ce44SJohn Forte } 3010fcf3ce44SJohn Forte } 3011fcf3ce44SJohn Forte } 3012fcf3ce44SJohn Forte } 3013fcf3ce44SJohn Forte 3014fcf3ce44SJohn Forte /* Load Header */ 3015fcf3ce44SJohn Forte src = (uint8_t *)ImageHdr; 3016fcf3ce44SJohn Forte 3017fcf3ce44SJohn Forte for (i = (0xFFFF - sizeof (IMAGE_HDR)); i < 0xFFFF; i++) { 3018fcf3ce44SJohn Forte for (k = 0; k < 3; k++) { 3019fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, wr[k].offset, wr[k].val); 3020fcf3ce44SJohn Forte } 3021fcf3ce44SJohn Forte 3022fcf3ce44SJohn Forte /* Reverse Endian word alignment */ 3023fcf3ce44SJohn Forte j = (i & 3) ^ 3; 3024fcf3ce44SJohn Forte 3025fcf3ce44SJohn Forte bb = src[j]; 3026fcf3ce44SJohn Forte 3027fcf3ce44SJohn Forte if (j == 0) { 3028fcf3ce44SJohn Forte src += 4; 3029fcf3ce44SJohn Forte } 3030291a2b48SSukumar Swaminathan 3031fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, i, bb); 3032fcf3ce44SJohn Forte 3033fcf3ce44SJohn Forte /* check for complete */ 3034fcf3ce44SJohn Forte for (;;) { 3035fcf3ce44SJohn Forte DELAYUS(20); 3036fcf3ce44SJohn Forte 3037fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, i); 3038fcf3ce44SJohn Forte 3039fcf3ce44SJohn Forte /* If data matches then continue */ 3040fcf3ce44SJohn Forte if (cc == bb) { 3041fcf3ce44SJohn Forte break; 3042fcf3ce44SJohn Forte } 3043291a2b48SSukumar Swaminathan 3044291a2b48SSukumar Swaminathan /* Polling bit will be inverse final value */ 3045291a2b48SSukumar Swaminathan /* while active */ 3046fcf3ce44SJohn Forte if ((cc ^ bb) & FLASH_POLLING_BIT) { 3047fcf3ce44SJohn Forte /* Still busy */ 3048fcf3ce44SJohn Forte 3049fcf3ce44SJohn Forte /* Check for error bit */ 3050fcf3ce44SJohn Forte if (cc & FLASH_ERROR_BIT) { 3051fcf3ce44SJohn Forte /* Read data one more time */ 3052fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, i); 3053fcf3ce44SJohn Forte 3054fcf3ce44SJohn Forte /* Check if data matches */ 3055fcf3ce44SJohn Forte if (cc == bb) { 3056fcf3ce44SJohn Forte break; 3057fcf3ce44SJohn Forte } 3058291a2b48SSukumar Swaminathan 3059fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3060fcf3ce44SJohn Forte &emlxs_download_failed_msg, 3061fcf3ce44SJohn Forte "FCode write error: offset:%x " 3062291a2b48SSukumar Swaminathan "wrote:%x read:%x\n", i, bb, cc); 3063fcf3ce44SJohn Forte 3064fcf3ce44SJohn Forte return (1); 3065fcf3ce44SJohn Forte } 3066fcf3ce44SJohn Forte } 3067fcf3ce44SJohn Forte } 3068fcf3ce44SJohn Forte } 3069fcf3ce44SJohn Forte 30704baa2c25SSukumar Swaminathan #ifdef FMA_SUPPORT 307182527734SSukumar Swaminathan if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.sbus_flash_acc_handle) 30724baa2c25SSukumar Swaminathan != DDI_FM_OK) { 30734baa2c25SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 30744baa2c25SSukumar Swaminathan &emlxs_invalid_access_handle_msg, NULL); 30754baa2c25SSukumar Swaminathan return (1); 30764baa2c25SSukumar Swaminathan } 30774baa2c25SSukumar Swaminathan #endif /* FMA_SUPPORT */ 3078291a2b48SSukumar Swaminathan 3079fcf3ce44SJohn Forte return (0); 3080fcf3ce44SJohn Forte 308182527734SSukumar Swaminathan } /* emlxs_write_fcode_flash() */ 3082fcf3ce44SJohn Forte 3083fcf3ce44SJohn Forte 3084fcf3ce44SJohn Forte 3085fcf3ce44SJohn Forte static uint32_t 3086fcf3ce44SJohn Forte emlxs_erase_fcode_flash(emlxs_hba_t *hba) 3087fcf3ce44SJohn Forte { 3088fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3089fcf3ce44SJohn Forte int32_t i, j; 3090fcf3ce44SJohn Forte uint8_t cc; 3091fcf3ce44SJohn Forte uint32_t offset; 3092fcf3ce44SJohn Forte 3093291a2b48SSukumar Swaminathan flash_t ef[6] = { 3094fcf3ce44SJohn Forte {0x555, 0xaa}, 3095fcf3ce44SJohn Forte {0x2aa, 0x55}, 3096fcf3ce44SJohn Forte {0x555, 0x80}, 3097fcf3ce44SJohn Forte {0x555, 0xaa}, 3098fcf3ce44SJohn Forte {0x2aa, 0x55}, 3099fcf3ce44SJohn Forte {0x555, 0x10} 3100fcf3ce44SJohn Forte }; 3101fcf3ce44SJohn Forte 3102fcf3ce44SJohn Forte /* Auto select */ 3103291a2b48SSukumar Swaminathan flash_t as[3] = { 3104fcf3ce44SJohn Forte {0x555, 0xaa}, 3105fcf3ce44SJohn Forte {0x2aa, 0x55}, 3106fcf3ce44SJohn Forte {0x555, 0x90} 3107fcf3ce44SJohn Forte }; 3108fcf3ce44SJohn Forte 3109fcf3ce44SJohn Forte 3110fcf3ce44SJohn Forte /* Check Manufacturers Code */ 3111fcf3ce44SJohn Forte for (i = 0; i < 3; i++) { 3112fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, as[i].offset, as[i].val); 3113fcf3ce44SJohn Forte } 3114fcf3ce44SJohn Forte 3115fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, 0); 3116fcf3ce44SJohn Forte 3117fcf3ce44SJohn Forte /* Check Device Code */ 3118fcf3ce44SJohn Forte for (i = 0; i < 3; i++) { 3119fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, as[i].offset, as[i].val); 3120fcf3ce44SJohn Forte } 3121fcf3ce44SJohn Forte 3122fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, 1); 3123fcf3ce44SJohn Forte 3124fcf3ce44SJohn Forte 3125fcf3ce44SJohn Forte /* Check block protections (up to 4 16K blocks = 64K) */ 3126fcf3ce44SJohn Forte for (j = 0; j < 4; j++) { 3127fcf3ce44SJohn Forte for (i = 0; i < 3; i++) { 3128fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, as[i].offset, as[i].val); 3129fcf3ce44SJohn Forte } 3130fcf3ce44SJohn Forte 3131fcf3ce44SJohn Forte offset = (j << 14) | 0x2; 3132fcf3ce44SJohn Forte 3133fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, offset); 3134fcf3ce44SJohn Forte 3135fcf3ce44SJohn Forte if (cc == 0x01) { 3136fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3137fcf3ce44SJohn Forte "Block %d is protected and can't be erased.", j); 3138fcf3ce44SJohn Forte } 3139fcf3ce44SJohn Forte } 3140fcf3ce44SJohn Forte 3141fcf3ce44SJohn Forte /* Write erase flash sequence */ 3142fcf3ce44SJohn Forte for (i = 0; i < 6; i++) { 3143fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, ef[i].offset, ef[i].val); 3144fcf3ce44SJohn Forte } 3145fcf3ce44SJohn Forte 3146fcf3ce44SJohn Forte /* check for complete */ 3147fcf3ce44SJohn Forte for (;;) { 3148fcf3ce44SJohn Forte /* Delay 3 seconds */ 3149fcf3ce44SJohn Forte DELAYMS(3000); 3150fcf3ce44SJohn Forte 3151fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, 0); 3152fcf3ce44SJohn Forte 3153fcf3ce44SJohn Forte 3154fcf3ce44SJohn Forte /* If data matches then continue; */ 3155fcf3ce44SJohn Forte if (cc == 0xff) { 3156fcf3ce44SJohn Forte break; 3157fcf3ce44SJohn Forte } 3158291a2b48SSukumar Swaminathan 3159fcf3ce44SJohn Forte /* Polling bit will be inverse final value while active */ 3160fcf3ce44SJohn Forte if ((cc ^ 0xff) & FLASH_POLLING_BIT) { 3161fcf3ce44SJohn Forte /* Still busy */ 3162fcf3ce44SJohn Forte 3163fcf3ce44SJohn Forte /* Check for error bit */ 3164fcf3ce44SJohn Forte if (cc & FLASH_ERROR_BIT) { 3165fcf3ce44SJohn Forte /* Read data one more time */ 3166fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, 0); 3167fcf3ce44SJohn Forte 3168fcf3ce44SJohn Forte /* Check if data matches */ 3169fcf3ce44SJohn Forte if (cc == 0xff) { 3170fcf3ce44SJohn Forte break; 3171fcf3ce44SJohn Forte } 3172291a2b48SSukumar Swaminathan 3173fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3174fcf3ce44SJohn Forte &emlxs_download_failed_msg, 3175291a2b48SSukumar Swaminathan "FCode write error: offset:%x wrote:%x " 3176291a2b48SSukumar Swaminathan "read:%x\n", i, 0xff, cc); 3177fcf3ce44SJohn Forte 3178fcf3ce44SJohn Forte return (1); 3179fcf3ce44SJohn Forte } 3180fcf3ce44SJohn Forte } 3181fcf3ce44SJohn Forte } 3182fcf3ce44SJohn Forte 31834baa2c25SSukumar Swaminathan #ifdef FMA_SUPPORT 318482527734SSukumar Swaminathan if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.sbus_flash_acc_handle) 31854baa2c25SSukumar Swaminathan != DDI_FM_OK) { 31864baa2c25SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 31874baa2c25SSukumar Swaminathan &emlxs_invalid_access_handle_msg, NULL); 31884baa2c25SSukumar Swaminathan return (1); 31894baa2c25SSukumar Swaminathan } 31904baa2c25SSukumar Swaminathan #endif /* FMA_SUPPORT */ 31914baa2c25SSukumar Swaminathan 3192fcf3ce44SJohn Forte return (0); 3193fcf3ce44SJohn Forte 319482527734SSukumar Swaminathan } /* emlxs_erase_fcode_flash() */ 3195fcf3ce44SJohn Forte 3196fcf3ce44SJohn Forte 31976a573d82SSukumar Swaminathan static uint32_t 31986a573d82SSukumar Swaminathan emlxs_delete_load_entry(emlxs_hba_t *hba, PROG_ID *progId) 31996a573d82SSukumar Swaminathan { 32006a573d82SSukumar Swaminathan emlxs_port_t *port = &PPORT; 32016a573d82SSukumar Swaminathan MAILBOXQ *mbox = NULL; 32026a573d82SSukumar Swaminathan MAILBOX *mb; 32036a573d82SSukumar Swaminathan uint32_t rval = 0; 32046a573d82SSukumar Swaminathan 32056a573d82SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 32066a573d82SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 32076a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 32086a573d82SSukumar Swaminathan "Unable to allocate mailbox buffer."); 32096a573d82SSukumar Swaminathan 32106a573d82SSukumar Swaminathan return (1); 32116a573d82SSukumar Swaminathan } 32126a573d82SSukumar Swaminathan 32136a573d82SSukumar Swaminathan mb = (MAILBOX *)mbox; 32146a573d82SSukumar Swaminathan mb->mbxCommand = MBX_DEL_LD_ENTRY; 32156a573d82SSukumar Swaminathan mb->un.varDelLdEntry.list_req = FLASH_LOAD_LIST; 32166a573d82SSukumar Swaminathan mb->un.varDelLdEntry.prog_id = *progId; 32176a573d82SSukumar Swaminathan 32186a573d82SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 32196a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 32206a573d82SSukumar Swaminathan "Unable to delete load entry: Mailbox cmd=%x status=%x", 32216a573d82SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 32226a573d82SSukumar Swaminathan 32236a573d82SSukumar Swaminathan rval = 1; 32246a573d82SSukumar Swaminathan } 32256a573d82SSukumar Swaminathan 32266a573d82SSukumar Swaminathan done: 32276a573d82SSukumar Swaminathan 32286a573d82SSukumar Swaminathan if (mbox) { 32296a573d82SSukumar Swaminathan kmem_free(mbox, sizeof (MAILBOXQ)); 32306a573d82SSukumar Swaminathan } 32316a573d82SSukumar Swaminathan 32326a573d82SSukumar Swaminathan return (rval); 32336a573d82SSukumar Swaminathan 32346a573d82SSukumar Swaminathan } /* emlxs_delete_load_entry() */ 32356a573d82SSukumar Swaminathan 32366a573d82SSukumar Swaminathan 3237fcf3ce44SJohn Forte extern uint32_t 3238fcf3ce44SJohn Forte emlxs_get_load_list(emlxs_hba_t *hba, PROG_ID *load_list) 3239fcf3ce44SJohn Forte { 3240fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3241fcf3ce44SJohn Forte LOAD_ENTRY *LoadEntry; 3242fcf3ce44SJohn Forte LOAD_LIST *LoadList = NULL; 3243fcf3ce44SJohn Forte uint32_t i; 32446a573d82SSukumar Swaminathan uint32_t count = 0; 3245fcf3ce44SJohn Forte 3246fcf3ce44SJohn Forte bzero(load_list, (sizeof (PROG_ID) * MAX_LOAD_ENTRY)); 3247fcf3ce44SJohn Forte 3248291a2b48SSukumar Swaminathan if ((LoadList = (LOAD_LIST *)kmem_zalloc(sizeof (LOAD_LIST), 3249291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 3250fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3251fcf3ce44SJohn Forte "Unable to allocate LOADLIST buffer."); 3252fcf3ce44SJohn Forte 3253fcf3ce44SJohn Forte goto done; 3254fcf3ce44SJohn Forte } 3255291a2b48SSukumar Swaminathan 3256fcf3ce44SJohn Forte if (emlxs_read_load_list(hba, LoadList)) { 3257fcf3ce44SJohn Forte goto done; 3258fcf3ce44SJohn Forte } 3259291a2b48SSukumar Swaminathan 3260fcf3ce44SJohn Forte for (i = 0; i < LoadList->entry_cnt; i++) { 3261fcf3ce44SJohn Forte LoadEntry = &LoadList->load_entry[i]; 3262fcf3ce44SJohn Forte if ((LoadEntry->un.wd[0] != 0) && 3263fcf3ce44SJohn Forte (LoadEntry->un.wd[0] != 0xffffffff)) { 3264fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 32656a573d82SSukumar Swaminathan "Load List[%d]: %08x %08x", count, 3266291a2b48SSukumar Swaminathan LoadEntry->un.wd[0], LoadEntry->un.wd[1]); 32676a573d82SSukumar Swaminathan 32686a573d82SSukumar Swaminathan load_list[count++] = LoadEntry->un.id; 3269fcf3ce44SJohn Forte } 3270fcf3ce44SJohn Forte } 3271fcf3ce44SJohn Forte 3272fcf3ce44SJohn Forte done: 3273fcf3ce44SJohn Forte 3274fcf3ce44SJohn Forte if (LoadList) { 3275fcf3ce44SJohn Forte kmem_free(LoadList, sizeof (LOAD_LIST)); 3276fcf3ce44SJohn Forte } 3277291a2b48SSukumar Swaminathan 32786a573d82SSukumar Swaminathan return (count); 3279fcf3ce44SJohn Forte 328082527734SSukumar Swaminathan } /* emlxs_get_load_list() */ 3281fcf3ce44SJohn Forte 3282fcf3ce44SJohn Forte 3283fcf3ce44SJohn Forte extern uint32_t 3284fcf3ce44SJohn Forte emlxs_read_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 3285fcf3ce44SJohn Forte uint32_t verbose) 3286fcf3ce44SJohn Forte { 3287fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3288fcf3ce44SJohn Forte MAILBOXQ *mbox; 3289fcf3ce44SJohn Forte MAILBOX *mb; 3290fcf3ce44SJohn Forte uint32_t rval = 0; 3291fcf3ce44SJohn Forte uint32_t *wd; 3292fcf3ce44SJohn Forte 3293fcf3ce44SJohn Forte bzero(WakeUpParms, sizeof (WAKE_UP_PARMS)); 3294fcf3ce44SJohn Forte 3295291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 3296291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 3297fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3298fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 3299fcf3ce44SJohn Forte 3300fcf3ce44SJohn Forte return (1); 3301fcf3ce44SJohn Forte } 3302291a2b48SSukumar Swaminathan 3303fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 3304fcf3ce44SJohn Forte 330582527734SSukumar Swaminathan emlxs_format_dump(hba, mbox, 3306291a2b48SSukumar Swaminathan DMP_NV_PARAMS, 3307291a2b48SSukumar Swaminathan WAKE_UP_PARMS_REGION_ID, 3308fcf3ce44SJohn Forte sizeof (WAKE_UP_PARMS) / sizeof (uint32_t), 0); 3309fcf3ce44SJohn Forte 331082527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 3311fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3312fcf3ce44SJohn Forte "Unable to get parameters: Mailbox cmd=%x status=%x", 3313fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 3314fcf3ce44SJohn Forte 3315fcf3ce44SJohn Forte if (mb->un.varDmp.word_cnt == (uint32_t)CFG_DATA_NO_REGION) { 3316fcf3ce44SJohn Forte rval = (uint32_t)CFG_DATA_NO_REGION; 3317fcf3ce44SJohn Forte } else { 3318fcf3ce44SJohn Forte rval = 1; 3319fcf3ce44SJohn Forte } 3320fcf3ce44SJohn Forte } else { 332182527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 332282527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle, 332382527734SSukumar Swaminathan 0, hba->sli.sli4.dump_region.size, 332482527734SSukumar Swaminathan DDI_DMA_SYNC_FORKERNEL); 332582527734SSukumar Swaminathan 332682527734SSukumar Swaminathan bcopy((caddr_t)hba->sli.sli4.dump_region.virt, 332782527734SSukumar Swaminathan (caddr_t)WakeUpParms, sizeof (WAKE_UP_PARMS)); 332882527734SSukumar Swaminathan } else { 332982527734SSukumar Swaminathan bcopy((caddr_t)&mb->un.varDmp.resp_offset, 333082527734SSukumar Swaminathan (caddr_t)WakeUpParms, sizeof (WAKE_UP_PARMS)); 333182527734SSukumar Swaminathan } 3332fcf3ce44SJohn Forte 3333fcf3ce44SJohn Forte if (verbose) { 3334fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->prog_id; 3335fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3336291a2b48SSukumar Swaminathan "Wakeup: prog_id=%08x %08x", wd[0], wd[1]); 3337fcf3ce44SJohn Forte 3338fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->u0.boot_bios_id; 3339fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3340291a2b48SSukumar Swaminathan "Wakeup: boot_bios_id=%08x %08x", wd[0], wd[1]); 3341fcf3ce44SJohn Forte 3342fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->sli1_prog_id; 3343fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3344291a2b48SSukumar Swaminathan "Wakeup: sli1_prog_id=%08x %08x", wd[0], wd[1]); 3345fcf3ce44SJohn Forte 3346fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->sli2_prog_id; 3347fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3348291a2b48SSukumar Swaminathan "Wakeup: sli2_prog_id=%08x %08x", wd[0], wd[1]); 3349fcf3ce44SJohn Forte 3350fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->sli3_prog_id; 3351fcf3ce44SJohn Forte if (wd[0] || wd[1]) { 3352291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 3353291a2b48SSukumar Swaminathan &emlxs_init_debug_msg, 3354291a2b48SSukumar Swaminathan "Wakeup: sli3_prog_id=%08x %08x", wd[0], 3355291a2b48SSukumar Swaminathan wd[1]); 3356fcf3ce44SJohn Forte } 3357291a2b48SSukumar Swaminathan 3358fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->sli4_prog_id; 3359fcf3ce44SJohn Forte if (wd[0] || wd[1]) { 3360291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 3361291a2b48SSukumar Swaminathan &emlxs_init_debug_msg, 3362291a2b48SSukumar Swaminathan "Wakeup: sli4_prog_id=%08x %08x", wd[0], 3363291a2b48SSukumar Swaminathan wd[1]); 3364fcf3ce44SJohn Forte } 3365291a2b48SSukumar Swaminathan 3366fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->u1.EROM_prog_id; 3367fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3368291a2b48SSukumar Swaminathan "Wakeup: EROM_prog_id=%08x %08x", wd[0], wd[1]); 3369fcf3ce44SJohn Forte 3370fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3371fcf3ce44SJohn Forte "Wakeup: pci_cfg_rsvd=%x", 3372fcf3ce44SJohn Forte WakeUpParms->pci_cfg_rsvd); 3373fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3374fcf3ce44SJohn Forte "Wakeup: use_hdw_def=%x", 3375fcf3ce44SJohn Forte WakeUpParms->use_hdw_def); 3376fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3377fcf3ce44SJohn Forte "Wakeup: pci_cfg_sel=%x", 3378fcf3ce44SJohn Forte WakeUpParms->pci_cfg_sel); 3379fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3380fcf3ce44SJohn Forte "Wakeup: cfg_lookup=%x", 3381fcf3ce44SJohn Forte WakeUpParms->pci_cfg_lookup_sel); 3382fcf3ce44SJohn Forte } 3383fcf3ce44SJohn Forte } 3384fcf3ce44SJohn Forte 3385fcf3ce44SJohn Forte done: 3386fcf3ce44SJohn Forte 3387fcf3ce44SJohn Forte if (mbox) { 3388fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 3389fcf3ce44SJohn Forte } 3390291a2b48SSukumar Swaminathan 3391b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 3392b3660a96SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 3393b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, 3394b3660a96SSukumar Swaminathan hba->sli.sli4.dump_region.dma_handle) != DDI_FM_OK) { 3395b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 3396b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 3397b3660a96SSukumar Swaminathan "emlxs_read_wakeup_parms: hdl=%p", 3398b3660a96SSukumar Swaminathan hba->sli.sli4.dump_region.dma_handle); 3399b3660a96SSukumar Swaminathan rval = 1; 3400b3660a96SSukumar Swaminathan } 3401b3660a96SSukumar Swaminathan } 3402b3660a96SSukumar Swaminathan #endif /* FMA_SUPPORT */ 3403b3660a96SSukumar Swaminathan 3404fcf3ce44SJohn Forte return (rval); 3405fcf3ce44SJohn Forte 340682527734SSukumar Swaminathan } /* emlxs_read_wakeup_parms() */ 3407fcf3ce44SJohn Forte 3408fcf3ce44SJohn Forte 3409fcf3ce44SJohn Forte static uint32_t 3410291a2b48SSukumar Swaminathan emlxs_read_load_list(emlxs_hba_t *hba, LOAD_LIST *LoadList) 3411fcf3ce44SJohn Forte { 3412fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3413fcf3ce44SJohn Forte LOAD_ENTRY *LoadEntry; 3414fcf3ce44SJohn Forte uint32_t *Uptr; 3415fcf3ce44SJohn Forte uint32_t CurEntryAddr; 3416fcf3ce44SJohn Forte MAILBOXQ *mbox = NULL; 3417fcf3ce44SJohn Forte MAILBOX *mb; 3418fcf3ce44SJohn Forte 3419fcf3ce44SJohn Forte bzero((caddr_t)LoadList, sizeof (LOAD_LIST)); 3420fcf3ce44SJohn Forte 3421291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 3422291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 3423fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3424fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 3425fcf3ce44SJohn Forte 3426fcf3ce44SJohn Forte return (1); 3427fcf3ce44SJohn Forte } 3428291a2b48SSukumar Swaminathan 3429fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 3430fcf3ce44SJohn Forte 343182527734SSukumar Swaminathan emlxs_format_dump(hba, mbox, DMP_MEM_REG, 0, 2, FLASH_LOAD_LIST_ADR); 3432fcf3ce44SJohn Forte 343382527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 3434fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3435fcf3ce44SJohn Forte "Unable to get load list: Mailbox cmd=%x status=%x", 3436fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 3437fcf3ce44SJohn Forte 3438fcf3ce44SJohn Forte goto done; 3439fcf3ce44SJohn Forte } 3440291a2b48SSukumar Swaminathan 344182527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 344282527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle, 0, 344382527734SSukumar Swaminathan hba->sli.sli4.dump_region.size, DDI_DMA_SYNC_FORKERNEL); 344482527734SSukumar Swaminathan Uptr = (uint32_t *)hba->sli.sli4.dump_region.virt; 344582527734SSukumar Swaminathan } else { 344682527734SSukumar Swaminathan Uptr = (uint32_t *)&mb->un.varDmp.resp_offset; 344782527734SSukumar Swaminathan } 3448fcf3ce44SJohn Forte 3449fcf3ce44SJohn Forte LoadList->head = Uptr[0]; 3450fcf3ce44SJohn Forte LoadList->tail = Uptr[1]; 3451fcf3ce44SJohn Forte 3452fcf3ce44SJohn Forte CurEntryAddr = LoadList->head; 3453fcf3ce44SJohn Forte 3454fcf3ce44SJohn Forte while ((CurEntryAddr != FLASH_LOAD_LIST_ADR) && 3455fcf3ce44SJohn Forte (LoadList->entry_cnt < MAX_LOAD_ENTRY)) { 3456fcf3ce44SJohn Forte LoadEntry = &LoadList->load_entry[LoadList->entry_cnt]; 3457fcf3ce44SJohn Forte LoadList->entry_cnt++; 3458fcf3ce44SJohn Forte 345982527734SSukumar Swaminathan emlxs_format_dump(hba, mbox, 3460291a2b48SSukumar Swaminathan DMP_MEM_REG, 0, FLASH_LOAD_ENTRY_SIZE, CurEntryAddr); 3461fcf3ce44SJohn Forte 346282527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 3463291a2b48SSukumar Swaminathan MBX_SUCCESS) { 3464fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3465291a2b48SSukumar Swaminathan "Unable to get load list (%d): Mailbox cmd=%x " 3466291a2b48SSukumar Swaminathan "status=%x", LoadList->entry_cnt, mb->mbxCommand, 3467291a2b48SSukumar Swaminathan mb->mbxStatus); 3468fcf3ce44SJohn Forte 3469fcf3ce44SJohn Forte goto done; 3470fcf3ce44SJohn Forte } 3471291a2b48SSukumar Swaminathan 347282527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 347382527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle, 347482527734SSukumar Swaminathan 0, hba->sli.sli4.dump_region.size, 347582527734SSukumar Swaminathan DDI_DMA_SYNC_FORKERNEL); 347682527734SSukumar Swaminathan Uptr = (uint32_t *)hba->sli.sli4.dump_region.virt; 347782527734SSukumar Swaminathan } else { 347882527734SSukumar Swaminathan Uptr = (uint32_t *)&mb->un.varDmp.resp_offset; 347982527734SSukumar Swaminathan } 3480fcf3ce44SJohn Forte 3481fcf3ce44SJohn Forte LoadEntry->next = Uptr[0]; 3482fcf3ce44SJohn Forte LoadEntry->prev = Uptr[1]; 3483fcf3ce44SJohn Forte LoadEntry->start_adr = Uptr[2]; 3484fcf3ce44SJohn Forte LoadEntry->len = Uptr[3]; 3485fcf3ce44SJohn Forte LoadEntry->un.wd[0] = Uptr[4]; 3486fcf3ce44SJohn Forte LoadEntry->un.wd[1] = Uptr[5]; 3487fcf3ce44SJohn Forte 3488fcf3ce44SJohn Forte /* update next current load entry address */ 3489fcf3ce44SJohn Forte CurEntryAddr = LoadEntry->next; 3490fcf3ce44SJohn Forte 3491fcf3ce44SJohn Forte } /* end of while (not end of list) */ 3492fcf3ce44SJohn Forte 3493fcf3ce44SJohn Forte done: 3494fcf3ce44SJohn Forte 3495fcf3ce44SJohn Forte if (mbox) { 3496fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 3497fcf3ce44SJohn Forte } 3498291a2b48SSukumar Swaminathan 3499b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 3500b3660a96SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 3501b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, 3502b3660a96SSukumar Swaminathan hba->sli.sli4.dump_region.dma_handle) != DDI_FM_OK) { 3503b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 3504b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 3505b3660a96SSukumar Swaminathan "emlxs_read_load_list: hdl=%p", 3506b3660a96SSukumar Swaminathan hba->sli.sli4.dump_region.dma_handle); 3507b3660a96SSukumar Swaminathan return (1); 3508b3660a96SSukumar Swaminathan } 3509b3660a96SSukumar Swaminathan } 3510b3660a96SSukumar Swaminathan #endif /* FMA_SUPPORT */ 3511b3660a96SSukumar Swaminathan 3512fcf3ce44SJohn Forte return (0); 3513fcf3ce44SJohn Forte 351482527734SSukumar Swaminathan } /* emlxs_read_load_list() */ 3515fcf3ce44SJohn Forte 3516fcf3ce44SJohn Forte 3517fcf3ce44SJohn Forte 3518*a9800bebSGarrett D'Amore 3519fcf3ce44SJohn Forte static int 3520291a2b48SSukumar Swaminathan emlxs_build_parms(caddr_t Buffer, 3521291a2b48SSukumar Swaminathan PWAKE_UP_PARMS AbsWakeUpParms, 35226a573d82SSukumar Swaminathan uint32_t BufferSize, PAIF_HDR AifHeader) 3523fcf3ce44SJohn Forte { 3524fcf3ce44SJohn Forte IMAGE_HDR ImageHdr; 3525fcf3ce44SJohn Forte uint32_t NextImage; 3526fcf3ce44SJohn Forte uint32_t i; 3527fcf3ce44SJohn Forte int32_t ChangeParams = FALSE; 3528fcf3ce44SJohn Forte caddr_t Sptr; 3529fcf3ce44SJohn Forte caddr_t Dptr; 3530fcf3ce44SJohn Forte 3531fcf3ce44SJohn Forte bzero((caddr_t)AbsWakeUpParms, sizeof (WAKE_UP_PARMS)); 3532fcf3ce44SJohn Forte 35336a573d82SSukumar Swaminathan if ((AifHeader->ImageBase != 0x20000) && 35346a573d82SSukumar Swaminathan ((AifHeader->RoSize + AifHeader->RwSize) <= 0x20000)) { 3535fcf3ce44SJohn Forte return (FALSE); 3536fcf3ce44SJohn Forte } 3537291a2b48SSukumar Swaminathan 3538fcf3ce44SJohn Forte NextImage = SLI_IMAGE_START - AifHeader->ImageBase; 3539fcf3ce44SJohn Forte 3540fcf3ce44SJohn Forte while (BufferSize > NextImage) { 3541fcf3ce44SJohn Forte Sptr = &Buffer[NextImage]; 3542fcf3ce44SJohn Forte Dptr = (caddr_t)&ImageHdr; 3543fcf3ce44SJohn Forte for (i = 0; i < sizeof (IMAGE_HDR); i++) { 3544fcf3ce44SJohn Forte Dptr[i] = Sptr[i]; 3545fcf3ce44SJohn Forte } 3546fcf3ce44SJohn Forte 3547fcf3ce44SJohn Forte if (ImageHdr.BlockSize == 0xffffffff) 3548fcf3ce44SJohn Forte break; 3549fcf3ce44SJohn Forte 3550fcf3ce44SJohn Forte switch (ImageHdr.Id.Type) { 3551fcf3ce44SJohn Forte case TEST_PROGRAM: 3552fcf3ce44SJohn Forte break; 3553fcf3ce44SJohn Forte case FUNC_FIRMWARE: 3554fcf3ce44SJohn Forte AbsWakeUpParms->prog_id = ImageHdr.Id; 3555fcf3ce44SJohn Forte ChangeParams = TRUE; 3556fcf3ce44SJohn Forte break; 3557fcf3ce44SJohn Forte case BOOT_BIOS: 3558fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_id = ImageHdr.Id; 3559fcf3ce44SJohn Forte ChangeParams = TRUE; 3560fcf3ce44SJohn Forte break; 3561fcf3ce44SJohn Forte case SLI1_OVERLAY: 3562fcf3ce44SJohn Forte AbsWakeUpParms->sli1_prog_id = ImageHdr.Id; 3563fcf3ce44SJohn Forte ChangeParams = TRUE; 3564fcf3ce44SJohn Forte break; 3565fcf3ce44SJohn Forte case SLI2_OVERLAY: 3566fcf3ce44SJohn Forte AbsWakeUpParms->sli2_prog_id = ImageHdr.Id; 3567fcf3ce44SJohn Forte ChangeParams = TRUE; 3568fcf3ce44SJohn Forte break; 3569fcf3ce44SJohn Forte case SLI3_OVERLAY: 3570fcf3ce44SJohn Forte AbsWakeUpParms->sli3_prog_id = ImageHdr.Id; 3571fcf3ce44SJohn Forte ChangeParams = TRUE; 3572fcf3ce44SJohn Forte break; 3573fcf3ce44SJohn Forte case SLI4_OVERLAY: 3574fcf3ce44SJohn Forte AbsWakeUpParms->sli4_prog_id = ImageHdr.Id; 3575fcf3ce44SJohn Forte ChangeParams = TRUE; 3576fcf3ce44SJohn Forte break; 3577fcf3ce44SJohn Forte default: 3578fcf3ce44SJohn Forte break; 3579fcf3ce44SJohn Forte } 3580fcf3ce44SJohn Forte 3581fcf3ce44SJohn Forte NextImage += ImageHdr.BlockSize; 3582fcf3ce44SJohn Forte } 3583fcf3ce44SJohn Forte 3584fcf3ce44SJohn Forte return (ChangeParams); 3585fcf3ce44SJohn Forte 358682527734SSukumar Swaminathan } /* emlxs_build_parms() */ 3587fcf3ce44SJohn Forte 3588fcf3ce44SJohn Forte 3589fcf3ce44SJohn Forte static uint32_t 3590fcf3ce44SJohn Forte emlxs_update_wakeup_parms(emlxs_hba_t *hba, 3591fcf3ce44SJohn Forte PWAKE_UP_PARMS AbsWakeUpParms, PWAKE_UP_PARMS WakeUpParms) 3592fcf3ce44SJohn Forte { 3593fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3594fcf3ce44SJohn Forte MAILBOX *mb; 3595fcf3ce44SJohn Forte MAILBOXQ *mbox; 3596fcf3ce44SJohn Forte uint32_t rval = 0; 3597fcf3ce44SJohn Forte 3598291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 3599291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 3600fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3601fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 3602fcf3ce44SJohn Forte 3603fcf3ce44SJohn Forte return (1); 3604fcf3ce44SJohn Forte } 3605291a2b48SSukumar Swaminathan 3606fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 3607fcf3ce44SJohn Forte 3608fcf3ce44SJohn Forte WakeUpParms->prog_id = AbsWakeUpParms->prog_id; 3609fcf3ce44SJohn Forte WakeUpParms->u0.boot_bios_id = AbsWakeUpParms->u0.boot_bios_id; 3610fcf3ce44SJohn Forte WakeUpParms->sli1_prog_id = AbsWakeUpParms->sli1_prog_id; 3611fcf3ce44SJohn Forte WakeUpParms->sli2_prog_id = AbsWakeUpParms->sli2_prog_id; 3612fcf3ce44SJohn Forte WakeUpParms->sli3_prog_id = AbsWakeUpParms->sli3_prog_id; 3613fcf3ce44SJohn Forte WakeUpParms->sli4_prog_id = AbsWakeUpParms->sli4_prog_id; 3614fcf3ce44SJohn Forte 361582527734SSukumar Swaminathan emlxs_format_update_parms(mbox, WakeUpParms); 3616fcf3ce44SJohn Forte 361782527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 3618fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3619291a2b48SSukumar Swaminathan "Unable to update wakeup parameters: Mailbox cmd=%x " 3620291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 3621fcf3ce44SJohn Forte 3622fcf3ce44SJohn Forte rval = 1; 3623fcf3ce44SJohn Forte } 3624291a2b48SSukumar Swaminathan 3625fcf3ce44SJohn Forte if (mbox) { 3626fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 3627fcf3ce44SJohn Forte } 3628291a2b48SSukumar Swaminathan 3629fcf3ce44SJohn Forte return (rval); 3630fcf3ce44SJohn Forte 363182527734SSukumar Swaminathan } /* emlxs_update_wakeup_parms() */ 3632fcf3ce44SJohn Forte 3633fcf3ce44SJohn Forte 3634fcf3ce44SJohn Forte static uint32_t 3635291a2b48SSukumar Swaminathan emlxs_validate_version(emlxs_hba_t *hba, emlxs_fw_file_t *file, uint32_t id, 3636291a2b48SSukumar Swaminathan uint32_t type, char *file_type) 3637fcf3ce44SJohn Forte { 3638fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3639fcf3ce44SJohn Forte 3640fcf3ce44SJohn Forte /* Create the version label */ 3641fcf3ce44SJohn Forte emlxs_decode_version(file->version, file->label); 3642fcf3ce44SJohn Forte 3643fcf3ce44SJohn Forte /* Process the DWC type */ 3644fcf3ce44SJohn Forte switch (type) { 3645fcf3ce44SJohn Forte case TEST_PROGRAM: 3646fcf3ce44SJohn Forte 3647fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3648291a2b48SSukumar Swaminathan "%s: TEST: offset=%08x version=%08x, %s", file_type, 3649291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 3650fcf3ce44SJohn Forte 3651fcf3ce44SJohn Forte break; 3652fcf3ce44SJohn Forte 3653fcf3ce44SJohn Forte case BOOT_BIOS: 3654fcf3ce44SJohn Forte 3655fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3656291a2b48SSukumar Swaminathan "%s: BOOT: offset=%08x version=%08x, %s", file_type, 3657291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 3658fcf3ce44SJohn Forte 3659fcf3ce44SJohn Forte if (!emlxs_bios_check(hba, id)) { 3660fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3661fcf3ce44SJohn Forte "BOOT Check: Image not compatible with %s. id=%02x", 3662fcf3ce44SJohn Forte hba->model_info.model, id); 3663fcf3ce44SJohn Forte 3664fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 3665fcf3ce44SJohn Forte } 3666291a2b48SSukumar Swaminathan 3667fcf3ce44SJohn Forte break; 3668fcf3ce44SJohn Forte 3669fcf3ce44SJohn Forte case FUNC_FIRMWARE: /* Stub */ 3670fcf3ce44SJohn Forte 3671fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3672291a2b48SSukumar Swaminathan "%s: STUB: offset=%08x version=%08x, %s", file_type, 3673291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 3674fcf3ce44SJohn Forte 3675fcf3ce44SJohn Forte if (!emlxs_stub_check(hba, id)) { 3676fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3677fcf3ce44SJohn Forte "STUB Check: Image not compatible with %s. id=%02x", 3678fcf3ce44SJohn Forte hba->model_info.model, id); 3679fcf3ce44SJohn Forte 3680fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 3681fcf3ce44SJohn Forte } 3682291a2b48SSukumar Swaminathan 3683fcf3ce44SJohn Forte break; 3684fcf3ce44SJohn Forte 3685fcf3ce44SJohn Forte case SLI1_OVERLAY: 3686fcf3ce44SJohn Forte 3687fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3688291a2b48SSukumar Swaminathan "%s: SLI1: offset=%08x version=%08x, %s", file_type, 3689291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 3690fcf3ce44SJohn Forte 3691fcf3ce44SJohn Forte if (!emlxs_sli1_check(hba, id)) { 3692fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3693fcf3ce44SJohn Forte "SLI1 Check: Image not compatible with %s. id=%02x", 3694fcf3ce44SJohn Forte hba->model_info.model, id); 3695fcf3ce44SJohn Forte 3696fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 3697fcf3ce44SJohn Forte } 3698291a2b48SSukumar Swaminathan 3699fcf3ce44SJohn Forte break; 3700fcf3ce44SJohn Forte 3701fcf3ce44SJohn Forte case SLI2_OVERLAY: 3702fcf3ce44SJohn Forte 3703fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3704291a2b48SSukumar Swaminathan "%s: SLI2: offset=%08x version=%08x, %s", file_type, 3705291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 3706fcf3ce44SJohn Forte 3707fcf3ce44SJohn Forte if (!emlxs_sli2_check(hba, id)) { 3708fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3709fcf3ce44SJohn Forte "SLI2 Check: Image not compatible with %s. id=%02x", 3710fcf3ce44SJohn Forte hba->model_info.model, id); 3711fcf3ce44SJohn Forte 3712fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 3713fcf3ce44SJohn Forte } 3714291a2b48SSukumar Swaminathan 3715fcf3ce44SJohn Forte break; 3716fcf3ce44SJohn Forte 3717fcf3ce44SJohn Forte case SLI3_OVERLAY: 3718fcf3ce44SJohn Forte 3719fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3720291a2b48SSukumar Swaminathan "%s: SLI3: offset=%08x version=%08x, %s", file_type, 3721291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 3722fcf3ce44SJohn Forte 3723fcf3ce44SJohn Forte if (!emlxs_sli3_check(hba, id)) { 3724fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3725fcf3ce44SJohn Forte "SLI3 Check: Image not compatible with %s. id=%02x", 3726fcf3ce44SJohn Forte hba->model_info.model, id); 3727fcf3ce44SJohn Forte 3728fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 3729fcf3ce44SJohn Forte } 3730291a2b48SSukumar Swaminathan 3731fcf3ce44SJohn Forte break; 3732fcf3ce44SJohn Forte 3733fcf3ce44SJohn Forte case SLI4_OVERLAY: 3734fcf3ce44SJohn Forte 3735fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3736291a2b48SSukumar Swaminathan "%s: SLI4: offset=%08x version=%08x, %s", file_type, 3737291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 3738fcf3ce44SJohn Forte 3739fcf3ce44SJohn Forte if (!emlxs_sli4_check(hba, id)) { 3740fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3741fcf3ce44SJohn Forte "SLI4 Check: Image not compatible with %s. id=%02x", 3742fcf3ce44SJohn Forte hba->model_info.model, id); 3743fcf3ce44SJohn Forte 3744fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 3745fcf3ce44SJohn Forte } 3746291a2b48SSukumar Swaminathan 3747fcf3ce44SJohn Forte break; 3748fcf3ce44SJohn Forte 3749fcf3ce44SJohn Forte case SBUS_FCODE: 3750fcf3ce44SJohn Forte 3751fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3752fcf3ce44SJohn Forte "%s: SBUS FCODE: offset=%08x version=%08x, %s", 3753291a2b48SSukumar Swaminathan file_type, file->offset, file->version, file->label); 3754fcf3ce44SJohn Forte 3755fcf3ce44SJohn Forte if (!emlxs_sbus_fcode_check(hba, id)) { 3756fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3757fcf3ce44SJohn Forte "SBUS FCODE Check: Image not compatible with %s. " 3758291a2b48SSukumar Swaminathan "id=%02x", hba->model_info.model, id); 3759fcf3ce44SJohn Forte 3760fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 3761fcf3ce44SJohn Forte } 3762291a2b48SSukumar Swaminathan 3763fcf3ce44SJohn Forte break; 3764fcf3ce44SJohn Forte 3765fcf3ce44SJohn Forte case KERNEL_CODE: 3766fcf3ce44SJohn Forte 3767fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3768291a2b48SSukumar Swaminathan "%s: KERN: offset=%08x version=%08x, %s", file_type, 3769291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 3770fcf3ce44SJohn Forte 3771fcf3ce44SJohn Forte if (!emlxs_kern_check(hba, id)) { 3772fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3773fcf3ce44SJohn Forte "KERN Check: Image not compatible with %s. id=%02x", 3774fcf3ce44SJohn Forte hba->model_info.model, id); 3775fcf3ce44SJohn Forte 3776fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 3777fcf3ce44SJohn Forte } 3778291a2b48SSukumar Swaminathan 3779fcf3ce44SJohn Forte break; 3780fcf3ce44SJohn Forte 3781fcf3ce44SJohn Forte default: 3782fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 3783291a2b48SSukumar Swaminathan "%s: Image type not supported. type=%x", file_type, type); 3784fcf3ce44SJohn Forte 3785fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 3786fcf3ce44SJohn Forte } 3787fcf3ce44SJohn Forte 3788fcf3ce44SJohn Forte return (0); 3789fcf3ce44SJohn Forte 379082527734SSukumar Swaminathan } /* emlxs_validate_version() */ 3791fcf3ce44SJohn Forte 3792fcf3ce44SJohn Forte 37936a573d82SSukumar Swaminathan static void 37946a573d82SSukumar Swaminathan emlxs_verify_image(emlxs_hba_t *hba, emlxs_fw_image_t *fw_image) 37956a573d82SSukumar Swaminathan { 37966a573d82SSukumar Swaminathan emlxs_port_t *port = &PPORT; 37976a573d82SSukumar Swaminathan emlxs_vpd_t *vpd = &VPD; 37986a573d82SSukumar Swaminathan uint32_t i; 37996a573d82SSukumar Swaminathan uint32_t count; 38006a573d82SSukumar Swaminathan 38016a573d82SSukumar Swaminathan /* Check for AWC file */ 38026a573d82SSukumar Swaminathan if (fw_image->awc.version) { 38036a573d82SSukumar Swaminathan if (fw_image->awc.version == vpd->postKernRev) { 38046a573d82SSukumar Swaminathan fw_image->awc.version = 0; 38056a573d82SSukumar Swaminathan } 38066a573d82SSukumar Swaminathan 38076a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 38086a573d82SSukumar Swaminathan "AWC file: KERN: old=%s new=%s %s.", 38096a573d82SSukumar Swaminathan vpd->postKernName, 38106a573d82SSukumar Swaminathan fw_image->awc.label, 38116a573d82SSukumar Swaminathan (fw_image->awc.version)? "Update":"Skip"); 38126a573d82SSukumar Swaminathan } 38136a573d82SSukumar Swaminathan 38146a573d82SSukumar Swaminathan /* Check for BWC file */ 38156a573d82SSukumar Swaminathan if (fw_image->bwc.version) { 38166a573d82SSukumar Swaminathan if (strcmp(vpd->fcode_version, fw_image->bwc.label) == 0) { 38176a573d82SSukumar Swaminathan fw_image->bwc.version = 0; 38186a573d82SSukumar Swaminathan } 38196a573d82SSukumar Swaminathan 38206a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 38216a573d82SSukumar Swaminathan "BWC file: BOOT: old=%s new=%s %s.", 38226a573d82SSukumar Swaminathan vpd->fcode_version, 38236a573d82SSukumar Swaminathan fw_image->bwc.label, 38246a573d82SSukumar Swaminathan (fw_image->bwc.version)? "Update":"Skip"); 38256a573d82SSukumar Swaminathan } 38266a573d82SSukumar Swaminathan 38276a573d82SSukumar Swaminathan /* Check for DWC file */ 38286a573d82SSukumar Swaminathan if (fw_image->dwc.version) { 38296a573d82SSukumar Swaminathan /* Check for program files */ 38306a573d82SSukumar Swaminathan count = 0; 38316a573d82SSukumar Swaminathan for (i = 0; i < MAX_PROG_TYPES; i++) { 38326a573d82SSukumar Swaminathan if (!fw_image->prog[i].version) { 38336a573d82SSukumar Swaminathan continue; 38346a573d82SSukumar Swaminathan } 38356a573d82SSukumar Swaminathan 38366a573d82SSukumar Swaminathan /* Skip components that don't need updating */ 38376a573d82SSukumar Swaminathan switch (i) { 38386a573d82SSukumar Swaminathan case TEST_PROGRAM: 38396a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 38406a573d82SSukumar Swaminathan "DWC file: TEST: new=%s " 38416a573d82SSukumar Swaminathan "Update.", 38426a573d82SSukumar Swaminathan fw_image->prog[i].label); 38436a573d82SSukumar Swaminathan break; 38446a573d82SSukumar Swaminathan 38456a573d82SSukumar Swaminathan case BOOT_BIOS: 38466a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 38476a573d82SSukumar Swaminathan "DWC file: BOOT: new=%s " 38486a573d82SSukumar Swaminathan "Update.", 38496a573d82SSukumar Swaminathan fw_image->prog[i].label); 38506a573d82SSukumar Swaminathan break; 38516a573d82SSukumar Swaminathan 38526a573d82SSukumar Swaminathan case FUNC_FIRMWARE: 38536a573d82SSukumar Swaminathan if (vpd->opFwRev && 38546a573d82SSukumar Swaminathan (fw_image->prog[i].version == 38556a573d82SSukumar Swaminathan vpd->opFwRev)) { 38566a573d82SSukumar Swaminathan fw_image->prog[i].version = 0; 38576a573d82SSukumar Swaminathan } 38586a573d82SSukumar Swaminathan 38596a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 38606a573d82SSukumar Swaminathan "DWC file: STUB: old=%s new=%s %s.", 38616a573d82SSukumar Swaminathan vpd->opFwName, 38626a573d82SSukumar Swaminathan fw_image->prog[i].label, 38636a573d82SSukumar Swaminathan (fw_image->prog[i].version)? 38646a573d82SSukumar Swaminathan "Update":"Skip"); 38656a573d82SSukumar Swaminathan break; 38666a573d82SSukumar Swaminathan 38676a573d82SSukumar Swaminathan case SLI1_OVERLAY: 38686a573d82SSukumar Swaminathan if (vpd->sli1FwRev && 38696a573d82SSukumar Swaminathan (fw_image->prog[i].version == 38706a573d82SSukumar Swaminathan vpd->sli1FwRev)) { 38716a573d82SSukumar Swaminathan fw_image->prog[i].version = 0; 38726a573d82SSukumar Swaminathan } 38736a573d82SSukumar Swaminathan 38746a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 38756a573d82SSukumar Swaminathan "DWC file: SLI1: old=%s new=%s %s.", 38766a573d82SSukumar Swaminathan vpd->sli1FwName, 38776a573d82SSukumar Swaminathan fw_image->prog[i].label, 38786a573d82SSukumar Swaminathan (fw_image->prog[i].version)? 38796a573d82SSukumar Swaminathan "Update":"Skip"); 38806a573d82SSukumar Swaminathan break; 38816a573d82SSukumar Swaminathan 38826a573d82SSukumar Swaminathan case SLI2_OVERLAY: 38836a573d82SSukumar Swaminathan if (vpd->sli2FwRev && 38846a573d82SSukumar Swaminathan (fw_image->prog[i].version == 38856a573d82SSukumar Swaminathan vpd->sli2FwRev)) { 38866a573d82SSukumar Swaminathan fw_image->prog[i].version = 0; 38876a573d82SSukumar Swaminathan } 38886a573d82SSukumar Swaminathan 38896a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 38906a573d82SSukumar Swaminathan "DWC file: SLI2: old=%s new=%s %s.", 38916a573d82SSukumar Swaminathan vpd->sli2FwName, 38926a573d82SSukumar Swaminathan fw_image->prog[i].label, 38936a573d82SSukumar Swaminathan (fw_image->prog[i].version)? 38946a573d82SSukumar Swaminathan "Update":"Skip"); 38956a573d82SSukumar Swaminathan break; 38966a573d82SSukumar Swaminathan 38976a573d82SSukumar Swaminathan case SLI3_OVERLAY: 38986a573d82SSukumar Swaminathan if (vpd->sli3FwRev && 38996a573d82SSukumar Swaminathan (fw_image->prog[i].version == 39006a573d82SSukumar Swaminathan vpd->sli3FwRev)) { 39016a573d82SSukumar Swaminathan fw_image->prog[i].version = 0; 39026a573d82SSukumar Swaminathan } 39036a573d82SSukumar Swaminathan 39046a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 39056a573d82SSukumar Swaminathan "DWC file: SLI3: old=%s new=%s %s.", 39066a573d82SSukumar Swaminathan vpd->sli3FwName, 39076a573d82SSukumar Swaminathan fw_image->prog[i].label, 39086a573d82SSukumar Swaminathan (fw_image->prog[i].version)? 39096a573d82SSukumar Swaminathan "Update":"Skip"); 39106a573d82SSukumar Swaminathan break; 39116a573d82SSukumar Swaminathan 39126a573d82SSukumar Swaminathan case SLI4_OVERLAY: 39136a573d82SSukumar Swaminathan if (vpd->sli4FwRev && 39146a573d82SSukumar Swaminathan (fw_image->prog[i].version == 39156a573d82SSukumar Swaminathan vpd->sli4FwRev)) { 39166a573d82SSukumar Swaminathan fw_image->prog[i].version = 0; 39176a573d82SSukumar Swaminathan } 39186a573d82SSukumar Swaminathan 39196a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 39206a573d82SSukumar Swaminathan "DWC file: SLI4: old=%s new=%s %s.", 39216a573d82SSukumar Swaminathan vpd->sli4FwRev, 39226a573d82SSukumar Swaminathan fw_image->prog[i].label, 39236a573d82SSukumar Swaminathan (fw_image->prog[i].version)? 39246a573d82SSukumar Swaminathan "Update":"Skip"); 39256a573d82SSukumar Swaminathan break; 39266a573d82SSukumar Swaminathan 39276a573d82SSukumar Swaminathan default: 39286a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 39296a573d82SSukumar Swaminathan "DWC file: type=%x version=%x label=%s " 39306a573d82SSukumar Swaminathan "Update.", 39316a573d82SSukumar Swaminathan i, 39326a573d82SSukumar Swaminathan fw_image->prog[i].version, 39336a573d82SSukumar Swaminathan fw_image->prog[i].label); 39346a573d82SSukumar Swaminathan } 39356a573d82SSukumar Swaminathan 39366a573d82SSukumar Swaminathan if (fw_image->prog[i].version) { 39376a573d82SSukumar Swaminathan count++; 39386a573d82SSukumar Swaminathan } 39396a573d82SSukumar Swaminathan } 39406a573d82SSukumar Swaminathan 39416a573d82SSukumar Swaminathan if (!count) { 39426a573d82SSukumar Swaminathan fw_image->dwc.version = 0; 39436a573d82SSukumar Swaminathan } 39446a573d82SSukumar Swaminathan } 39456a573d82SSukumar Swaminathan 39466a573d82SSukumar Swaminathan return; 39476a573d82SSukumar Swaminathan 39486a573d82SSukumar Swaminathan } /* emlxs_verify_image() */ 39496a573d82SSukumar Swaminathan 39506a573d82SSukumar Swaminathan 3951fcf3ce44SJohn Forte static uint32_t 3952fcf3ce44SJohn Forte emlxs_validate_image(emlxs_hba_t *hba, caddr_t Buffer, uint32_t Size, 3953fcf3ce44SJohn Forte emlxs_fw_image_t *image) 3954fcf3ce44SJohn Forte { 3955fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3956fcf3ce44SJohn Forte uint32_t ImageType; 3957fcf3ce44SJohn Forte AIF_HDR AifHdr; 3958fcf3ce44SJohn Forte IMAGE_HDR ImageHdr; 3959fcf3ce44SJohn Forte uint32_t NextImage; 39606a573d82SSukumar Swaminathan uint32_t count; 3961fcf3ce44SJohn Forte uint32_t FileType; 3962fcf3ce44SJohn Forte uint32_t FileLen = 0; 3963fcf3ce44SJohn Forte uint32_t TotalLen = 0; 3964fcf3ce44SJohn Forte uint32_t *CkSumEnd; 3965fcf3ce44SJohn Forte uint32_t id; 3966fcf3ce44SJohn Forte uint32_t type; 3967fcf3ce44SJohn Forte uint32_t ver; 3968fcf3ce44SJohn Forte uint32_t ImageLength; 3969fcf3ce44SJohn Forte uint32_t BufferSize; 3970fcf3ce44SJohn Forte uint32_t rval = 0; 3971fcf3ce44SJohn Forte caddr_t bptr; 3972fcf3ce44SJohn Forte emlxs_vpd_t *vpd; 3973fcf3ce44SJohn Forte 3974fcf3ce44SJohn Forte vpd = &VPD; 3975fcf3ce44SJohn Forte 3976fcf3ce44SJohn Forte /* Get image type */ 3977fcf3ce44SJohn Forte ImageType = *((uint32_t *)Buffer); 3978fcf3ce44SJohn Forte 3979fcf3ce44SJohn Forte /* Pegasus and beyond adapters */ 3980fcf3ce44SJohn Forte if ((ImageType == NOP_IMAGE_TYPE) && 3981fcf3ce44SJohn Forte !(hba->model_info.chip & 3982fcf3ce44SJohn Forte (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 3983fcf3ce44SJohn Forte bptr = Buffer; 3984fcf3ce44SJohn Forte TotalLen = sizeof (uint32_t); 3985fcf3ce44SJohn Forte 3986fcf3ce44SJohn Forte while (TotalLen < Size) { 3987fcf3ce44SJohn Forte if (Size < sizeof (AIF_HDR)) { 3988291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 3989291a2b48SSukumar Swaminathan &emlxs_image_bad_msg, 3990fcf3ce44SJohn Forte "Invalid image header length: 0x%x < 0x%x", 3991fcf3ce44SJohn Forte Size, sizeof (AIF_HDR)); 3992fcf3ce44SJohn Forte 3993fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 3994fcf3ce44SJohn Forte } 3995291a2b48SSukumar Swaminathan 3996fcf3ce44SJohn Forte bcopy(bptr, &AifHdr, sizeof (AIF_HDR)); 3997fcf3ce44SJohn Forte emlxs_disp_aif_header(hba, &AifHdr); 3998fcf3ce44SJohn Forte 3999fcf3ce44SJohn Forte ImageLength = AifHdr.RoSize; 4000fcf3ce44SJohn Forte 4001fcf3ce44SJohn Forte /* Validate checksum */ 4002291a2b48SSukumar Swaminathan CkSumEnd = 4003291a2b48SSukumar Swaminathan (uint32_t *)(bptr + ImageLength + 4004291a2b48SSukumar Swaminathan sizeof (AIF_HDR)); 4005fcf3ce44SJohn Forte if (emlxs_valid_cksum((uint32_t *)bptr, CkSumEnd)) { 4006291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 4007291a2b48SSukumar Swaminathan &emlxs_image_bad_msg, 4008fcf3ce44SJohn Forte "Invalid checksum found."); 4009fcf3ce44SJohn Forte 4010fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 4011fcf3ce44SJohn Forte } 4012291a2b48SSukumar Swaminathan 4013fcf3ce44SJohn Forte FileType = AifHdr.ZinitBr; 4014fcf3ce44SJohn Forte switch (FileType) { 4015fcf3ce44SJohn Forte case FILE_TYPE_AWC: 4016291a2b48SSukumar Swaminathan image->awc.offset = 4017291a2b48SSukumar Swaminathan (uint32_t)((uintptr_t)bptr - 4018291a2b48SSukumar Swaminathan (uintptr_t)Buffer); 4019fcf3ce44SJohn Forte image->awc.version = AifHdr.AVersion; 4020fcf3ce44SJohn Forte image->awc.revcomp = 0; 4021fcf3ce44SJohn Forte 4022fcf3ce44SJohn Forte id = (AifHdr.AVersion & 0x00ff0000) >> 16; 4023fcf3ce44SJohn Forte type = emlxs_type_check( 4024fcf3ce44SJohn Forte (AifHdr.AVersion & 0xff000000) >> 24); 4025fcf3ce44SJohn Forte 4026fcf3ce44SJohn Forte /* Validate the file version */ 4027fcf3ce44SJohn Forte if ((rval = emlxs_validate_version(hba, 4028fcf3ce44SJohn Forte &image->awc, id, type, "AWC file"))) { 4029fcf3ce44SJohn Forte return (rval); 4030fcf3ce44SJohn Forte } 4031291a2b48SSukumar Swaminathan 4032fcf3ce44SJohn Forte break; 4033fcf3ce44SJohn Forte 4034fcf3ce44SJohn Forte case FILE_TYPE_BWC: 4035291a2b48SSukumar Swaminathan image->bwc.offset = 4036291a2b48SSukumar Swaminathan (uint32_t)((uintptr_t)bptr - 4037291a2b48SSukumar Swaminathan (uintptr_t)Buffer); 4038fcf3ce44SJohn Forte image->bwc.version = AifHdr.AVersion; 4039fcf3ce44SJohn Forte image->bwc.revcomp = 0; 4040fcf3ce44SJohn Forte 4041fcf3ce44SJohn Forte id = (AifHdr.AVersion & 0x00ff0000) >> 16; 4042fcf3ce44SJohn Forte type = emlxs_type_check( 4043fcf3ce44SJohn Forte (AifHdr.AVersion & 0xff000000) >> 24); 4044fcf3ce44SJohn Forte 4045fcf3ce44SJohn Forte /* Validate the file version */ 4046fcf3ce44SJohn Forte if ((rval = emlxs_validate_version(hba, 4047fcf3ce44SJohn Forte &image->bwc, id, type, "BWC file"))) { 4048fcf3ce44SJohn Forte return (rval); 4049fcf3ce44SJohn Forte } 4050291a2b48SSukumar Swaminathan 4051fcf3ce44SJohn Forte break; 4052fcf3ce44SJohn Forte 4053fcf3ce44SJohn Forte case FILE_TYPE_DWC: 4054291a2b48SSukumar Swaminathan image->dwc.offset = 4055291a2b48SSukumar Swaminathan (uint32_t)((uintptr_t)bptr - 4056291a2b48SSukumar Swaminathan (uintptr_t)Buffer); 4057fcf3ce44SJohn Forte image->dwc.version = AifHdr.AVersion; 4058fcf3ce44SJohn Forte image->dwc.revcomp = 0; 4059fcf3ce44SJohn Forte 4060fcf3ce44SJohn Forte id = (AifHdr.AVersion & 0x00ff0000) >> 16; 4061fcf3ce44SJohn Forte type = emlxs_type_check( 4062fcf3ce44SJohn Forte (AifHdr.AVersion & 0xff000000) >> 24); 4063fcf3ce44SJohn Forte 4064fcf3ce44SJohn Forte /* Validate the file version */ 4065fcf3ce44SJohn Forte if ((rval = emlxs_validate_version(hba, 4066fcf3ce44SJohn Forte &image->dwc, id, type, "DWC file"))) { 4067fcf3ce44SJohn Forte return (rval); 4068fcf3ce44SJohn Forte } 4069291a2b48SSukumar Swaminathan 4070fcf3ce44SJohn Forte /* Scan for program types */ 4071fcf3ce44SJohn Forte NextImage = sizeof (AIF_HDR) + 4; 4072fcf3ce44SJohn Forte BufferSize = AifHdr.RoSize + AifHdr.RwSize; 4073fcf3ce44SJohn Forte 40746a573d82SSukumar Swaminathan count = 0; 4075fcf3ce44SJohn Forte while (BufferSize > NextImage) { 4076fcf3ce44SJohn Forte bcopy(&bptr[NextImage], &ImageHdr, 4077fcf3ce44SJohn Forte sizeof (IMAGE_HDR)); 4078291a2b48SSukumar Swaminathan emlxs_dump_image_header(hba, 4079291a2b48SSukumar Swaminathan &ImageHdr); 4080fcf3ce44SJohn Forte 4081fcf3ce44SJohn Forte /* Validate block size */ 4082fcf3ce44SJohn Forte if (ImageHdr.BlockSize == 0xffffffff) { 4083fcf3ce44SJohn Forte break; 4084fcf3ce44SJohn Forte } 4085291a2b48SSukumar Swaminathan 4086fcf3ce44SJohn Forte type = emlxs_type_check( 4087fcf3ce44SJohn Forte ImageHdr.Id.Type); 4088fcf3ce44SJohn Forte 4089fcf3ce44SJohn Forte /* Calculate the program offset */ 4090291a2b48SSukumar Swaminathan image->prog[type].offset = 4091291a2b48SSukumar Swaminathan (uint32_t)((uintptr_t) 4092291a2b48SSukumar Swaminathan &bptr[NextImage] - 4093fcf3ce44SJohn Forte (uintptr_t)Buffer); 4094fcf3ce44SJohn Forte 4095fcf3ce44SJohn Forte /* Acquire the versions */ 4096fcf3ce44SJohn Forte image->prog[type].version = 4097fcf3ce44SJohn Forte (ImageHdr.Id.Type << 24) | 4098fcf3ce44SJohn Forte (ImageHdr.Id.Id << 16) | 4099fcf3ce44SJohn Forte (ImageHdr.Id.Ver << 8) | 4100fcf3ce44SJohn Forte ImageHdr.Id.Rev; 4101fcf3ce44SJohn Forte 4102fcf3ce44SJohn Forte image->prog[type].revcomp = 4103fcf3ce44SJohn Forte ImageHdr.Id.un.revcomp; 4104fcf3ce44SJohn Forte 4105fcf3ce44SJohn Forte /* Validate the file version */ 4106fcf3ce44SJohn Forte if ((rval = emlxs_validate_version(hba, 4107fcf3ce44SJohn Forte &image->prog[type], ImageHdr.Id.Id, 4108fcf3ce44SJohn Forte type, "DWC prog"))) { 4109fcf3ce44SJohn Forte return (rval); 4110fcf3ce44SJohn Forte } 4111291a2b48SSukumar Swaminathan 41126a573d82SSukumar Swaminathan count++; 4113fcf3ce44SJohn Forte NextImage += ImageHdr.BlockSize; 4114fcf3ce44SJohn Forte 411582527734SSukumar Swaminathan } /* while () */ 4116fcf3ce44SJohn Forte 41176a573d82SSukumar Swaminathan if (count == 0) { 41186a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 41196a573d82SSukumar Swaminathan &emlxs_image_bad_msg, 41206a573d82SSukumar Swaminathan "DWC file has no PRG images."); 41216a573d82SSukumar Swaminathan 41226a573d82SSukumar Swaminathan return (EMLXS_IMAGE_BAD); 41236a573d82SSukumar Swaminathan } 41246a573d82SSukumar Swaminathan 4125fcf3ce44SJohn Forte break; 4126fcf3ce44SJohn Forte } 4127fcf3ce44SJohn Forte 4128291a2b48SSukumar Swaminathan FileLen = 4129291a2b48SSukumar Swaminathan sizeof (AIF_HDR) + ImageLength + 4130fcf3ce44SJohn Forte sizeof (uint32_t); 4131fcf3ce44SJohn Forte TotalLen += FileLen; 4132fcf3ce44SJohn Forte bptr += FileLen; 4133fcf3ce44SJohn Forte } 4134fcf3ce44SJohn Forte } 4135291a2b48SSukumar Swaminathan 4136fcf3ce44SJohn Forte /* Pre-pegasus adapters */ 4137fcf3ce44SJohn Forte 4138fcf3ce44SJohn Forte else if (ImageType == NOP_IMAGE_TYPE) { 4139fcf3ce44SJohn Forte if (Size < sizeof (AIF_HDR)) { 4140fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 4141291a2b48SSukumar Swaminathan "Invalid image header length: 0x%x < 0x%x", Size, 4142291a2b48SSukumar Swaminathan sizeof (AIF_HDR)); 4143fcf3ce44SJohn Forte 4144fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 4145fcf3ce44SJohn Forte } 4146291a2b48SSukumar Swaminathan 4147fcf3ce44SJohn Forte bcopy(Buffer, &AifHdr, sizeof (AIF_HDR)); 4148fcf3ce44SJohn Forte emlxs_disp_aif_header(hba, &AifHdr); 4149fcf3ce44SJohn Forte 4150fcf3ce44SJohn Forte ImageLength = AifHdr.RoSize + AifHdr.RwSize; 4151fcf3ce44SJohn Forte 4152fcf3ce44SJohn Forte if (Size != (sizeof (AIF_HDR) + ImageLength + sizeof (int))) { 4153fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 4154291a2b48SSukumar Swaminathan "Image length incorrect: 0x%x != 0x%x", Size, 4155291a2b48SSukumar Swaminathan sizeof (AIF_HDR) + ImageLength + 4156291a2b48SSukumar Swaminathan sizeof (uint32_t)); 4157fcf3ce44SJohn Forte 4158fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 4159fcf3ce44SJohn Forte } 4160291a2b48SSukumar Swaminathan 4161fcf3ce44SJohn Forte if (AifHdr.ImageBase && AifHdr.ImageBase != 0x20000) { 4162fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 4163fcf3ce44SJohn Forte "Invalid imageBase value %x != 0x20000", 4164fcf3ce44SJohn Forte AifHdr.ImageBase); 4165fcf3ce44SJohn Forte 4166fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 4167fcf3ce44SJohn Forte } 4168291a2b48SSukumar Swaminathan 4169291a2b48SSukumar Swaminathan CkSumEnd = 4170291a2b48SSukumar Swaminathan (uint32_t *)(Buffer + ImageLength + sizeof (AIF_HDR)); 4171fcf3ce44SJohn Forte if (emlxs_valid_cksum((uint32_t *)Buffer, CkSumEnd)) { 4172fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 4173fcf3ce44SJohn Forte "Invalid checksum found."); 4174fcf3ce44SJohn Forte 4175fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 4176fcf3ce44SJohn Forte } 4177291a2b48SSukumar Swaminathan 4178fcf3ce44SJohn Forte image->dwc.offset = 0; 4179fcf3ce44SJohn Forte image->dwc.version = AifHdr.AVersion; 4180fcf3ce44SJohn Forte image->dwc.revcomp = 0; 4181fcf3ce44SJohn Forte 4182fcf3ce44SJohn Forte id = (AifHdr.AVersion & 0x00ff0000) >> 16; 4183fcf3ce44SJohn Forte type = emlxs_type_check((AifHdr.AVersion & 0xff000000) >> 24); 4184fcf3ce44SJohn Forte 4185fcf3ce44SJohn Forte /* Validate the file version */ 4186291a2b48SSukumar Swaminathan if ((rval = emlxs_validate_version(hba, &image->dwc, id, type, 4187291a2b48SSukumar Swaminathan "DWC file"))) { 4188fcf3ce44SJohn Forte return (rval); 4189fcf3ce44SJohn Forte } 4190291a2b48SSukumar Swaminathan 4191fcf3ce44SJohn Forte NextImage = SLI_IMAGE_START - AifHdr.ImageBase; 4192fcf3ce44SJohn Forte while (Size > NextImage) { 4193fcf3ce44SJohn Forte bcopy(&Buffer[NextImage], &ImageHdr, 4194fcf3ce44SJohn Forte sizeof (IMAGE_HDR)); 4195fcf3ce44SJohn Forte emlxs_dump_image_header(hba, &ImageHdr); 4196fcf3ce44SJohn Forte 4197fcf3ce44SJohn Forte /* Validate block size */ 4198fcf3ce44SJohn Forte if (ImageHdr.BlockSize == 0xffffffff) { 4199fcf3ce44SJohn Forte break; 4200fcf3ce44SJohn Forte } 4201291a2b48SSukumar Swaminathan 4202fcf3ce44SJohn Forte type = emlxs_type_check(ImageHdr.Id.Type); 4203fcf3ce44SJohn Forte 4204fcf3ce44SJohn Forte /* Calculate the program offset */ 4205fcf3ce44SJohn Forte image->prog[type].offset = NextImage; 4206fcf3ce44SJohn Forte 4207fcf3ce44SJohn Forte /* Acquire the versions */ 4208291a2b48SSukumar Swaminathan image->prog[type].version = 4209291a2b48SSukumar Swaminathan (ImageHdr.Id.Type << 24) | 4210291a2b48SSukumar Swaminathan (ImageHdr.Id.Id << 16) | 4211291a2b48SSukumar Swaminathan (ImageHdr.Id.Ver << 8) | 4212fcf3ce44SJohn Forte ImageHdr.Id.Rev; 4213fcf3ce44SJohn Forte 4214fcf3ce44SJohn Forte image->prog[type].revcomp = ImageHdr.Id.un.revcomp; 4215fcf3ce44SJohn Forte 4216fcf3ce44SJohn Forte /* Validate the file version */ 4217fcf3ce44SJohn Forte if ((rval = emlxs_validate_version(hba, 4218291a2b48SSukumar Swaminathan &image->prog[type], ImageHdr.Id.Id, type, 4219291a2b48SSukumar Swaminathan "DWC prog"))) { 4220fcf3ce44SJohn Forte return (rval); 4221fcf3ce44SJohn Forte } 4222291a2b48SSukumar Swaminathan 4223fcf3ce44SJohn Forte NextImage += ImageHdr.BlockSize; 4224fcf3ce44SJohn Forte } 42256a573d82SSukumar Swaminathan 42266a573d82SSukumar Swaminathan } else { /* PRG File */ 42276a573d82SSukumar Swaminathan 4228fcf3ce44SJohn Forte /* Precheck image size */ 4229fcf3ce44SJohn Forte if (Size < sizeof (IMAGE_HDR)) { 4230fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 4231291a2b48SSukumar Swaminathan "Invalid image header length: 0x%x < 0x%x", Size, 4232291a2b48SSukumar Swaminathan sizeof (IMAGE_HDR)); 4233fcf3ce44SJohn Forte 4234fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 4235fcf3ce44SJohn Forte } 4236291a2b48SSukumar Swaminathan 4237fcf3ce44SJohn Forte bcopy(Buffer, &ImageHdr, sizeof (IMAGE_HDR)); 4238fcf3ce44SJohn Forte emlxs_dump_image_header(hba, &ImageHdr); 4239fcf3ce44SJohn Forte 4240fcf3ce44SJohn Forte /* Validate block size */ 4241fcf3ce44SJohn Forte if (ImageHdr.BlockSize == 0xffffffff) { 4242fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 4243fcf3ce44SJohn Forte "Invalid block size."); 4244fcf3ce44SJohn Forte 4245fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 4246fcf3ce44SJohn Forte } 4247291a2b48SSukumar Swaminathan 4248fcf3ce44SJohn Forte ImageLength = ImageHdr.BlockSize; 4249fcf3ce44SJohn Forte 4250fcf3ce44SJohn Forte /* Validate image length */ 4251fcf3ce44SJohn Forte if (Size != ImageLength) { 4252fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 4253291a2b48SSukumar Swaminathan "Invalid image length: 0x%x != 0x%x", Size, 4254291a2b48SSukumar Swaminathan ImageLength); 4255fcf3ce44SJohn Forte 4256fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 4257fcf3ce44SJohn Forte } 4258291a2b48SSukumar Swaminathan 4259fcf3ce44SJohn Forte /* Validate Checksum */ 4260291a2b48SSukumar Swaminathan CkSumEnd = 4261291a2b48SSukumar Swaminathan (uint32_t *)Buffer + (ImageLength / sizeof (uint32_t)) - 4262291a2b48SSukumar Swaminathan 1; 4263fcf3ce44SJohn Forte if (emlxs_valid_cksum((uint32_t *)Buffer, CkSumEnd)) { 4264fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 4265fcf3ce44SJohn Forte "Invalid checksum found."); 4266fcf3ce44SJohn Forte 4267fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 4268fcf3ce44SJohn Forte } 4269291a2b48SSukumar Swaminathan 4270fcf3ce44SJohn Forte type = emlxs_type_check(ImageHdr.Id.Type); 4271fcf3ce44SJohn Forte 4272fcf3ce44SJohn Forte /* Calculate the program offset */ 4273fcf3ce44SJohn Forte image->prog[type].offset = 0; 4274fcf3ce44SJohn Forte 4275fcf3ce44SJohn Forte /* Acquire the versions */ 4276291a2b48SSukumar Swaminathan image->prog[type].version = 42776a573d82SSukumar Swaminathan (ImageHdr.Id.Type << 24) | 42786a573d82SSukumar Swaminathan (ImageHdr.Id.Id << 16) | 42796a573d82SSukumar Swaminathan (ImageHdr.Id.Ver << 8) | 42806a573d82SSukumar Swaminathan ImageHdr.Id.Rev; 4281fcf3ce44SJohn Forte 4282fcf3ce44SJohn Forte image->prog[type].revcomp = ImageHdr.Id.un.revcomp; 4283fcf3ce44SJohn Forte 4284fcf3ce44SJohn Forte /* Validate the file version */ 4285fcf3ce44SJohn Forte if ((rval = emlxs_validate_version(hba, &image->prog[type], 4286fcf3ce44SJohn Forte ImageHdr.Id.Id, type, "DWC file"))) { 4287fcf3ce44SJohn Forte return (rval); 4288fcf3ce44SJohn Forte } 4289fcf3ce44SJohn Forte } 4290fcf3ce44SJohn Forte 4291fcf3ce44SJohn Forte /* 4292291a2b48SSukumar Swaminathan * This checks if a DragonFly (pre-V2 ASIC) SLI2 42936a573d82SSukumar Swaminathan * image file is < version 3.8 4294fcf3ce44SJohn Forte */ 4295fcf3ce44SJohn Forte if (FC_JEDEC_ID(vpd->biuRev) == DRAGONFLY_JEDEC_ID) { 42966a573d82SSukumar Swaminathan ver = (image->prog[SLI2_OVERLAY].version & 42976a573d82SSukumar Swaminathan 0x0000ff00) >> 8; 4298fcf3ce44SJohn Forte 42996a573d82SSukumar Swaminathan if (ver >= 0x38) { 43006a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 43016a573d82SSukumar Swaminathan &emlxs_image_incompat_msg, 43026a573d82SSukumar Swaminathan "ASIC Check: Image requires DragonFly " 43036a573d82SSukumar Swaminathan "V2 ASIC"); 4304fcf3ce44SJohn Forte 43056a573d82SSukumar Swaminathan return (EMLXS_IMAGE_INCOMPATIBLE); 4306fcf3ce44SJohn Forte } 4307fcf3ce44SJohn Forte } 4308291a2b48SSukumar Swaminathan 4309fcf3ce44SJohn Forte return (0); 4310fcf3ce44SJohn Forte 431182527734SSukumar Swaminathan } /* emlxs_validate_image() */ 4312fcf3ce44SJohn Forte 4313fcf3ce44SJohn Forte 4314fcf3ce44SJohn Forte static uint32_t 4315fcf3ce44SJohn Forte emlxs_update_exp_rom(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms) 4316fcf3ce44SJohn Forte { 4317fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 4318fcf3ce44SJohn Forte MAILBOXQ *mbox; 4319fcf3ce44SJohn Forte MAILBOX *mb; 4320fcf3ce44SJohn Forte uint32_t next_address; 4321fcf3ce44SJohn Forte uint32_t rval = 0; 4322fcf3ce44SJohn Forte 4323fcf3ce44SJohn Forte if (WakeUpParms->u1.EROM_prog_wd[0] == 0) { 4324fcf3ce44SJohn Forte return (1); 4325fcf3ce44SJohn Forte } 4326291a2b48SSukumar Swaminathan 4327291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 4328291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 4329fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4330fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 4331fcf3ce44SJohn Forte 4332fcf3ce44SJohn Forte return (1); 4333fcf3ce44SJohn Forte } 4334291a2b48SSukumar Swaminathan 4335fcf3ce44SJohn Forte bzero(mbox, sizeof (MAILBOXQ)); 4336fcf3ce44SJohn Forte 4337fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 4338fcf3ce44SJohn Forte mb->mbxCommand = MBX_LOAD_EXP_ROM; 4339fcf3ce44SJohn Forte mb->un.varLdExpRom.step = EROM_CMD_FIND_IMAGE; 4340fcf3ce44SJohn Forte mb->un.varLdExpRom.progress = 0; 4341fcf3ce44SJohn Forte mb->un.varLdExpRom.un.prog_id = WakeUpParms->u1.EROM_prog_id; 434282527734SSukumar Swaminathan mbox->mbox_cmpl = NULL; 4343fcf3ce44SJohn Forte 434482527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 4345fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4346fcf3ce44SJohn Forte "Unable to load exp ROM. Mailbox cmd=%x status=%x", 4347fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 4348fcf3ce44SJohn Forte 4349fcf3ce44SJohn Forte rval = 1; 4350fcf3ce44SJohn Forte 4351fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 4352fcf3ce44SJohn Forte } 4353291a2b48SSukumar Swaminathan 4354fcf3ce44SJohn Forte if (mb->un.varLdExpRom.progress == EROM_RSP_COPY_DONE) { 4355fcf3ce44SJohn Forte (void) emlxs_update_wakeup_parms(hba, WakeUpParms, WakeUpParms); 4356fcf3ce44SJohn Forte 4357fcf3ce44SJohn Forte rval = 1; 4358fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 4359fcf3ce44SJohn Forte } 4360291a2b48SSukumar Swaminathan 4361fcf3ce44SJohn Forte if (mb->un.varLdExpRom.progress != EROM_RSP_ERASE_STARTED) { 4362fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4363fcf3ce44SJohn Forte "Invalid exp ROM progress. progress=%x", 4364fcf3ce44SJohn Forte mb->un.varLdExpRom.progress); 4365fcf3ce44SJohn Forte 4366fcf3ce44SJohn Forte rval = 1; 4367fcf3ce44SJohn Forte 4368fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 4369fcf3ce44SJohn Forte } 4370291a2b48SSukumar Swaminathan 4371fcf3ce44SJohn Forte /* 4372fcf3ce44SJohn Forte * continue Erase 4373fcf3ce44SJohn Forte */ 4374fcf3ce44SJohn Forte while (mb->un.varLdExpRom.progress != EROM_RSP_ERASE_COMPLETE) { 4375fcf3ce44SJohn Forte 4376fcf3ce44SJohn Forte next_address = mb->un.varLdExpRom.dl_to_adr; 4377fcf3ce44SJohn Forte 4378fcf3ce44SJohn Forte bzero((void *)mb, MAILBOX_CMD_BSIZE); 4379fcf3ce44SJohn Forte 4380fcf3ce44SJohn Forte mb->mbxCommand = MBX_LOAD_EXP_ROM; 4381fcf3ce44SJohn Forte mb->un.varLdExpRom.step = EROM_CMD_CONTINUE_ERASE; 4382fcf3ce44SJohn Forte mb->un.varLdExpRom.dl_to_adr = next_address; 4383fcf3ce44SJohn Forte mb->un.varLdExpRom.progress = 0; 4384fcf3ce44SJohn Forte mb->un.varLdExpRom.un.prog_id = WakeUpParms->u1.EROM_prog_id; 438582527734SSukumar Swaminathan mbox->mbox_cmpl = NULL; 4386fcf3ce44SJohn Forte 438782527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 4388291a2b48SSukumar Swaminathan MBX_SUCCESS) { 4389fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4390fcf3ce44SJohn Forte "Unable to load exp ROM. Mailbox cmd=%x status=%x", 4391fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 4392fcf3ce44SJohn Forte 4393fcf3ce44SJohn Forte rval = 1; 4394fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 4395fcf3ce44SJohn Forte } 4396291a2b48SSukumar Swaminathan 4397fcf3ce44SJohn Forte } 4398fcf3ce44SJohn Forte 4399fcf3ce44SJohn Forte while (mb->un.varLdExpRom.progress != EROM_RSP_COPY_DONE) { 4400fcf3ce44SJohn Forte next_address = mb->un.varLdExpRom.dl_to_adr; 4401fcf3ce44SJohn Forte 4402fcf3ce44SJohn Forte bzero((void *)mb, MAILBOX_CMD_BSIZE); 4403fcf3ce44SJohn Forte 4404fcf3ce44SJohn Forte mb->mbxCommand = MBX_LOAD_EXP_ROM; 4405fcf3ce44SJohn Forte mb->un.varLdExpRom.step = EROM_CMD_COPY; 4406fcf3ce44SJohn Forte mb->un.varLdExpRom.dl_to_adr = next_address; 4407fcf3ce44SJohn Forte mb->un.varLdExpRom.progress = 0; 4408fcf3ce44SJohn Forte mb->un.varLdExpRom.un.prog_id = WakeUpParms->u1.EROM_prog_id; 440982527734SSukumar Swaminathan mbox->mbox_cmpl = NULL; 4410fcf3ce44SJohn Forte 441182527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 4412291a2b48SSukumar Swaminathan MBX_SUCCESS) { 4413fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4414fcf3ce44SJohn Forte "Unable to load exp ROM. Mailbox cmd=%x status=%x", 4415fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 4416fcf3ce44SJohn Forte 4417fcf3ce44SJohn Forte rval = 1; 4418fcf3ce44SJohn Forte 4419fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 4420fcf3ce44SJohn Forte } 4421fcf3ce44SJohn Forte } 4422fcf3ce44SJohn Forte 4423fcf3ce44SJohn Forte rval = emlxs_update_wakeup_parms(hba, WakeUpParms, WakeUpParms); 4424fcf3ce44SJohn Forte 4425fcf3ce44SJohn Forte SLI_DOWNLOAD_EXIT: 4426fcf3ce44SJohn Forte 4427fcf3ce44SJohn Forte if (mbox) { 4428fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 4429fcf3ce44SJohn Forte } 4430291a2b48SSukumar Swaminathan 4431fcf3ce44SJohn Forte return (rval); 4432fcf3ce44SJohn Forte 443382527734SSukumar Swaminathan } /* emlxs_update_exp_rom() */ 4434fcf3ce44SJohn Forte 4435fcf3ce44SJohn Forte 4436fcf3ce44SJohn Forte /* 4437fcf3ce44SJohn Forte * 4438fcf3ce44SJohn Forte * FUNCTION NAME: emlxs_start_abs_download_2mb 4439fcf3ce44SJohn Forte * 4440fcf3ce44SJohn Forte * DESCRIPTION: Perform absolute download for 2 MB flash. A incoming 4441fcf3ce44SJohn Forte * buffer may consist of more than 1 file. This function 4442fcf3ce44SJohn Forte * will parse the buffer to find all the files. 4443fcf3ce44SJohn Forte * 4444fcf3ce44SJohn Forte * 4445fcf3ce44SJohn Forte * PARAMETERS: 4446fcf3ce44SJohn Forte * 4447fcf3ce44SJohn Forte * 4448fcf3ce44SJohn Forte * RETURNS: 4449fcf3ce44SJohn Forte * 4450fcf3ce44SJohn Forte */ 4451fcf3ce44SJohn Forte /* ARGSUSED */ 4452fcf3ce44SJohn Forte static uint32_t 4453fcf3ce44SJohn Forte emlxs_start_abs_download_2mb(emlxs_hba_t *hba, caddr_t buffer, uint32_t len, 4454fcf3ce44SJohn Forte uint32_t offline, emlxs_fw_image_t *fw_image) 4455fcf3ce44SJohn Forte { 4456fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 4457fcf3ce44SJohn Forte uint32_t rval = 0; 4458fcf3ce44SJohn Forte 4459fcf3ce44SJohn Forte /* If nothing to download then quit now */ 44606a573d82SSukumar Swaminathan if (!fw_image->awc.version && 44616a573d82SSukumar Swaminathan !fw_image->dwc.version && 44626a573d82SSukumar Swaminathan !fw_image->bwc.version) { 44636a573d82SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 44646a573d82SSukumar Swaminathan "Nothing new to update. Exiting."); 4465fcf3ce44SJohn Forte return (0); 4466fcf3ce44SJohn Forte } 4467291a2b48SSukumar Swaminathan 4468fcf3ce44SJohn Forte /* 4469fcf3ce44SJohn Forte * Everything checks out, now to just do it 4470fcf3ce44SJohn Forte */ 4471fcf3ce44SJohn Forte if (offline) { 4472fcf3ce44SJohn Forte if (emlxs_offline(hba) != FC_SUCCESS) { 4473fcf3ce44SJohn Forte return (EMLXS_OFFLINE_FAILED); 4474fcf3ce44SJohn Forte } 4475291a2b48SSukumar Swaminathan 447682527734SSukumar Swaminathan if (EMLXS_SLI_HBA_RESET(hba, 1, 1, 0) != FC_SUCCESS) { 4477fcf3ce44SJohn Forte return (EMLXS_OFFLINE_FAILED); 4478fcf3ce44SJohn Forte } 4479fcf3ce44SJohn Forte } 4480291a2b48SSukumar Swaminathan 44816a573d82SSukumar Swaminathan if (fw_image->awc.version) { 4482291a2b48SSukumar Swaminathan rval = emlxs_proc_abs_2mb(hba, 44836a573d82SSukumar Swaminathan (buffer + fw_image->awc.offset), 44846a573d82SSukumar Swaminathan FILE_TYPE_AWC, 0); 4485fcf3ce44SJohn Forte 4486fcf3ce44SJohn Forte if (rval) { 4487fcf3ce44SJohn Forte goto SLI_DOWNLOAD_2MB_EXIT; 4488fcf3ce44SJohn Forte } 4489fcf3ce44SJohn Forte } 4490291a2b48SSukumar Swaminathan 44916a573d82SSukumar Swaminathan if (fw_image->bwc.version) { 4492291a2b48SSukumar Swaminathan rval = emlxs_proc_abs_2mb(hba, 44936a573d82SSukumar Swaminathan (buffer + fw_image->bwc.offset), 44946a573d82SSukumar Swaminathan FILE_TYPE_BWC, 44956a573d82SSukumar Swaminathan (fw_image->dwc.version)? ALLext:BWCext); 4496fcf3ce44SJohn Forte 4497fcf3ce44SJohn Forte if (rval) { 4498fcf3ce44SJohn Forte goto SLI_DOWNLOAD_2MB_EXIT; 4499fcf3ce44SJohn Forte } 4500fcf3ce44SJohn Forte } 4501291a2b48SSukumar Swaminathan 45026a573d82SSukumar Swaminathan if (fw_image->dwc.version) { 45036a573d82SSukumar Swaminathan rval = emlxs_proc_rel_2mb(hba, buffer, fw_image); 4504fcf3ce44SJohn Forte 45056a573d82SSukumar Swaminathan if (rval) { 45066a573d82SSukumar Swaminathan goto SLI_DOWNLOAD_2MB_EXIT; 45076a573d82SSukumar Swaminathan } 4508fcf3ce44SJohn Forte } 4509291a2b48SSukumar Swaminathan 4510fcf3ce44SJohn Forte SLI_DOWNLOAD_2MB_EXIT: 4511fcf3ce44SJohn Forte 4512fcf3ce44SJohn Forte if (offline) { 4513fcf3ce44SJohn Forte (void) emlxs_online(hba); 4514fcf3ce44SJohn Forte } 4515291a2b48SSukumar Swaminathan 4516fcf3ce44SJohn Forte return (rval); 4517fcf3ce44SJohn Forte 451882527734SSukumar Swaminathan } /* emlxs_start_abs_download_2mb() */ 4519fcf3ce44SJohn Forte 4520fcf3ce44SJohn Forte 4521fcf3ce44SJohn Forte /* 4522fcf3ce44SJohn Forte * 4523fcf3ce44SJohn Forte * FUNCTION NAME: emlxs_proc_abs_2mb 4524fcf3ce44SJohn Forte * 4525fcf3ce44SJohn Forte * DESCRIPTION: Given one of the 3 file types(awc/bwc/dwc), it will reset 4526fcf3ce44SJohn Forte * the port and download the file with sliIssueMbCommand() 4527fcf3ce44SJohn Forte * 4528fcf3ce44SJohn Forte * 4529fcf3ce44SJohn Forte * PARAMETERS: 4530fcf3ce44SJohn Forte * 4531fcf3ce44SJohn Forte * 4532fcf3ce44SJohn Forte * RETURNS: 4533fcf3ce44SJohn Forte * 4534fcf3ce44SJohn Forte */ 4535fcf3ce44SJohn Forte static uint32_t 45366a573d82SSukumar Swaminathan emlxs_proc_abs_2mb(emlxs_hba_t *hba, caddr_t EntireBuffer, 45376a573d82SSukumar Swaminathan uint32_t FileType, uint32_t extType) 4538fcf3ce44SJohn Forte { 4539fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 45406a573d82SSukumar Swaminathan PAIF_HDR AifHdr; 4541fcf3ce44SJohn Forte caddr_t Buffer = NULL; 4542fcf3ce44SJohn Forte caddr_t DataBuffer = NULL; 4543fcf3ce44SJohn Forte uint32_t *Src; 4544fcf3ce44SJohn Forte uint32_t *Dst; 4545fcf3ce44SJohn Forte MAILBOXQ *mbox; 4546fcf3ce44SJohn Forte MAILBOX *mb; 45476a573d82SSukumar Swaminathan uint32_t DlByteCount; 4548fcf3ce44SJohn Forte uint32_t rval = 0; 4549fcf3ce44SJohn Forte uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT; 45506a573d82SSukumar Swaminathan uint32_t DlToAddr; 4551fcf3ce44SJohn Forte uint32_t DlCount; 4552fcf3ce44SJohn Forte WAKE_UP_PARMS AbsWakeUpParms; 4553fcf3ce44SJohn Forte uint32_t i; 4554fcf3ce44SJohn Forte uint32_t NextAddr; 4555fcf3ce44SJohn Forte uint32_t EraseByteCount; 4556fcf3ce44SJohn Forte uint32_t AreaId; 4557fcf3ce44SJohn Forte uint32_t RspProgress = 0; 45586a573d82SSukumar Swaminathan uint32_t ParamsChg; 45596a573d82SSukumar Swaminathan 45606a573d82SSukumar Swaminathan AifHdr = (PAIF_HDR)EntireBuffer; 45616a573d82SSukumar Swaminathan DlByteCount = AifHdr->RoSize + AifHdr->RwSize; 45626a573d82SSukumar Swaminathan DlToAddr = AifHdr->ImageBase; 4563fcf3ce44SJohn Forte 4564291a2b48SSukumar Swaminathan if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT, 4565291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 4566fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4567fcf3ce44SJohn Forte "%x: Unable to allocate data buffer.", FileType); 4568fcf3ce44SJohn Forte 4569fcf3ce44SJohn Forte return (EMLXS_IMAGE_FAILED); 4570fcf3ce44SJohn Forte } 4571291a2b48SSukumar Swaminathan 4572291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 4573291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 4574fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4575fcf3ce44SJohn Forte "%x: Unable to allocate mailbox buffer.", FileType); 4576fcf3ce44SJohn Forte 4577fcf3ce44SJohn Forte kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 4578fcf3ce44SJohn Forte 4579fcf3ce44SJohn Forte return (EMLXS_IMAGE_FAILED); 4580fcf3ce44SJohn Forte } 4581291a2b48SSukumar Swaminathan 4582fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 4583fcf3ce44SJohn Forte 4584fcf3ce44SJohn Forte Buffer = EntireBuffer + sizeof (AIF_HDR); 4585fcf3ce44SJohn Forte 4586fcf3ce44SJohn Forte switch (FileType) { 4587fcf3ce44SJohn Forte case FILE_TYPE_AWC: 45886a573d82SSukumar Swaminathan ParamsChg = 0; 4589fcf3ce44SJohn Forte break; 4590fcf3ce44SJohn Forte 4591fcf3ce44SJohn Forte case FILE_TYPE_BWC: 45926a573d82SSukumar Swaminathan rval = emlxs_build_parms_2mb_bwc(hba, 4593291a2b48SSukumar Swaminathan AifHdr, extType, &AbsWakeUpParms); 4594fcf3ce44SJohn Forte 45956a573d82SSukumar Swaminathan if (rval == FALSE) { 4596fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4597fcf3ce44SJohn Forte "BWC build parms failed."); 4598fcf3ce44SJohn Forte 4599fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 4600fcf3ce44SJohn Forte 4601fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 4602fcf3ce44SJohn Forte } 46036a573d82SSukumar Swaminathan ParamsChg = 1; 4604fcf3ce44SJohn Forte break; 4605fcf3ce44SJohn Forte 4606fcf3ce44SJohn Forte default: 4607fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 4608fcf3ce44SJohn Forte "Invalid file type: %x", FileType); 4609fcf3ce44SJohn Forte 4610fcf3ce44SJohn Forte rval = EMLXS_IMAGE_BAD; 4611fcf3ce44SJohn Forte 4612fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 4613fcf3ce44SJohn Forte } 4614fcf3ce44SJohn Forte 4615fcf3ce44SJohn Forte EraseByteCount = AifHdr->Area_Size; 4616fcf3ce44SJohn Forte AreaId = AifHdr->Area_ID; 4617fcf3ce44SJohn Forte 461882527734SSukumar Swaminathan emlxs_format_load_area_cmd(mbox, 4619291a2b48SSukumar Swaminathan DlToAddr, 4620291a2b48SSukumar Swaminathan EraseByteCount, 4621291a2b48SSukumar Swaminathan ERASE_FLASH, 4622fcf3ce44SJohn Forte 0, DL_FROM_SLIM_OFFSET, AreaId, MBX_LOAD_AREA, CMD_START_ERASE); 4623fcf3ce44SJohn Forte 462482527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 4625fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4626fcf3ce44SJohn Forte "%x: Could not erase 2MB Flash: Mailbox cmd=%x status=%x", 4627fcf3ce44SJohn Forte FileType, mb->mbxCommand, mb->mbxStatus); 4628fcf3ce44SJohn Forte 4629fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 4630fcf3ce44SJohn Forte 4631fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 4632fcf3ce44SJohn Forte } 4633291a2b48SSukumar Swaminathan 4634fcf3ce44SJohn Forte while (mb->un.varLdArea.progress != RSP_ERASE_COMPLETE) { 4635fcf3ce44SJohn Forte NextAddr = mb->un.varLdArea.dl_to_adr; 4636fcf3ce44SJohn Forte 463782527734SSukumar Swaminathan emlxs_format_load_area_cmd(mbox, 4638291a2b48SSukumar Swaminathan NextAddr, 4639291a2b48SSukumar Swaminathan EraseByteCount, 4640291a2b48SSukumar Swaminathan ERASE_FLASH, 4641291a2b48SSukumar Swaminathan 0, 4642291a2b48SSukumar Swaminathan DL_FROM_SLIM_OFFSET, 4643291a2b48SSukumar Swaminathan AreaId, MBX_LOAD_AREA, CMD_CONTINUE_ERASE); 4644fcf3ce44SJohn Forte 464582527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 4646291a2b48SSukumar Swaminathan MBX_SUCCESS) { 4647fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4648291a2b48SSukumar Swaminathan "%x: Could not erase 2MB Flash2: Mailbox cmd=%x " 4649291a2b48SSukumar Swaminathan "status=%x", FileType, mb->mbxCommand, 4650291a2b48SSukumar Swaminathan mb->mbxStatus); 4651fcf3ce44SJohn Forte 4652fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 4653fcf3ce44SJohn Forte 4654fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 4655fcf3ce44SJohn Forte } 4656fcf3ce44SJohn Forte } 4657fcf3ce44SJohn Forte 4658fcf3ce44SJohn Forte while (DlByteCount) { 4659fcf3ce44SJohn Forte if (DlByteCount >= SegSize) 4660fcf3ce44SJohn Forte DlCount = SegSize; 4661fcf3ce44SJohn Forte else 4662fcf3ce44SJohn Forte DlCount = DlByteCount; 4663fcf3ce44SJohn Forte 4664fcf3ce44SJohn Forte DlByteCount -= DlCount; 4665fcf3ce44SJohn Forte 4666fcf3ce44SJohn Forte Dst = (uint32_t *)DataBuffer; 4667fcf3ce44SJohn Forte Src = (uint32_t *)Buffer; 4668fcf3ce44SJohn Forte 4669fcf3ce44SJohn Forte for (i = 0; i < (DlCount / 4); i++) { 4670fcf3ce44SJohn Forte *Dst = *Src; 4671fcf3ce44SJohn Forte Dst++; 4672fcf3ce44SJohn Forte Src++; 4673fcf3ce44SJohn Forte } 4674fcf3ce44SJohn Forte 4675fcf3ce44SJohn Forte WRITE_SLIM_COPY(hba, (uint32_t *)DataBuffer, 467682527734SSukumar Swaminathan (volatile uint32_t *)((volatile char *) 467782527734SSukumar Swaminathan hba->sli.sli3.slim_addr + sizeof (MAILBOX)), 467882527734SSukumar Swaminathan (DlCount / sizeof (uint32_t))); 4679fcf3ce44SJohn Forte 4680fcf3ce44SJohn Forte if ((RspProgress == RSP_DOWNLOAD_MORE) || (RspProgress == 0)) { 468182527734SSukumar Swaminathan emlxs_format_load_area_cmd(mbox, 4682291a2b48SSukumar Swaminathan DlToAddr, 4683291a2b48SSukumar Swaminathan DlCount, 4684291a2b48SSukumar Swaminathan PROGRAM_FLASH, 4685291a2b48SSukumar Swaminathan (DlByteCount) ? 0 : 1, 4686291a2b48SSukumar Swaminathan DL_FROM_SLIM_OFFSET, 4687291a2b48SSukumar Swaminathan AreaId, 4688291a2b48SSukumar Swaminathan MBX_LOAD_AREA, 4689fcf3ce44SJohn Forte (DlByteCount) ? CMD_DOWNLOAD : CMD_END_DOWNLOAD); 4690fcf3ce44SJohn Forte 469182527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 4692fcf3ce44SJohn Forte MBX_SUCCESS) { 4693fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 4694fcf3ce44SJohn Forte &emlxs_download_failed_msg, 4695291a2b48SSukumar Swaminathan "%x: Could not program 2MB Flash: Mailbox " 4696291a2b48SSukumar Swaminathan "cmd=%x status=%x", FileType, 4697291a2b48SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 4698fcf3ce44SJohn Forte 4699fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 4700fcf3ce44SJohn Forte 4701fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 4702fcf3ce44SJohn Forte } 4703fcf3ce44SJohn Forte } 4704291a2b48SSukumar Swaminathan 4705fcf3ce44SJohn Forte RspProgress = mb->un.varLdArea.progress; 4706fcf3ce44SJohn Forte 4707fcf3ce44SJohn Forte Buffer += DlCount; 4708fcf3ce44SJohn Forte DlToAddr += DlCount; 4709fcf3ce44SJohn Forte } 4710fcf3ce44SJohn Forte 47114baa2c25SSukumar Swaminathan #ifdef FMA_SUPPORT 471282527734SSukumar Swaminathan if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle) 47134baa2c25SSukumar Swaminathan != DDI_FM_OK) { 47144baa2c25SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 47154baa2c25SSukumar Swaminathan &emlxs_invalid_access_handle_msg, NULL); 47164baa2c25SSukumar Swaminathan 47174baa2c25SSukumar Swaminathan rval = EMLXS_IMAGE_FAILED; 47184baa2c25SSukumar Swaminathan 47194baa2c25SSukumar Swaminathan goto EXIT_ABS_DOWNLOAD; 47204baa2c25SSukumar Swaminathan } 47214baa2c25SSukumar Swaminathan #endif /* FMA_SUPPORT */ 47224baa2c25SSukumar Swaminathan 4723fcf3ce44SJohn Forte if (RspProgress != RSP_DOWNLOAD_DONE) { 4724fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4725291a2b48SSukumar Swaminathan "%x: Failed download response received. %x", FileType, 4726291a2b48SSukumar Swaminathan RspProgress); 4727fcf3ce44SJohn Forte 4728fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 4729fcf3ce44SJohn Forte 4730fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 4731fcf3ce44SJohn Forte } 4732291a2b48SSukumar Swaminathan 4733fcf3ce44SJohn Forte if (ParamsChg) { 4734fcf3ce44SJohn Forte if (emlxs_update_wakeup_parms(hba, &AbsWakeUpParms, 4735fcf3ce44SJohn Forte &AbsWakeUpParms)) { 4736fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4737fcf3ce44SJohn Forte "%x: Unable to update parms.", FileType); 4738fcf3ce44SJohn Forte 4739fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 4740fcf3ce44SJohn Forte } 4741fcf3ce44SJohn Forte } 4742291a2b48SSukumar Swaminathan 4743fcf3ce44SJohn Forte EXIT_ABS_DOWNLOAD: 4744fcf3ce44SJohn Forte 4745fcf3ce44SJohn Forte if (DataBuffer) { 4746fcf3ce44SJohn Forte kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 4747fcf3ce44SJohn Forte } 4748291a2b48SSukumar Swaminathan 4749fcf3ce44SJohn Forte if (mbox) { 4750fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 4751fcf3ce44SJohn Forte } 4752291a2b48SSukumar Swaminathan 4753fcf3ce44SJohn Forte return (rval); 4754fcf3ce44SJohn Forte 475582527734SSukumar Swaminathan } /* emlxs_proc_abs_2mb() */ 4756fcf3ce44SJohn Forte 4757fcf3ce44SJohn Forte 4758fcf3ce44SJohn Forte static void 475982527734SSukumar Swaminathan emlxs_format_load_area_cmd(MAILBOXQ * mbq, 4760291a2b48SSukumar Swaminathan uint32_t Base, 4761291a2b48SSukumar Swaminathan uint32_t DlByteCount, 4762291a2b48SSukumar Swaminathan uint32_t Function, 4763291a2b48SSukumar Swaminathan uint32_t Complete, 4764291a2b48SSukumar Swaminathan uint32_t DataOffset, uint32_t AreaId, uint8_t MbxCmd, uint32_t StepCmd) 4765fcf3ce44SJohn Forte { 476682527734SSukumar Swaminathan MAILBOX *mb = (MAILBOX *)mbq; 476782527734SSukumar Swaminathan 4768fcf3ce44SJohn Forte bzero((void *)mb, MAILBOX_CMD_BSIZE); 4769fcf3ce44SJohn Forte 4770fcf3ce44SJohn Forte mb->mbxCommand = MbxCmd; 4771fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 4772fcf3ce44SJohn Forte mb->un.varLdArea.update_flash = 1; 4773fcf3ce44SJohn Forte mb->un.varLdArea.erase_or_prog = Function; 4774fcf3ce44SJohn Forte mb->un.varLdArea.dl_to_adr = Base; 4775fcf3ce44SJohn Forte mb->un.varLdArea.dl_len = DlByteCount; 4776fcf3ce44SJohn Forte mb->un.varLdArea.load_cmplt = Complete; 4777fcf3ce44SJohn Forte mb->un.varLdArea.method = DL_FROM_SLIM; 4778fcf3ce44SJohn Forte mb->un.varLdArea.area_id = AreaId; 4779fcf3ce44SJohn Forte mb->un.varLdArea.step = StepCmd; 4780fcf3ce44SJohn Forte mb->un.varLdArea.un.dl_from_slim_offset = DataOffset; 478182527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 4782fcf3ce44SJohn Forte 478382527734SSukumar Swaminathan } /* emlxs_format_load_area_cmd() */ 4784fcf3ce44SJohn Forte 4785fcf3ce44SJohn Forte 4786291a2b48SSukumar Swaminathan /* ARGSUSED */ 4787fcf3ce44SJohn Forte static uint32_t 4788291a2b48SSukumar Swaminathan emlxs_build_parms_2mb_bwc(emlxs_hba_t *hba, 4789291a2b48SSukumar Swaminathan PAIF_HDR AifHdr, uint32_t extType, PWAKE_UP_PARMS AbsWakeUpParms) 4790fcf3ce44SJohn Forte { 4791fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 4792fcf3ce44SJohn Forte uint32_t pId[2]; 4793fcf3ce44SJohn Forte uint32_t returnStat; 4794fcf3ce44SJohn Forte 4795fcf3ce44SJohn Forte /* Read wakeup paramters */ 4796fcf3ce44SJohn Forte if (emlxs_read_wakeup_parms(hba, AbsWakeUpParms, 0) == 47976a573d82SSukumar Swaminathan (uint32_t)CFG_DATA_NO_REGION) { 4798fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4799fcf3ce44SJohn Forte "Unable to get BWC parameters."); 4800fcf3ce44SJohn Forte return (FALSE); 4801fcf3ce44SJohn Forte } 4802291a2b48SSukumar Swaminathan 4803fcf3ce44SJohn Forte pId[0] = AifHdr->AVersion; 4804fcf3ce44SJohn Forte pId[1] = 0; 4805fcf3ce44SJohn Forte 4806fcf3ce44SJohn Forte if (extType == BWCext) { 4807fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_wd[0] = pId[0]; 4808fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_wd[1] = pId[1]; 4809fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 4810fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 4811291a2b48SSukumar Swaminathan } 4812291a2b48SSukumar Swaminathan 4813291a2b48SSukumar Swaminathan else if (extType == ALLext) { 4814fcf3ce44SJohn Forte if (!AbsWakeUpParms->u0.boot_bios_wd[0]) { 4815fcf3ce44SJohn Forte /* case of EROM inactive */ 4816fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 4817fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 4818fcf3ce44SJohn Forte } else { 4819fcf3ce44SJohn Forte /* case of EROM active */ 4820fcf3ce44SJohn Forte if (AbsWakeUpParms->u0.boot_bios_wd[0] == pId[0]) { 4821fcf3ce44SJohn Forte /* same ID */ 4822fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_wd[0] = pId[0]; 4823fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_wd[1] = pId[1]; 4824fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 4825fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 4826fcf3ce44SJohn Forte } else { 4827fcf3ce44SJohn Forte /* different ID */ 4828fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 4829fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 4830fcf3ce44SJohn Forte 4831291a2b48SSukumar Swaminathan returnStat = 4832291a2b48SSukumar Swaminathan emlxs_update_exp_rom(hba, AbsWakeUpParms); 4833fcf3ce44SJohn Forte 4834fcf3ce44SJohn Forte if (returnStat) { 4835fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_wd[0] = 4836fcf3ce44SJohn Forte pId[0]; 4837fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_wd[1] = 4838fcf3ce44SJohn Forte pId[1]; 4839fcf3ce44SJohn Forte } 4840fcf3ce44SJohn Forte } 4841fcf3ce44SJohn Forte } 4842fcf3ce44SJohn Forte } 4843291a2b48SSukumar Swaminathan 4844fcf3ce44SJohn Forte return (TRUE); 4845fcf3ce44SJohn Forte 484682527734SSukumar Swaminathan } /* emlxs_build_parms_2mb_bwc() */ 4847fcf3ce44SJohn Forte 4848fcf3ce44SJohn Forte 4849fcf3ce44SJohn Forte extern uint32_t 4850fcf3ce44SJohn Forte emlxs_get_max_sram(emlxs_hba_t *hba, uint32_t *MaxRbusSize, 4851fcf3ce44SJohn Forte uint32_t *MaxIbusSize) 4852fcf3ce44SJohn Forte { 4853fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 4854fcf3ce44SJohn Forte MAILBOXQ *mbox; 4855fcf3ce44SJohn Forte MAILBOX *mb; 4856fcf3ce44SJohn Forte uint32_t *Uptr; 4857fcf3ce44SJohn Forte uint32_t rval = 0; 4858fcf3ce44SJohn Forte 48596a573d82SSukumar Swaminathan if (MaxRbusSize) { 48606a573d82SSukumar Swaminathan *MaxRbusSize = 0; 48616a573d82SSukumar Swaminathan } 48626a573d82SSukumar Swaminathan 48636a573d82SSukumar Swaminathan if (MaxIbusSize) { 48646a573d82SSukumar Swaminathan *MaxIbusSize = 0; 48656a573d82SSukumar Swaminathan } 48666a573d82SSukumar Swaminathan 4867291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 4868291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 4869fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4870fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 4871fcf3ce44SJohn Forte 4872fcf3ce44SJohn Forte return (1); 4873fcf3ce44SJohn Forte } 4874291a2b48SSukumar Swaminathan 4875fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 4876fcf3ce44SJohn Forte 487782527734SSukumar Swaminathan emlxs_format_dump(hba, mbox, DMP_MEM_REG, 0, 2, MAX_RBUS_SRAM_SIZE_ADR); 4878fcf3ce44SJohn Forte 487982527734SSukumar Swaminathan if ((rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0)) != 4880291a2b48SSukumar Swaminathan MBX_SUCCESS) { 4881fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4882fcf3ce44SJohn Forte "Unable to get SRAM size: Mailbox cmd=%x status=%x", 4883fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 4884fcf3ce44SJohn Forte 4885fcf3ce44SJohn Forte rval = 1; 4886fcf3ce44SJohn Forte 4887fcf3ce44SJohn Forte goto Exit_Function; 4888fcf3ce44SJohn Forte } 4889291a2b48SSukumar Swaminathan 489082527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 489182527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle, 0, 489282527734SSukumar Swaminathan hba->sli.sli4.dump_region.size, DDI_DMA_SYNC_FORKERNEL); 489382527734SSukumar Swaminathan Uptr = (uint32_t *)hba->sli.sli4.dump_region.virt; 489482527734SSukumar Swaminathan } else { 489582527734SSukumar Swaminathan Uptr = (uint32_t *)&mb->un.varDmp.resp_offset; 489682527734SSukumar Swaminathan } 4897fcf3ce44SJohn Forte 48986a573d82SSukumar Swaminathan if (MaxRbusSize) { 48996a573d82SSukumar Swaminathan *MaxRbusSize = Uptr[0]; 49006a573d82SSukumar Swaminathan } 49016a573d82SSukumar Swaminathan 49026a573d82SSukumar Swaminathan if (MaxIbusSize) { 49036a573d82SSukumar Swaminathan *MaxIbusSize = Uptr[1]; 49046a573d82SSukumar Swaminathan } 4905fcf3ce44SJohn Forte 4906fcf3ce44SJohn Forte Exit_Function: 4907fcf3ce44SJohn Forte 4908fcf3ce44SJohn Forte if (mbox) { 4909fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 4910fcf3ce44SJohn Forte } 4911291a2b48SSukumar Swaminathan 4912b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 4913b3660a96SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 4914b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, 4915b3660a96SSukumar Swaminathan hba->sli.sli4.dump_region.dma_handle) != DDI_FM_OK) { 4916b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 4917b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 4918b3660a96SSukumar Swaminathan "emlxs_get_max_sram: hdl=%p", 4919b3660a96SSukumar Swaminathan hba->sli.sli4.dump_region.dma_handle); 4920b3660a96SSukumar Swaminathan rval = 1; 4921b3660a96SSukumar Swaminathan } 4922b3660a96SSukumar Swaminathan } 4923b3660a96SSukumar Swaminathan #endif /* FMA_SUPPORT */ 4924b3660a96SSukumar Swaminathan 4925fcf3ce44SJohn Forte return (rval); 4926fcf3ce44SJohn Forte 492782527734SSukumar Swaminathan } /* emlxs_get_max_sram() */ 4928fcf3ce44SJohn Forte 4929fcf3ce44SJohn Forte 4930fcf3ce44SJohn Forte static uint32_t 4931fcf3ce44SJohn Forte emlxs_kern_check(emlxs_hba_t *hba, uint32_t version) 4932fcf3ce44SJohn Forte { 4933fcf3ce44SJohn Forte uint8_t *ptr; 4934fcf3ce44SJohn Forte uint8_t ver; 4935fcf3ce44SJohn Forte 4936fcf3ce44SJohn Forte ver = version & 0xff; 4937fcf3ce44SJohn Forte ptr = hba->model_info.pt_FF; 4938fcf3ce44SJohn Forte 4939fcf3ce44SJohn Forte while (*ptr) { 4940fcf3ce44SJohn Forte if (*ptr++ == ver) { 4941fcf3ce44SJohn Forte return (1); 4942fcf3ce44SJohn Forte } 4943fcf3ce44SJohn Forte } 4944fcf3ce44SJohn Forte 4945fcf3ce44SJohn Forte return (0); 4946fcf3ce44SJohn Forte 494782527734SSukumar Swaminathan } /* emlxs_kern_check() */ 4948fcf3ce44SJohn Forte 4949fcf3ce44SJohn Forte static uint32_t 4950fcf3ce44SJohn Forte emlxs_stub_check(emlxs_hba_t *hba, uint32_t version) 4951fcf3ce44SJohn Forte { 4952fcf3ce44SJohn Forte uint8_t *ptr; 4953fcf3ce44SJohn Forte uint8_t ver; 4954fcf3ce44SJohn Forte 4955fcf3ce44SJohn Forte ver = version & 0xff; 4956fcf3ce44SJohn Forte ptr = hba->model_info.pt_2; 4957fcf3ce44SJohn Forte 4958fcf3ce44SJohn Forte while (*ptr) { 4959fcf3ce44SJohn Forte if (*ptr++ == ver) { 4960fcf3ce44SJohn Forte return (1); 4961fcf3ce44SJohn Forte } 4962fcf3ce44SJohn Forte } 4963fcf3ce44SJohn Forte 4964fcf3ce44SJohn Forte return (0); 4965fcf3ce44SJohn Forte 496682527734SSukumar Swaminathan } /* emlxs_stub_check() */ 4967fcf3ce44SJohn Forte 4968fcf3ce44SJohn Forte static uint32_t 4969fcf3ce44SJohn Forte emlxs_bios_check(emlxs_hba_t *hba, uint32_t version) 4970fcf3ce44SJohn Forte { 4971fcf3ce44SJohn Forte uint8_t *ptr; 4972fcf3ce44SJohn Forte uint8_t ver; 4973fcf3ce44SJohn Forte 4974fcf3ce44SJohn Forte ver = version & 0xff; 4975fcf3ce44SJohn Forte ptr = hba->model_info.pt_3; 4976fcf3ce44SJohn Forte 4977fcf3ce44SJohn Forte while (*ptr) { 4978fcf3ce44SJohn Forte if (*ptr++ == ver) { 4979fcf3ce44SJohn Forte return (1); 4980fcf3ce44SJohn Forte } 4981fcf3ce44SJohn Forte } 4982fcf3ce44SJohn Forte 4983fcf3ce44SJohn Forte return (0); 4984fcf3ce44SJohn Forte 498582527734SSukumar Swaminathan } /* emlxs_bios_check() */ 4986fcf3ce44SJohn Forte 4987fcf3ce44SJohn Forte static uint32_t 4988fcf3ce44SJohn Forte emlxs_sli1_check(emlxs_hba_t *hba, uint32_t version) 4989fcf3ce44SJohn Forte { 4990fcf3ce44SJohn Forte uint8_t *ptr; 4991fcf3ce44SJohn Forte uint8_t ver; 4992fcf3ce44SJohn Forte 4993fcf3ce44SJohn Forte ver = version & 0xff; 4994fcf3ce44SJohn Forte ptr = hba->model_info.pt_6; 4995fcf3ce44SJohn Forte 4996fcf3ce44SJohn Forte while (*ptr) { 4997fcf3ce44SJohn Forte if (*ptr++ == ver) { 4998fcf3ce44SJohn Forte return (1); 4999fcf3ce44SJohn Forte } 5000fcf3ce44SJohn Forte } 5001fcf3ce44SJohn Forte 5002fcf3ce44SJohn Forte return (0); 5003fcf3ce44SJohn Forte 500482527734SSukumar Swaminathan } /* emlxs_sli1_check() */ 5005fcf3ce44SJohn Forte 5006fcf3ce44SJohn Forte static uint32_t 5007fcf3ce44SJohn Forte emlxs_sli2_check(emlxs_hba_t *hba, uint32_t version) 5008fcf3ce44SJohn Forte { 5009fcf3ce44SJohn Forte uint8_t *ptr; 5010fcf3ce44SJohn Forte uint8_t ver; 5011fcf3ce44SJohn Forte 5012fcf3ce44SJohn Forte ver = version & 0xff; 5013fcf3ce44SJohn Forte ptr = hba->model_info.pt_7; 5014fcf3ce44SJohn Forte 5015fcf3ce44SJohn Forte while (*ptr) { 5016fcf3ce44SJohn Forte if (*ptr++ == ver) { 5017fcf3ce44SJohn Forte return (1); 5018fcf3ce44SJohn Forte } 5019fcf3ce44SJohn Forte } 5020fcf3ce44SJohn Forte 5021fcf3ce44SJohn Forte return (0); 5022fcf3ce44SJohn Forte 502382527734SSukumar Swaminathan } /* emlxs_sli2_check() */ 5024fcf3ce44SJohn Forte 5025fcf3ce44SJohn Forte static uint32_t 5026fcf3ce44SJohn Forte emlxs_sli3_check(emlxs_hba_t *hba, uint32_t version) 5027fcf3ce44SJohn Forte { 5028fcf3ce44SJohn Forte uint8_t *ptr; 5029fcf3ce44SJohn Forte uint8_t ver; 5030fcf3ce44SJohn Forte 5031fcf3ce44SJohn Forte ver = version & 0xff; 5032fcf3ce44SJohn Forte ptr = hba->model_info.pt_B; 5033fcf3ce44SJohn Forte 5034fcf3ce44SJohn Forte while (*ptr) { 5035fcf3ce44SJohn Forte if (*ptr++ == ver) { 5036fcf3ce44SJohn Forte return (1); 5037fcf3ce44SJohn Forte } 5038fcf3ce44SJohn Forte } 5039fcf3ce44SJohn Forte 5040fcf3ce44SJohn Forte return (0); 5041fcf3ce44SJohn Forte 504282527734SSukumar Swaminathan } /* emlxs_sli3_check() */ 5043fcf3ce44SJohn Forte 5044fcf3ce44SJohn Forte 5045fcf3ce44SJohn Forte static uint32_t 5046fcf3ce44SJohn Forte emlxs_sli4_check(emlxs_hba_t *hba, uint32_t version) 5047fcf3ce44SJohn Forte { 5048fcf3ce44SJohn Forte uint8_t *ptr; 5049fcf3ce44SJohn Forte uint8_t ver; 5050fcf3ce44SJohn Forte 5051fcf3ce44SJohn Forte ver = version & 0xff; 5052fcf3ce44SJohn Forte ptr = hba->model_info.pt_E; 5053fcf3ce44SJohn Forte 5054fcf3ce44SJohn Forte while (*ptr) { 5055fcf3ce44SJohn Forte if (*ptr++ == ver) { 5056fcf3ce44SJohn Forte return (1); 5057fcf3ce44SJohn Forte } 5058fcf3ce44SJohn Forte } 5059fcf3ce44SJohn Forte 5060fcf3ce44SJohn Forte return (0); 5061fcf3ce44SJohn Forte 506282527734SSukumar Swaminathan } /* emlxs_sli4_check() */ 5063fcf3ce44SJohn Forte 5064fcf3ce44SJohn Forte 5065fcf3ce44SJohn Forte static uint32_t 5066fcf3ce44SJohn Forte emlxs_sbus_fcode_check(emlxs_hba_t *hba, uint32_t version) 5067fcf3ce44SJohn Forte { 5068fcf3ce44SJohn Forte uint8_t *ptr; 5069fcf3ce44SJohn Forte uint8_t ver; 5070fcf3ce44SJohn Forte 5071fcf3ce44SJohn Forte ver = version & 0xff; 5072fcf3ce44SJohn Forte ptr = hba->model_info.pt_A; 5073fcf3ce44SJohn Forte 5074fcf3ce44SJohn Forte while (*ptr) { 5075fcf3ce44SJohn Forte if (*ptr++ == ver) { 5076fcf3ce44SJohn Forte return (1); 5077fcf3ce44SJohn Forte } 5078fcf3ce44SJohn Forte } 5079fcf3ce44SJohn Forte 5080fcf3ce44SJohn Forte return (0); 5081fcf3ce44SJohn Forte 508282527734SSukumar Swaminathan } /* emlxs_sbus_fcode_check() */ 5083fcf3ce44SJohn Forte 5084*a9800bebSGarrett D'Amore 5085fcf3ce44SJohn Forte static uint32_t 5086fcf3ce44SJohn Forte emlxs_type_check(uint32_t type) 5087fcf3ce44SJohn Forte { 5088fcf3ce44SJohn Forte if (type == 0xff) { 5089fcf3ce44SJohn Forte return (KERNEL_CODE); 5090fcf3ce44SJohn Forte } 5091291a2b48SSukumar Swaminathan 5092fcf3ce44SJohn Forte if (type >= MAX_PROG_TYPES) { 5093fcf3ce44SJohn Forte return (RESERVED_D); 5094fcf3ce44SJohn Forte } 5095291a2b48SSukumar Swaminathan 5096fcf3ce44SJohn Forte return (type); 5097fcf3ce44SJohn Forte 509882527734SSukumar Swaminathan } /* emlxs_type_check() */ 5099fcf3ce44SJohn Forte 5100fcf3ce44SJohn Forte 5101291a2b48SSukumar Swaminathan extern int32_t 5102fcf3ce44SJohn Forte emlxs_boot_code_disable(emlxs_hba_t *hba) 5103fcf3ce44SJohn Forte { 5104fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 5105fcf3ce44SJohn Forte PROG_ID Id; 5106fcf3ce44SJohn Forte emlxs_vpd_t *vpd; 5107fcf3ce44SJohn Forte 5108fcf3ce44SJohn Forte vpd = &VPD; 5109fcf3ce44SJohn Forte 5110*a9800bebSGarrett D'Amore if ((hba->model_info.chip == EMLXS_BE2_CHIP) || 5111*a9800bebSGarrett D'Amore (hba->model_info.chip == EMLXS_BE3_CHIP)) { 5112fe199829SSukumar Swaminathan return (EMLXS_OP_NOT_SUP); 5113fe199829SSukumar Swaminathan } 5114fe199829SSukumar Swaminathan 5115fcf3ce44SJohn Forte if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 0)) { 5116fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, 5117fcf3ce44SJohn Forte "emlxs_boot_code_disable: Unable to read wake up parms."); 5118fcf3ce44SJohn Forte 5119291a2b48SSukumar Swaminathan return (FC_FAILURE); 5120fcf3ce44SJohn Forte } 5121291a2b48SSukumar Swaminathan 5122fcf3ce44SJohn Forte /* Check if boot code is already disabled */ 5123fcf3ce44SJohn Forte if (hba->wakeup_parms.u0.boot_bios_wd[0] == 0) { 5124fcf3ce44SJohn Forte return (FC_SUCCESS); 5125fcf3ce44SJohn Forte } 5126291a2b48SSukumar Swaminathan 5127fcf3ce44SJohn Forte /* Make sure EROM entry has copy of boot bios entry */ 5128fcf3ce44SJohn Forte if (!(hba->model_info.chip & 5129fcf3ce44SJohn Forte (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP)) && 5130fcf3ce44SJohn Forte (hba->wakeup_parms.u0.boot_bios_wd[0] != 5131fcf3ce44SJohn Forte hba->wakeup_parms.u1.EROM_prog_wd[0]) && 5132fcf3ce44SJohn Forte (hba->wakeup_parms.u0.boot_bios_wd[1] != 5133fcf3ce44SJohn Forte hba->wakeup_parms.u1.EROM_prog_wd[1])) { 5134fcf3ce44SJohn Forte (void) emlxs_update_boot_wakeup_parms(hba, &hba->wakeup_parms, 5135fcf3ce44SJohn Forte &hba->wakeup_parms.u0.boot_bios_id, 1); 5136fcf3ce44SJohn Forte } 5137291a2b48SSukumar Swaminathan 5138fcf3ce44SJohn Forte /* Update the bios id with a zero id */ 5139fcf3ce44SJohn Forte /* Don't load the EROM this time */ 5140fcf3ce44SJohn Forte bzero(&Id, sizeof (PROG_ID)); 5141fcf3ce44SJohn Forte (void) emlxs_update_boot_wakeup_parms(hba, &hba->wakeup_parms, &Id, 0); 5142fcf3ce44SJohn Forte 5143fcf3ce44SJohn Forte /* Now read the parms again to verify */ 5144fcf3ce44SJohn Forte (void) emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1); 5145fcf3ce44SJohn Forte emlxs_decode_version(hba->wakeup_parms.u0.boot_bios_wd[0], 5146fcf3ce44SJohn Forte vpd->boot_version); 5147fcf3ce44SJohn Forte /* (void) strcpy(vpd->fcode_version, vpd->boot_version); */ 5148fcf3ce44SJohn Forte 5149fcf3ce44SJohn Forte /* Return the result */ 5150291a2b48SSukumar Swaminathan return ((hba->wakeup_parms.u0.boot_bios_wd[0] == 0) ? 5151291a2b48SSukumar Swaminathan FC_SUCCESS : FC_FAILURE); 5152fcf3ce44SJohn Forte 515382527734SSukumar Swaminathan } /* emlxs_boot_code_disable() */ 5154fcf3ce44SJohn Forte 5155fcf3ce44SJohn Forte 5156291a2b48SSukumar Swaminathan extern int32_t 5157fcf3ce44SJohn Forte emlxs_boot_code_enable(emlxs_hba_t *hba) 5158fcf3ce44SJohn Forte { 5159fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 5160fcf3ce44SJohn Forte emlxs_vpd_t *vpd; 5161fcf3ce44SJohn Forte PROG_ID load_list[MAX_LOAD_ENTRY]; 5162fcf3ce44SJohn Forte uint32_t i; 51636a573d82SSukumar Swaminathan uint32_t count; 5164fcf3ce44SJohn Forte 5165fcf3ce44SJohn Forte vpd = &VPD; 5166fcf3ce44SJohn Forte 5167*a9800bebSGarrett D'Amore if ((hba->model_info.chip == EMLXS_BE2_CHIP) || 5168*a9800bebSGarrett D'Amore (hba->model_info.chip == EMLXS_BE3_CHIP)) { 5169fe199829SSukumar Swaminathan return (FC_SUCCESS); 5170fe199829SSukumar Swaminathan } 5171fe199829SSukumar Swaminathan 5172fcf3ce44SJohn Forte /* Read the wakeup parms */ 5173fcf3ce44SJohn Forte if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 0)) { 5174fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, 5175fcf3ce44SJohn Forte "emlxs_boot_code_enable: Unable to read wake up parms."); 5176fcf3ce44SJohn Forte 5177291a2b48SSukumar Swaminathan return (FC_FAILURE); 5178fcf3ce44SJohn Forte } 5179291a2b48SSukumar Swaminathan 5180fcf3ce44SJohn Forte /* Check if boot code is already enabled */ 5181fcf3ce44SJohn Forte if (hba->wakeup_parms.u0.boot_bios_id.Type == BOOT_BIOS) { 5182fcf3ce44SJohn Forte return (FC_SUCCESS); 5183fcf3ce44SJohn Forte } 5184291a2b48SSukumar Swaminathan 5185fcf3ce44SJohn Forte if (!(hba->model_info.chip & 5186fcf3ce44SJohn Forte (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 5187fcf3ce44SJohn Forte if (hba->wakeup_parms.u1.EROM_prog_id.Type != BOOT_BIOS) { 5188fcf3ce44SJohn Forte return (EMLXS_NO_BOOT_CODE); 5189fcf3ce44SJohn Forte } 5190291a2b48SSukumar Swaminathan 5191fcf3ce44SJohn Forte /* Update the parms with the boot image id */ 5192fcf3ce44SJohn Forte /* Don't load the EROM this time */ 5193fcf3ce44SJohn Forte (void) emlxs_update_boot_wakeup_parms(hba, &hba->wakeup_parms, 5194fcf3ce44SJohn Forte &hba->wakeup_parms.u1.EROM_prog_id, 0); 5195fcf3ce44SJohn Forte } else { /* (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP) */ 5196291a2b48SSukumar Swaminathan 51976a573d82SSukumar Swaminathan count = emlxs_get_load_list(hba, load_list); 51986a573d82SSukumar Swaminathan 51996a573d82SSukumar Swaminathan if (!count) { 5200291a2b48SSukumar Swaminathan return (FC_FAILURE); 5201fcf3ce44SJohn Forte } 5202291a2b48SSukumar Swaminathan 5203fcf3ce44SJohn Forte /* Scan load list for a boot image */ 52046a573d82SSukumar Swaminathan for (i = 0; i < count; i++) { 5205fcf3ce44SJohn Forte if (load_list[i].Type == BOOT_BIOS) { 5206fcf3ce44SJohn Forte /* Update the parms with the boot image id */ 5207fcf3ce44SJohn Forte /* Don't load the EROM this time */ 5208fcf3ce44SJohn Forte (void) emlxs_update_boot_wakeup_parms(hba, 5209fcf3ce44SJohn Forte &hba->wakeup_parms, &load_list[i], 0); 5210fcf3ce44SJohn Forte 5211fcf3ce44SJohn Forte break; 5212fcf3ce44SJohn Forte } 5213fcf3ce44SJohn Forte } 5214fcf3ce44SJohn Forte 52156a573d82SSukumar Swaminathan if (i == count) { 5216fcf3ce44SJohn Forte return (EMLXS_NO_BOOT_CODE); 5217fcf3ce44SJohn Forte } 5218fcf3ce44SJohn Forte } 5219fcf3ce44SJohn Forte 5220fcf3ce44SJohn Forte /* Now read the parms again to verify */ 5221fcf3ce44SJohn Forte (void) emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1); 5222fcf3ce44SJohn Forte emlxs_decode_version(hba->wakeup_parms.u0.boot_bios_wd[0], 5223fcf3ce44SJohn Forte vpd->boot_version); 5224291a2b48SSukumar Swaminathan /* (void) strcpy(vpd->fcode_version, vpd->boot_version); */ 5225fcf3ce44SJohn Forte 5226fcf3ce44SJohn Forte /* return the result */ 5227291a2b48SSukumar Swaminathan return ((hba->wakeup_parms.u0.boot_bios_wd[0] != 0) ? 5228291a2b48SSukumar Swaminathan FC_SUCCESS : FC_FAILURE); 5229fcf3ce44SJohn Forte 523082527734SSukumar Swaminathan } /* emlxs_boot_code_enable() */ 5231fcf3ce44SJohn Forte 5232fcf3ce44SJohn Forte 5233fcf3ce44SJohn Forte 5234291a2b48SSukumar Swaminathan extern int32_t 5235fcf3ce44SJohn Forte emlxs_boot_code_state(emlxs_hba_t *hba) 5236fcf3ce44SJohn Forte { 5237fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 5238fcf3ce44SJohn Forte 5239*a9800bebSGarrett D'Amore if ((hba->model_info.chip == EMLXS_BE2_CHIP) || 5240*a9800bebSGarrett D'Amore (hba->model_info.chip == EMLXS_BE3_CHIP)) { 5241fe199829SSukumar Swaminathan return (FC_SUCCESS); 5242fe199829SSukumar Swaminathan } 5243fe199829SSukumar Swaminathan 5244fcf3ce44SJohn Forte /* Read the wakeup parms */ 5245fcf3ce44SJohn Forte if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1)) { 5246fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, 5247fcf3ce44SJohn Forte "emlxs_boot_code_state: Unable to read wake up parms."); 5248fcf3ce44SJohn Forte 5249291a2b48SSukumar Swaminathan return (FC_FAILURE); 5250fcf3ce44SJohn Forte } 5251291a2b48SSukumar Swaminathan 5252fcf3ce44SJohn Forte /* return the result */ 5253291a2b48SSukumar Swaminathan return ((hba->wakeup_parms.u0.boot_bios_wd[0] != 0) ? 5254291a2b48SSukumar Swaminathan FC_SUCCESS : FC_FAILURE); 5255fcf3ce44SJohn Forte 525682527734SSukumar Swaminathan } /* emlxs_boot_code_state() */ 5257