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 /* 23291a2b48SSukumar Swaminathan * Copyright 2009 Emulex. All rights reserved. 24*82527734SSukumar Swaminathan * Use is subject to license terms. 25fcf3ce44SJohn Forte */ 26fcf3ce44SJohn Forte 27*82527734SSukumar 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); 36*82527734SSukumar 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, 41291a2b48SSukumar Swaminathan uint32_t BufferSize, PAIF_HDR AifHeader, 42291a2b48SSukumar Swaminathan int32_t DwcFile); 43291a2b48SSukumar Swaminathan static uint32_t emlxs_validate_image(emlxs_hba_t *hba, caddr_t Buffer, 44291a2b48SSukumar Swaminathan uint32_t Size, emlxs_fw_image_t *fw_image); 45*82527734SSukumar Swaminathan static void emlxs_format_dump(emlxs_hba_t *hba, MAILBOXQ *mbq, 46*82527734SSukumar Swaminathan uint32_t Type, uint32_t RegionId, uint32_t WordCnt, 47*82527734SSukumar Swaminathan uint32_t BaseAddr); 48291a2b48SSukumar Swaminathan static uint32_t emlxs_start_abs_download(emlxs_hba_t *hba, PAIF_HDR AifHdr, 49291a2b48SSukumar Swaminathan caddr_t Buffer, PWAKE_UP_PARMS WakeUpParms, 50291a2b48SSukumar Swaminathan uint32_t MaxRbusSramSize, uint32_t MaxIbusSramSize, 51291a2b48SSukumar Swaminathan PWAKE_UP_PARMS AbsWakeUpParms, int32_t DwcFile); 52291a2b48SSukumar Swaminathan static uint32_t emlxs_start_abs_download_2mb(emlxs_hba_t *hba, caddr_t buffer, 53291a2b48SSukumar Swaminathan uint32_t len, uint32_t offline, 54291a2b48SSukumar Swaminathan emlxs_fw_image_t *fw_image); 55291a2b48SSukumar Swaminathan static uint32_t emlxs_proc_abs_2mb(emlxs_hba_t *hba, PAIF_HDR AifHdr, 56291a2b48SSukumar Swaminathan caddr_t EntireBuffer, uint32_t FileType, 57291a2b48SSukumar Swaminathan uint32_t BWCflag, uint32_t extType); 58*82527734SSukumar Swaminathan static void emlxs_format_load_area_cmd(MAILBOXQ *mbq, uint32_t Base, 59291a2b48SSukumar Swaminathan uint32_t DlByteCount, uint32_t Function, 60291a2b48SSukumar Swaminathan uint32_t Complete, uint32_t DataOffset, uint32_t AreaId, 61291a2b48SSukumar Swaminathan uint8_t MbxCmd, uint32_t StepCmd); 62291a2b48SSukumar Swaminathan static uint32_t emlxs_build_parms_2mb_bwc(emlxs_hba_t *hba, PAIF_HDR AifHdr, 63291a2b48SSukumar Swaminathan uint32_t extType, PWAKE_UP_PARMS AbsWakeUpParms); 64291a2b48SSukumar Swaminathan static uint32_t emlxs_build_parms_2mb_dwc(emlxs_hba_t *hba, caddr_t Buffer, 65291a2b48SSukumar Swaminathan uint32_t BufferSize, PAIF_HDR AifHeader, 66291a2b48SSukumar Swaminathan PWAKE_UP_PARMS AbsWakeUpParms, uint32_t BWCflag, 67291a2b48SSukumar Swaminathan uint32_t extType, uint32_t *numBootImage); 68291a2b48SSukumar Swaminathan static uint32_t emlxs_update_exp_rom(emlxs_hba_t *hba, 69291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms); 70291a2b48SSukumar Swaminathan extern uint32_t emlxs_get_max_sram(emlxs_hba_t *hba, uint32_t *MaxRbusSize, 71291a2b48SSukumar Swaminathan uint32_t *MaxIbusSize); 72*82527734SSukumar Swaminathan static void emlxs_format_prog_flash(MAILBOXQ *mbq, uint32_t Base, 73291a2b48SSukumar Swaminathan uint32_t DlByteCount, uint32_t Function, 74291a2b48SSukumar Swaminathan uint32_t Complete, uint32_t BdeAddress, 75291a2b48SSukumar Swaminathan uint32_t BdeSize, PROG_ID *ProgId); 76*82527734SSukumar Swaminathan static void emlxs_format_update_parms(MAILBOXQ *mbq, 77291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms); 78*82527734SSukumar Swaminathan static void emlxs_format_update_pci_cfg(emlxs_hba_t *hba, MAILBOXQ *mbq, 79291a2b48SSukumar Swaminathan uint32_t region_id, uint32_t size); 80291a2b48SSukumar Swaminathan static uint32_t emlxs_update_wakeup_parms(emlxs_hba_t *hba, 81291a2b48SSukumar Swaminathan PWAKE_UP_PARMS AbsWakeUpParms, 82291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms); 83291a2b48SSukumar Swaminathan static uint32_t emlxs_update_boot_wakeup_parms(emlxs_hba_t *hba, 84291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, PROG_ID *id, 85291a2b48SSukumar Swaminathan uint32_t proc_erom); 86291a2b48SSukumar Swaminathan static uint32_t emlxs_update_ff_wakeup_parms(emlxs_hba_t *hba, 87291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 88291a2b48SSukumar Swaminathan static uint32_t emlxs_update_sli1_wakeup_parms(emlxs_hba_t *hba, 89291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 90291a2b48SSukumar Swaminathan static uint32_t emlxs_update_sli2_wakeup_parms(emlxs_hba_t *hba, 91291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 92291a2b48SSukumar Swaminathan static uint32_t emlxs_update_sli3_wakeup_parms(emlxs_hba_t *hba, 93291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 94291a2b48SSukumar Swaminathan static uint32_t emlxs_update_sli4_wakeup_parms(emlxs_hba_t *hba, 95291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 96291a2b48SSukumar Swaminathan static uint32_t emlxs_start_rel_download(emlxs_hba_t *hba, PIMAGE_HDR ImageHdr, 97291a2b48SSukumar Swaminathan caddr_t Buffer, PWAKE_UP_PARMS WakeUpParms, 98291a2b48SSukumar Swaminathan uint32_t MaxRbusSramSize, uint32_t MaxIbusSramSize); 99291a2b48SSukumar Swaminathan static uint32_t emlxs_read_load_list(emlxs_hba_t *hba, LOAD_LIST *LoadList); 100fcf3ce44SJohn Forte 101291a2b48SSukumar Swaminathan static uint32_t emlxs_valid_cksum(uint32_t *StartAddr, uint32_t *EndAddr); 102*82527734SSukumar Swaminathan 103291a2b48SSukumar Swaminathan static void emlxs_disp_aif_header(emlxs_hba_t *hba, PAIF_HDR AifHdr); 104*82527734SSukumar Swaminathan 105291a2b48SSukumar Swaminathan static void emlxs_dump_image_header(emlxs_hba_t *hba, PIMAGE_HDR image); 106*82527734SSukumar Swaminathan 107291a2b48SSukumar Swaminathan static uint32_t emlxs_get_abs_image_type(caddr_t Buffer, uint32_t BufferSize); 108fcf3ce44SJohn Forte 109291a2b48SSukumar Swaminathan static uint32_t emlxs_get_dwc_image_type(emlxs_hba_t *hba, caddr_t Buffer, 110291a2b48SSukumar Swaminathan uint32_t BufferSize, PAIF_HDR AifHeader); 111291a2b48SSukumar Swaminathan static uint32_t emlxs_type_check(uint32_t type); 112*82527734SSukumar Swaminathan 113291a2b48SSukumar Swaminathan static uint32_t emlxs_kern_check(emlxs_hba_t *hba, uint32_t version); 114*82527734SSukumar Swaminathan 115291a2b48SSukumar Swaminathan static uint32_t emlxs_stub_check(emlxs_hba_t *hba, uint32_t version); 116*82527734SSukumar Swaminathan 117291a2b48SSukumar Swaminathan static uint32_t emlxs_sli1_check(emlxs_hba_t *hba, uint32_t version); 118*82527734SSukumar Swaminathan 119291a2b48SSukumar Swaminathan static uint32_t emlxs_sli2_check(emlxs_hba_t *hba, uint32_t version); 120*82527734SSukumar Swaminathan 121291a2b48SSukumar Swaminathan static uint32_t emlxs_sli3_check(emlxs_hba_t *hba, uint32_t version); 122*82527734SSukumar Swaminathan 123291a2b48SSukumar Swaminathan static uint32_t emlxs_sli4_check(emlxs_hba_t *hba, uint32_t version); 124*82527734SSukumar Swaminathan 125291a2b48SSukumar Swaminathan static uint32_t emlxs_bios_check(emlxs_hba_t *hba, uint32_t version); 126*82527734SSukumar Swaminathan 127291a2b48SSukumar Swaminathan static uint32_t emlxs_sbus_fcode_check(emlxs_hba_t *hba, uint32_t version); 128*82527734SSukumar Swaminathan 129291a2b48SSukumar Swaminathan static uint32_t emlxs_validate_version(emlxs_hba_t *hba, 130291a2b48SSukumar Swaminathan emlxs_fw_file_t *file, uint32_t id, uint32_t type, 131291a2b48SSukumar Swaminathan char *file_type); 132*82527734SSukumar Swaminathan static uint32_t emlxs_sli4_validate_image(emlxs_hba_t *hba, caddr_t buffer, 133*82527734SSukumar Swaminathan uint32_t len, emlxs_be_fw_image_t *fw_image); 134*82527734SSukumar Swaminathan static int32_t emlxs_sli4_verify_image(emlxs_hba_t *hba, caddr_t buffer, 135*82527734SSukumar Swaminathan emlxs_be_fw_file_t *file, 136*82527734SSukumar Swaminathan MAILBOXQ *mbq, MATCHMAP *mp); 137*82527734SSukumar Swaminathan static int32_t emlxs_sli4_verify_crc(emlxs_hba_t *hba, 138*82527734SSukumar Swaminathan emlxs_be_fw_file_t *file, 139*82527734SSukumar Swaminathan MAILBOXQ *mbq, MATCHMAP *mp); 140*82527734SSukumar Swaminathan static int32_t emlxs_sli4_flash_image(emlxs_hba_t *hba, caddr_t buffer, 141*82527734SSukumar Swaminathan emlxs_be_fw_file_t *file, MAILBOXQ *mbq, MATCHMAP *mp); 142*82527734SSukumar Swaminathan static int32_t emlxs_sli4_fw_download(emlxs_hba_t *hba, caddr_t buffer, 143*82527734SSukumar Swaminathan uint32_t len, uint32_t offline); 144fcf3ce44SJohn Forte 145291a2b48SSukumar Swaminathan /* ************************************************************************* */ 146fcf3ce44SJohn Forte 147fcf3ce44SJohn Forte extern int32_t 148fcf3ce44SJohn Forte emlxs_fw_download(emlxs_hba_t *hba, caddr_t buffer, uint32_t len, 149fcf3ce44SJohn Forte uint32_t offline) 150fcf3ce44SJohn Forte { 151fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 152fcf3ce44SJohn Forte uint32_t *Uptr; 153fcf3ce44SJohn Forte IMAGE_HDR ImageHdr; 154fcf3ce44SJohn Forte AIF_HDR AifHdr; 155fcf3ce44SJohn Forte uint32_t ImageType; 156fcf3ce44SJohn Forte WAKE_UP_PARMS WakeUpParms; 157fcf3ce44SJohn Forte WAKE_UP_PARMS AbsWakeUpParms; 158fcf3ce44SJohn Forte uint32_t MaxRbusSramSize; 159fcf3ce44SJohn Forte uint32_t MaxIbusSramSize; 160fcf3ce44SJohn Forte int32_t AbsChangeParams = 0; 161fcf3ce44SJohn Forte int32_t DwcFile = FALSE; 162fcf3ce44SJohn Forte uint32_t rval = 0; 163fcf3ce44SJohn Forte emlxs_fw_image_t fw_image; 164fcf3ce44SJohn Forte uint32_t i; 165fcf3ce44SJohn Forte 166*82527734SSukumar Swaminathan #ifdef EMLXS_LITTLE_ENDIAN 167fcf3ce44SJohn Forte caddr_t local_buffer; 168fcf3ce44SJohn Forte uint32_t *bptr1; 169fcf3ce44SJohn Forte uint32_t *bptr2; 170*82527734SSukumar Swaminathan #endif /* EMLXS_LITTLE_ENDIAN */ 171*82527734SSukumar Swaminathan 172*82527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 173*82527734SSukumar Swaminathan rval = emlxs_sli4_fw_download(hba, buffer, len, offline); 174*82527734SSukumar Swaminathan return (rval); 175*82527734SSukumar Swaminathan } 176fcf3ce44SJohn Forte 177fcf3ce44SJohn Forte if (buffer == NULL || len == 0) { 178fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 179fcf3ce44SJohn Forte } 180*82527734SSukumar Swaminathan 181*82527734SSukumar Swaminathan #ifdef EMLXS_LITTLE_ENDIAN 182fcf3ce44SJohn Forte /* We need to swap the image buffer before we start */ 183fcf3ce44SJohn Forte 184fcf3ce44SJohn Forte /* 185fcf3ce44SJohn Forte * Use KM_SLEEP to allocate a temporary buffer 186fcf3ce44SJohn Forte */ 187fcf3ce44SJohn Forte local_buffer = (caddr_t)kmem_zalloc(len, KM_SLEEP); 188fcf3ce44SJohn Forte 189fcf3ce44SJohn Forte /* Perform a 32 bit swap of the image */ 190fcf3ce44SJohn Forte bptr1 = (uint32_t *)local_buffer; 191fcf3ce44SJohn Forte bptr2 = (uint32_t *)buffer; 192fcf3ce44SJohn Forte for (i = 0; i < (len / 4); i++) { 193*82527734SSukumar Swaminathan *bptr1 = LE_SWAP32(*bptr2); 194fcf3ce44SJohn Forte bptr1++; 195fcf3ce44SJohn Forte bptr2++; 196fcf3ce44SJohn Forte } 197fcf3ce44SJohn Forte 198fcf3ce44SJohn Forte /* Replace the original buffer */ 199fcf3ce44SJohn Forte buffer = local_buffer; 200*82527734SSukumar Swaminathan #endif /* EMLXS_LITTLE_ENDIAN */ 201fcf3ce44SJohn Forte 202fcf3ce44SJohn Forte bzero(&fw_image, sizeof (emlxs_fw_image_t)); 203fcf3ce44SJohn Forte for (i = 0; i < MAX_PROG_TYPES; i++) { 204fcf3ce44SJohn Forte (void) strcpy(fw_image.prog[i].label, "none"); 205fcf3ce44SJohn Forte } 206fcf3ce44SJohn Forte 207fcf3ce44SJohn Forte /* Validate image */ 208fcf3ce44SJohn Forte if ((rval = emlxs_validate_image(hba, buffer, len, &fw_image))) { 209fcf3ce44SJohn Forte goto done; 210fcf3ce44SJohn Forte } 211291a2b48SSukumar Swaminathan 212fcf3ce44SJohn Forte /* Get image type */ 213fcf3ce44SJohn Forte Uptr = (uint32_t *)buffer; 214fcf3ce44SJohn Forte ImageType = *Uptr; 215fcf3ce44SJohn Forte 216fcf3ce44SJohn Forte /* 217291a2b48SSukumar Swaminathan * Pegasus and beyond FW download is done differently 218291a2b48SSukumar Swaminathan * for absolute download. 219fcf3ce44SJohn Forte */ 220fcf3ce44SJohn Forte 221fcf3ce44SJohn Forte /* Check for absolute image */ 222fcf3ce44SJohn Forte if ((ImageType == NOP_IMAGE_TYPE) && 223fcf3ce44SJohn Forte !(hba->model_info.chip & 224fcf3ce44SJohn Forte (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 225fcf3ce44SJohn Forte /* 226fcf3ce44SJohn Forte * Because 2Mb flash download file format is different from 227fcf3ce44SJohn Forte * 512k, it needs to be handled differently 228fcf3ce44SJohn Forte */ 229fcf3ce44SJohn Forte if (rval = emlxs_start_abs_download_2mb(hba, buffer, len, 230fcf3ce44SJohn Forte offline, &fw_image)) { 231fcf3ce44SJohn Forte goto done; 232fcf3ce44SJohn Forte } 233291a2b48SSukumar Swaminathan 234fcf3ce44SJohn Forte /* Offline already handled */ 235fcf3ce44SJohn Forte offline = 0; 236fcf3ce44SJohn Forte 237fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 238fcf3ce44SJohn Forte } 239291a2b48SSukumar Swaminathan 240fcf3ce44SJohn Forte /* Pre-pegasus adapters only */ 241fcf3ce44SJohn Forte 242fcf3ce44SJohn Forte /* Check for absolute image */ 243fcf3ce44SJohn Forte else if (ImageType == NOP_IMAGE_TYPE) { 244fcf3ce44SJohn Forte bcopy(buffer, &AifHdr, sizeof (AIF_HDR)); 245fcf3ce44SJohn Forte bzero((void *)&ImageHdr, sizeof (IMAGE_HDR)); 246fcf3ce44SJohn Forte 247fcf3ce44SJohn Forte if (AifHdr.ImageBase && (AifHdr.ImageBase == 0x20000)) { 248fcf3ce44SJohn Forte DwcFile = TRUE; 249fcf3ce44SJohn Forte } 250291a2b48SSukumar Swaminathan 251291a2b48SSukumar Swaminathan AbsChangeParams = emlxs_build_parms(buffer, 252291a2b48SSukumar Swaminathan &AbsWakeUpParms, len, &AifHdr, DwcFile); 253fcf3ce44SJohn Forte } else { /* (ImageType != NOP_IMAGE_TYPE) Relative image */ 254291a2b48SSukumar Swaminathan 255fcf3ce44SJohn Forte bzero((void *)&AifHdr, sizeof (AIF_HDR)); 256fcf3ce44SJohn Forte bcopy(buffer, &ImageHdr, sizeof (IMAGE_HDR)); 257fcf3ce44SJohn Forte } 258fcf3ce44SJohn Forte 259fcf3ce44SJohn Forte /* 260fcf3ce44SJohn Forte * Everything checks out, now to just do it 261fcf3ce44SJohn Forte */ 262fcf3ce44SJohn Forte 263fcf3ce44SJohn Forte if (offline) { 264fcf3ce44SJohn Forte if (emlxs_offline(hba) != FC_SUCCESS) { 265fcf3ce44SJohn Forte offline = 0; 266fcf3ce44SJohn Forte 267fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 268fcf3ce44SJohn Forte "Unable to take adapter offline."); 269fcf3ce44SJohn Forte 270fcf3ce44SJohn Forte rval = EMLXS_OFFLINE_FAILED; 271fcf3ce44SJohn Forte 272fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 273fcf3ce44SJohn Forte } 274291a2b48SSukumar Swaminathan 275*82527734SSukumar Swaminathan if (EMLXS_SLI_HBA_RESET(hba, 1, 1, 0) != FC_SUCCESS) { 276fcf3ce44SJohn Forte offline = 0; 277fcf3ce44SJohn Forte 278fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 279fcf3ce44SJohn Forte "Unable to restart adapter."); 280fcf3ce44SJohn Forte 281fcf3ce44SJohn Forte rval = EMLXS_OFFLINE_FAILED; 282fcf3ce44SJohn Forte 283fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 284fcf3ce44SJohn Forte } 285fcf3ce44SJohn Forte } 286291a2b48SSukumar Swaminathan 287fcf3ce44SJohn Forte if (ImageHdr.Id.Type == SBUS_FCODE) { 288fcf3ce44SJohn Forte /* Erase Flash */ 289fcf3ce44SJohn Forte if (emlxs_erase_fcode_flash(hba)) { 290fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 291fcf3ce44SJohn Forte "Unable to erase flash."); 292fcf3ce44SJohn Forte 293fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 294fcf3ce44SJohn Forte 295fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 296fcf3ce44SJohn Forte } 297291a2b48SSukumar Swaminathan 298fcf3ce44SJohn Forte /* Write FCODE */ 299fcf3ce44SJohn Forte if (emlxs_write_fcode_flash(hba, &ImageHdr, buffer)) { 300fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 301fcf3ce44SJohn Forte "Unable to write flash."); 302fcf3ce44SJohn Forte 303fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 304fcf3ce44SJohn Forte 305fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 306fcf3ce44SJohn Forte } 307291a2b48SSukumar Swaminathan 308fcf3ce44SJohn Forte } else { /* !SBUS_FCODE */ 309fcf3ce44SJohn Forte 310291a2b48SSukumar Swaminathan 311fcf3ce44SJohn Forte if (emlxs_read_wakeup_parms(hba, &WakeUpParms, 1)) { 312fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 313fcf3ce44SJohn Forte "Unable to get parameters."); 314fcf3ce44SJohn Forte 315fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 316fcf3ce44SJohn Forte 317fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 318fcf3ce44SJohn Forte } 319291a2b48SSukumar Swaminathan 320fcf3ce44SJohn Forte if (emlxs_get_max_sram(hba, &MaxRbusSramSize, 321fcf3ce44SJohn Forte &MaxIbusSramSize)) { 322fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 323fcf3ce44SJohn Forte "Unable to get RAM size."); 324fcf3ce44SJohn Forte 325fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 326fcf3ce44SJohn Forte 327fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 328fcf3ce44SJohn Forte } 329291a2b48SSukumar Swaminathan 330fcf3ce44SJohn Forte if (ImageType == NOP_IMAGE_TYPE) { 331fcf3ce44SJohn Forte if (emlxs_start_abs_download(hba, &AifHdr, buffer, 332fcf3ce44SJohn Forte &WakeUpParms, MaxRbusSramSize, MaxIbusSramSize, 333fcf3ce44SJohn Forte (AbsChangeParams) ? &AbsWakeUpParms : NULL, 334fcf3ce44SJohn Forte DwcFile)) { 335fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 336fcf3ce44SJohn Forte &emlxs_download_failed_msg, 337fcf3ce44SJohn Forte "Failed to program flash."); 338fcf3ce44SJohn Forte 339fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 340fcf3ce44SJohn Forte 341fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 342fcf3ce44SJohn Forte } 343291a2b48SSukumar Swaminathan 344fcf3ce44SJohn Forte } else { 345fcf3ce44SJohn Forte 346fcf3ce44SJohn Forte if (emlxs_start_rel_download(hba, &ImageHdr, buffer, 347fcf3ce44SJohn Forte &WakeUpParms, MaxRbusSramSize, MaxIbusSramSize)) { 348fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 349fcf3ce44SJohn Forte &emlxs_download_failed_msg, 350fcf3ce44SJohn Forte "Failed to program flash."); 351fcf3ce44SJohn Forte 352fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 353fcf3ce44SJohn Forte 354fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 355fcf3ce44SJohn Forte } 356fcf3ce44SJohn Forte } 357fcf3ce44SJohn Forte 358fcf3ce44SJohn Forte } /* !SBUS_FCODE */ 359fcf3ce44SJohn Forte 360fcf3ce44SJohn Forte 361fcf3ce44SJohn Forte SLI_DOWNLOAD_EXIT: 362fcf3ce44SJohn Forte 363fcf3ce44SJohn Forte if (offline) { 364fcf3ce44SJohn Forte (void) emlxs_online(hba); 365fcf3ce44SJohn Forte } 366291a2b48SSukumar Swaminathan 367fcf3ce44SJohn Forte if (rval == 0) { 368fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_complete_msg, 369fcf3ce44SJohn Forte "Status good."); 370fcf3ce44SJohn Forte } 371291a2b48SSukumar Swaminathan 372fcf3ce44SJohn Forte done: 373fcf3ce44SJohn Forte 374*82527734SSukumar Swaminathan #ifdef EMLXS_LITTLE_ENDIAN 375fcf3ce44SJohn Forte /* Free the local buffer */ 376fcf3ce44SJohn Forte kmem_free(local_buffer, len); 377*82527734SSukumar Swaminathan #endif /* EMLXS_LITTLE_ENDIAN */ 378*82527734SSukumar Swaminathan 379*82527734SSukumar Swaminathan return (rval); 380*82527734SSukumar Swaminathan 381*82527734SSukumar Swaminathan } /* emlxs_fw_download */ 382*82527734SSukumar Swaminathan 383*82527734SSukumar Swaminathan 384*82527734SSukumar Swaminathan static void 385*82527734SSukumar Swaminathan emlxs_memset(uint8_t *buffer, uint8_t value, uint32_t size) 386*82527734SSukumar Swaminathan { 387*82527734SSukumar Swaminathan while (size--) { 388*82527734SSukumar Swaminathan *buffer++ = value; 389*82527734SSukumar Swaminathan } 390*82527734SSukumar Swaminathan 391*82527734SSukumar Swaminathan } /* emlxs_memset () */ 392*82527734SSukumar Swaminathan 393*82527734SSukumar Swaminathan 394*82527734SSukumar Swaminathan static int32_t 395*82527734SSukumar Swaminathan emlxs_sli4_flash_image(emlxs_hba_t *hba, caddr_t buffer, 396*82527734SSukumar Swaminathan emlxs_be_fw_file_t *file, MAILBOXQ *mbq, MATCHMAP *mp) 397*82527734SSukumar Swaminathan { 398*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 399*82527734SSukumar Swaminathan uint8_t *image_ptr; 400*82527734SSukumar Swaminathan uint32_t *wptr; 401*82527734SSukumar Swaminathan uint8_t *payload; 402*82527734SSukumar Swaminathan MAILBOX4 *mb; 403*82527734SSukumar Swaminathan IOCTL_COMMON_FLASHROM *flashrom; 404*82527734SSukumar Swaminathan mbox_req_hdr_t *hdr_req; 405*82527734SSukumar Swaminathan uint32_t image_size; 406*82527734SSukumar Swaminathan uint32_t block_size; 407*82527734SSukumar Swaminathan uint32_t xfer_size; 408*82527734SSukumar Swaminathan uint32_t block_offset; 409*82527734SSukumar Swaminathan uint32_t count; 410*82527734SSukumar Swaminathan uint32_t rval = 0; 411*82527734SSukumar Swaminathan 412*82527734SSukumar Swaminathan if (file->image_size == 0) { 413*82527734SSukumar Swaminathan return (0); 414*82527734SSukumar Swaminathan } 415*82527734SSukumar Swaminathan 416*82527734SSukumar Swaminathan image_ptr = (uint8_t *)buffer + file->image_offset; 417*82527734SSukumar Swaminathan image_size = file->image_size; 418*82527734SSukumar Swaminathan block_size = file->block_size; 419*82527734SSukumar Swaminathan block_offset = 0; 420*82527734SSukumar Swaminathan mb = (MAILBOX4*)mbq; 421*82527734SSukumar Swaminathan 422*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 423*82527734SSukumar Swaminathan "%s: Downloading...", file->label); 424*82527734SSukumar Swaminathan 425*82527734SSukumar Swaminathan while (block_size) { 426*82527734SSukumar Swaminathan bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 427*82527734SSukumar Swaminathan bzero((void *) mp->virt, mp->size); 428*82527734SSukumar Swaminathan 429*82527734SSukumar Swaminathan xfer_size = min(BE_MAX_XFER_SIZE, block_size); 430*82527734SSukumar Swaminathan 431*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.embedded = 0; 432*82527734SSukumar Swaminathan mbq->nonembed = (uint8_t *)mp; 433*82527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 434*82527734SSukumar Swaminathan 435*82527734SSukumar Swaminathan mb->mbxCommand = MBX_SLI_CONFIG; 436*82527734SSukumar Swaminathan mb->mbxOwner = OWN_HOST; 437*82527734SSukumar Swaminathan 438*82527734SSukumar Swaminathan hdr_req = (mbox_req_hdr_t *)mp->virt; 439*82527734SSukumar Swaminathan hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON; 440*82527734SSukumar Swaminathan hdr_req->opcode = COMMON_OPCODE_WRITE_FLASHROM; 441*82527734SSukumar Swaminathan hdr_req->timeout = 0; 442*82527734SSukumar Swaminathan hdr_req->req_length = sizeof (IOCTL_COMMON_FLASHROM) + 443*82527734SSukumar Swaminathan xfer_size; 444*82527734SSukumar Swaminathan 445*82527734SSukumar Swaminathan flashrom = (IOCTL_COMMON_FLASHROM *)(hdr_req + 1); 446*82527734SSukumar Swaminathan flashrom->params.opcode = ((block_size == xfer_size)? 447*82527734SSukumar Swaminathan MGMT_FLASHROM_OPCODE_FLASH:MGMT_FLASHROM_OPCODE_SAVE); 448*82527734SSukumar Swaminathan flashrom->params.optype = file->type; 449*82527734SSukumar Swaminathan flashrom->params.data_buffer_size = xfer_size; 450*82527734SSukumar Swaminathan flashrom->params.offset = block_offset; 451*82527734SSukumar Swaminathan 452*82527734SSukumar Swaminathan /* Build data buffer payload */ 453*82527734SSukumar Swaminathan payload = (uint8_t *)(&flashrom->params.data_buffer); 454*82527734SSukumar Swaminathan emlxs_memset(payload, 0xff, xfer_size); 455*82527734SSukumar Swaminathan 456*82527734SSukumar Swaminathan /* Copy remaining image into payload */ 457*82527734SSukumar Swaminathan if (image_size) { 458*82527734SSukumar Swaminathan count = min(image_size, xfer_size); 459*82527734SSukumar Swaminathan BE_SWAP32_BCOPY(image_ptr, payload, count); 460*82527734SSukumar Swaminathan image_size -= count; 461*82527734SSukumar Swaminathan image_ptr += count; 462*82527734SSukumar Swaminathan } 463*82527734SSukumar Swaminathan 464*82527734SSukumar Swaminathan /* Set last two words of last payload with */ 465*82527734SSukumar Swaminathan /* image size and block crc */ 466*82527734SSukumar Swaminathan if (flashrom->params.opcode == MGMT_FLASHROM_OPCODE_FLASH) { 467*82527734SSukumar Swaminathan wptr = (uint32_t *)&payload[(xfer_size - 8)]; 468*82527734SSukumar Swaminathan wptr[0] = file->image_size; 469*82527734SSukumar Swaminathan wptr[1] = file->block_crc; 470*82527734SSukumar Swaminathan } 471*82527734SSukumar Swaminathan 472*82527734SSukumar Swaminathan /* Send write request */ 473*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 474*82527734SSukumar Swaminathan MBX_SUCCESS) { 475*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 476*82527734SSukumar Swaminathan "%s: Unable to download image. status=%x", 477*82527734SSukumar Swaminathan file->label, mb->mbxStatus); 478*82527734SSukumar Swaminathan rval = EMLXS_IMAGE_FAILED; 479*82527734SSukumar Swaminathan goto done; 480*82527734SSukumar Swaminathan } 481*82527734SSukumar Swaminathan 482*82527734SSukumar Swaminathan block_size -= xfer_size; 483*82527734SSukumar Swaminathan block_offset += xfer_size; 484*82527734SSukumar Swaminathan } 485*82527734SSukumar Swaminathan 486*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 487*82527734SSukumar Swaminathan "%s: Download complete.", file->label); 488*82527734SSukumar Swaminathan done: 489*82527734SSukumar Swaminathan 490*82527734SSukumar Swaminathan return (rval); 491*82527734SSukumar Swaminathan 492*82527734SSukumar Swaminathan } /* emlxs_sli4_flash_image() */ 493*82527734SSukumar Swaminathan 494*82527734SSukumar Swaminathan 495*82527734SSukumar Swaminathan static int32_t 496*82527734SSukumar Swaminathan emlxs_sli4_verify_image(emlxs_hba_t *hba, caddr_t buffer, 497*82527734SSukumar Swaminathan emlxs_be_fw_file_t *file, MAILBOXQ *mbq, MATCHMAP *mp) 498*82527734SSukumar Swaminathan { 499*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 500*82527734SSukumar Swaminathan uint8_t *image_ptr; 501*82527734SSukumar Swaminathan uint32_t *wptr; 502*82527734SSukumar Swaminathan uint32_t *wptr1; 503*82527734SSukumar Swaminathan uint8_t *payload; 504*82527734SSukumar Swaminathan MAILBOX4 *mb; 505*82527734SSukumar Swaminathan IOCTL_COMMON_FLASHROM *flashrom; 506*82527734SSukumar Swaminathan mbox_req_hdr_t *hdr_req; 507*82527734SSukumar Swaminathan uint32_t xfer_size; 508*82527734SSukumar Swaminathan uint32_t block_size; 509*82527734SSukumar Swaminathan uint32_t block_offset; 510*82527734SSukumar Swaminathan uint32_t rval = 0; 511*82527734SSukumar Swaminathan uint32_t i; 512*82527734SSukumar Swaminathan char signature[BE_SIGNATURE_SIZE]; 513*82527734SSukumar Swaminathan uint32_t ufi_plus = 0; 514*82527734SSukumar Swaminathan 515*82527734SSukumar Swaminathan /* Check for special deflated format */ 516*82527734SSukumar Swaminathan (void) sprintf(signature, "%s+", BE_SIGNATURE); 517*82527734SSukumar Swaminathan if (strncmp(signature, buffer, 518*82527734SSukumar Swaminathan sizeof (signature)-1) == 0) { 519*82527734SSukumar Swaminathan ufi_plus = 1; 520*82527734SSukumar Swaminathan } 521*82527734SSukumar Swaminathan 522*82527734SSukumar Swaminathan image_ptr = (uint8_t *)buffer + file->image_offset; 523*82527734SSukumar Swaminathan block_size = (ufi_plus)? file->image_size: file->block_size; 524*82527734SSukumar Swaminathan block_offset = 0; 525*82527734SSukumar Swaminathan mb = (MAILBOX4*)mbq; 526*82527734SSukumar Swaminathan 527*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 528*82527734SSukumar Swaminathan "%s: Verifying image...", file->label); 529*82527734SSukumar Swaminathan 530*82527734SSukumar Swaminathan while (block_size) { 531*82527734SSukumar Swaminathan bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 532*82527734SSukumar Swaminathan bzero((void *) mp->virt, mp->size); 533*82527734SSukumar Swaminathan 534*82527734SSukumar Swaminathan xfer_size = min(BE_MAX_XFER_SIZE, block_size); 535*82527734SSukumar Swaminathan 536*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.embedded = 0; 537*82527734SSukumar Swaminathan mbq->nonembed = (uint8_t *)mp; 538*82527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 539*82527734SSukumar Swaminathan 540*82527734SSukumar Swaminathan mb->mbxCommand = MBX_SLI_CONFIG; 541*82527734SSukumar Swaminathan mb->mbxOwner = OWN_HOST; 542*82527734SSukumar Swaminathan 543*82527734SSukumar Swaminathan hdr_req = (mbox_req_hdr_t *)mp->virt; 544*82527734SSukumar Swaminathan hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON; 545*82527734SSukumar Swaminathan hdr_req->opcode = COMMON_OPCODE_READ_FLASHROM; 546*82527734SSukumar Swaminathan hdr_req->timeout = 0; 547*82527734SSukumar Swaminathan hdr_req->req_length = sizeof (IOCTL_COMMON_FLASHROM) + 548*82527734SSukumar Swaminathan xfer_size; 549*82527734SSukumar Swaminathan 550*82527734SSukumar Swaminathan flashrom = (IOCTL_COMMON_FLASHROM *)(hdr_req + 1); 551*82527734SSukumar Swaminathan flashrom->params.opcode = MGMT_FLASHROM_OPCODE_REPORT; 552*82527734SSukumar Swaminathan flashrom->params.optype = file->type; 553*82527734SSukumar Swaminathan flashrom->params.data_buffer_size = xfer_size; 554*82527734SSukumar Swaminathan flashrom->params.offset = block_offset; 555*82527734SSukumar Swaminathan 556*82527734SSukumar Swaminathan /* Send read request */ 557*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 558*82527734SSukumar Swaminathan MBX_SUCCESS) { 559*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 560*82527734SSukumar Swaminathan "%s: Unable to read image. status=%x", 561*82527734SSukumar Swaminathan file->label, mb->mbxStatus); 562*82527734SSukumar Swaminathan 563*82527734SSukumar Swaminathan rval = EMLXS_IMAGE_FAILED; 564*82527734SSukumar Swaminathan goto done; 565*82527734SSukumar Swaminathan } 566*82527734SSukumar Swaminathan 567*82527734SSukumar Swaminathan payload = (uint8_t *)(&flashrom->params.data_buffer); 568*82527734SSukumar Swaminathan 569*82527734SSukumar Swaminathan BE_SWAP32_BUFFER(payload, xfer_size); 570*82527734SSukumar Swaminathan 571*82527734SSukumar Swaminathan wptr = (uint32_t *)image_ptr; 572*82527734SSukumar Swaminathan wptr1 = (uint32_t *)payload; 573*82527734SSukumar Swaminathan for (i = 0; i < xfer_size; i += 4, wptr++, wptr1++) { 574*82527734SSukumar Swaminathan if (*wptr != *wptr1) { 575*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 576*82527734SSukumar Swaminathan "%s: Image mismatch. [%08x] %x, %x", 577*82527734SSukumar Swaminathan file->label, i, 578*82527734SSukumar Swaminathan BE_MAX_XFER_SIZE, xfer_size); 579*82527734SSukumar Swaminathan 580*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 581*82527734SSukumar Swaminathan "%08x: %08x %08x %08x %08x %08x " \ 582*82527734SSukumar Swaminathan "%08x %08x %08x", 583*82527734SSukumar Swaminathan i, wptr[0], wptr[1], wptr[2], 584*82527734SSukumar Swaminathan wptr[3], wptr[4], wptr[5], wptr[6], 585*82527734SSukumar Swaminathan wptr[7]); 586*82527734SSukumar Swaminathan 587*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 588*82527734SSukumar Swaminathan "%08x: %08x %08x %08x %08x %08x " \ 589*82527734SSukumar Swaminathan "%08x %08x %08x", 590*82527734SSukumar Swaminathan i, wptr1[0], wptr1[1], wptr1[2], 591*82527734SSukumar Swaminathan wptr1[3], wptr1[4], wptr1[5], wptr1[6], 592*82527734SSukumar Swaminathan wptr1[7]); 593*82527734SSukumar Swaminathan 594*82527734SSukumar Swaminathan rval = EMLXS_IMAGE_FAILED; 595*82527734SSukumar Swaminathan goto done; 596*82527734SSukumar Swaminathan } 597*82527734SSukumar Swaminathan } 598*82527734SSukumar Swaminathan 599*82527734SSukumar Swaminathan bcopy((uint8_t *)(&flashrom->params.data_buffer), image_ptr, 600*82527734SSukumar Swaminathan xfer_size); 601*82527734SSukumar Swaminathan 602*82527734SSukumar Swaminathan block_size -= xfer_size; 603*82527734SSukumar Swaminathan block_offset += xfer_size; 604*82527734SSukumar Swaminathan image_ptr += xfer_size; 605*82527734SSukumar Swaminathan } 606*82527734SSukumar Swaminathan 607*82527734SSukumar Swaminathan /* Verify CRC */ 608*82527734SSukumar Swaminathan rval = emlxs_sli4_verify_crc(hba, file, mbq, mp); 609*82527734SSukumar Swaminathan 610*82527734SSukumar Swaminathan done: 611*82527734SSukumar Swaminathan 612*82527734SSukumar Swaminathan if (rval == 0) { 613*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 614*82527734SSukumar Swaminathan "%s: Image verified.", file->label); 615*82527734SSukumar Swaminathan } 616fcf3ce44SJohn Forte 617fcf3ce44SJohn Forte return (rval); 618fcf3ce44SJohn Forte 619*82527734SSukumar Swaminathan } /* emlxs_sli4_verify_image() */ 620*82527734SSukumar Swaminathan 621*82527734SSukumar Swaminathan 622*82527734SSukumar Swaminathan static int32_t 623*82527734SSukumar Swaminathan emlxs_sli4_verify_crc(emlxs_hba_t *hba, 624*82527734SSukumar Swaminathan emlxs_be_fw_file_t *file, MAILBOXQ *mbq, MATCHMAP *mp) 625*82527734SSukumar Swaminathan { 626*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 627*82527734SSukumar Swaminathan uint32_t *wptr; 628*82527734SSukumar Swaminathan uint8_t *payload; 629*82527734SSukumar Swaminathan MAILBOX4 *mb; 630*82527734SSukumar Swaminathan IOCTL_COMMON_FLASHROM *flashrom; 631*82527734SSukumar Swaminathan mbox_req_hdr_t *hdr_req; 632*82527734SSukumar Swaminathan uint32_t xfer_size; 633*82527734SSukumar Swaminathan uint32_t block_offset; 634*82527734SSukumar Swaminathan uint32_t rval = 0; 635*82527734SSukumar Swaminathan uint32_t value; 636*82527734SSukumar Swaminathan 637*82527734SSukumar Swaminathan xfer_size = 8; 638*82527734SSukumar Swaminathan block_offset = file->block_size - xfer_size; 639*82527734SSukumar Swaminathan mb = (MAILBOX4*)mbq; 640*82527734SSukumar Swaminathan 641*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 642*82527734SSukumar Swaminathan "%s: Verifying CRC...", file->label); 643*82527734SSukumar Swaminathan 644*82527734SSukumar Swaminathan bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 645*82527734SSukumar Swaminathan bzero((void *) mp->virt, mp->size); 646*82527734SSukumar Swaminathan 647*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.embedded = 0; 648*82527734SSukumar Swaminathan mbq->nonembed = (uint8_t *)mp; 649*82527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 650*82527734SSukumar Swaminathan 651*82527734SSukumar Swaminathan mb->mbxCommand = MBX_SLI_CONFIG; 652*82527734SSukumar Swaminathan mb->mbxOwner = OWN_HOST; 653*82527734SSukumar Swaminathan 654*82527734SSukumar Swaminathan hdr_req = (mbox_req_hdr_t *)mp->virt; 655*82527734SSukumar Swaminathan hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON; 656*82527734SSukumar Swaminathan hdr_req->opcode = COMMON_OPCODE_READ_FLASHROM; 657*82527734SSukumar Swaminathan hdr_req->timeout = 0; 658*82527734SSukumar Swaminathan hdr_req->req_length = sizeof (IOCTL_COMMON_FLASHROM) + 659*82527734SSukumar Swaminathan xfer_size; 660*82527734SSukumar Swaminathan 661*82527734SSukumar Swaminathan flashrom = (IOCTL_COMMON_FLASHROM *)(hdr_req + 1); 662*82527734SSukumar Swaminathan flashrom->params.opcode = MGMT_FLASHROM_OPCODE_REPORT; 663*82527734SSukumar Swaminathan flashrom->params.optype = file->type; 664*82527734SSukumar Swaminathan flashrom->params.data_buffer_size = xfer_size; 665*82527734SSukumar Swaminathan flashrom->params.offset = block_offset; 666*82527734SSukumar Swaminathan 667*82527734SSukumar Swaminathan /* Send read request */ 668*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 669*82527734SSukumar Swaminathan MBX_SUCCESS) { 670*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 671*82527734SSukumar Swaminathan "%s: Unable to read CRC. status=%x", 672*82527734SSukumar Swaminathan file->label, mb->mbxStatus); 673*82527734SSukumar Swaminathan 674*82527734SSukumar Swaminathan rval = EMLXS_IMAGE_FAILED; 675*82527734SSukumar Swaminathan goto done; 676*82527734SSukumar Swaminathan } 677*82527734SSukumar Swaminathan 678*82527734SSukumar Swaminathan payload = (uint8_t *)(&flashrom->params.data_buffer); 679*82527734SSukumar Swaminathan wptr = (uint32_t *)(payload + xfer_size - 8); 680*82527734SSukumar Swaminathan 681*82527734SSukumar Swaminathan /* Verify image size */ 682*82527734SSukumar Swaminathan value = *wptr++; 683*82527734SSukumar Swaminathan if (value != file->image_size) { 684*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 685*82527734SSukumar Swaminathan "%s: Image size mismatch. %08x != %08x", 686*82527734SSukumar Swaminathan file->label, value, file->image_size); 687*82527734SSukumar Swaminathan 688*82527734SSukumar Swaminathan rval = EMLXS_IMAGE_FAILED; 689*82527734SSukumar Swaminathan goto done; 690*82527734SSukumar Swaminathan } 691*82527734SSukumar Swaminathan 692*82527734SSukumar Swaminathan /* Verify block crc */ 693*82527734SSukumar Swaminathan value = *wptr; 694*82527734SSukumar Swaminathan if (value != file->block_crc) { 695*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 696*82527734SSukumar Swaminathan "%s: CRC mismatch. %08x != %08x", 697*82527734SSukumar Swaminathan file->label, value, file->block_crc); 698*82527734SSukumar Swaminathan rval = EMLXS_IMAGE_FAILED; 699*82527734SSukumar Swaminathan } 700*82527734SSukumar Swaminathan 701*82527734SSukumar Swaminathan done: 702*82527734SSukumar Swaminathan 703*82527734SSukumar Swaminathan if (rval == 0) { 704*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 705*82527734SSukumar Swaminathan "%s: CRC verified.", file->label); 706*82527734SSukumar Swaminathan } 707*82527734SSukumar Swaminathan 708*82527734SSukumar Swaminathan return (rval); 709*82527734SSukumar Swaminathan 710*82527734SSukumar Swaminathan } /* emlxs_sli4_verify_crc() */ 711*82527734SSukumar Swaminathan 712*82527734SSukumar Swaminathan 713*82527734SSukumar Swaminathan extern int32_t 714*82527734SSukumar Swaminathan emlxs_sli4_read_fw_version(emlxs_hba_t *hba, emlxs_firmware_t *fw) 715*82527734SSukumar Swaminathan { 716*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 717*82527734SSukumar Swaminathan MAILBOXQ *mbq = NULL; 718*82527734SSukumar Swaminathan MATCHMAP *mp = NULL; 719*82527734SSukumar Swaminathan MAILBOX4 *mb; 720*82527734SSukumar Swaminathan uint32_t *wptr; 721*82527734SSukumar Swaminathan uint8_t *payload; 722*82527734SSukumar Swaminathan IOCTL_COMMON_FLASHROM *flashrom; 723*82527734SSukumar Swaminathan mbox_req_hdr_t *hdr_req; 724*82527734SSukumar Swaminathan uint32_t xfer_size; 725*82527734SSukumar Swaminathan uint32_t block_offset; 726*82527734SSukumar Swaminathan uint32_t rval = 0; 727*82527734SSukumar Swaminathan 728*82527734SSukumar Swaminathan bzero((void *) fw, sizeof (emlxs_firmware_t)); 729*82527734SSukumar Swaminathan 730*82527734SSukumar Swaminathan if ((mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 731*82527734SSukumar Swaminathan KM_SLEEP)) == NULL) { 732*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 733*82527734SSukumar Swaminathan "read_fw_version: Unable to allocate mailbox buffer."); 734*82527734SSukumar Swaminathan 735*82527734SSukumar Swaminathan rval = 1; 736*82527734SSukumar Swaminathan goto done; 737*82527734SSukumar Swaminathan } 738*82527734SSukumar Swaminathan 739*82527734SSukumar Swaminathan if ((mp = emlxs_mem_buf_alloc(hba, (sizeof (mbox_req_hdr_t) + 740*82527734SSukumar Swaminathan sizeof (IOCTL_COMMON_FLASHROM) + 32))) == NULL) { 741*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 742*82527734SSukumar Swaminathan "read_fw_version: Unable to allocate payload buffer."); 743*82527734SSukumar Swaminathan 744*82527734SSukumar Swaminathan rval = EMLXS_IMAGE_FAILED; 745*82527734SSukumar Swaminathan goto done; 746*82527734SSukumar Swaminathan } 747*82527734SSukumar Swaminathan 748*82527734SSukumar Swaminathan mb = (MAILBOX4*)mbq; 749*82527734SSukumar Swaminathan 750*82527734SSukumar Swaminathan /* Read CRC and size */ 751*82527734SSukumar Swaminathan xfer_size = 8; 752*82527734SSukumar Swaminathan block_offset = 0x140000 - xfer_size; 753*82527734SSukumar Swaminathan 754*82527734SSukumar Swaminathan bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 755*82527734SSukumar Swaminathan bzero((void *) mp->virt, mp->size); 756*82527734SSukumar Swaminathan 757*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.embedded = 0; 758*82527734SSukumar Swaminathan mbq->nonembed = (uint8_t *)mp; 759*82527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 760*82527734SSukumar Swaminathan 761*82527734SSukumar Swaminathan mb->mbxCommand = MBX_SLI_CONFIG; 762*82527734SSukumar Swaminathan mb->mbxOwner = OWN_HOST; 763*82527734SSukumar Swaminathan 764*82527734SSukumar Swaminathan hdr_req = (mbox_req_hdr_t *)mp->virt; 765*82527734SSukumar Swaminathan hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON; 766*82527734SSukumar Swaminathan hdr_req->opcode = COMMON_OPCODE_READ_FLASHROM; 767*82527734SSukumar Swaminathan hdr_req->timeout = 0; 768*82527734SSukumar Swaminathan hdr_req->req_length = sizeof (IOCTL_COMMON_FLASHROM) + 769*82527734SSukumar Swaminathan xfer_size; 770*82527734SSukumar Swaminathan 771*82527734SSukumar Swaminathan flashrom = (IOCTL_COMMON_FLASHROM *)(hdr_req + 1); 772*82527734SSukumar Swaminathan flashrom->params.opcode = MGMT_FLASHROM_OPCODE_REPORT; 773*82527734SSukumar Swaminathan flashrom->params.optype = MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE; 774*82527734SSukumar Swaminathan flashrom->params.data_buffer_size = xfer_size; 775*82527734SSukumar Swaminathan flashrom->params.offset = block_offset; 776*82527734SSukumar Swaminathan 777*82527734SSukumar Swaminathan /* Send read request */ 778*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 779*82527734SSukumar Swaminathan MBX_SUCCESS) { 780*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 781*82527734SSukumar Swaminathan "read_fw_version: Unable to read CRC. status=%x", 782*82527734SSukumar Swaminathan mb->mbxStatus); 783*82527734SSukumar Swaminathan 784*82527734SSukumar Swaminathan rval = 1; 785*82527734SSukumar Swaminathan goto done; 786*82527734SSukumar Swaminathan } 787*82527734SSukumar Swaminathan 788*82527734SSukumar Swaminathan payload = (uint8_t *)(&flashrom->params.data_buffer); 789*82527734SSukumar Swaminathan 790*82527734SSukumar Swaminathan wptr = (uint32_t *)payload; 791*82527734SSukumar Swaminathan fw->size = *wptr++; /* image size */ 792*82527734SSukumar Swaminathan fw->sli4 = *wptr; /* block crc */ 793*82527734SSukumar Swaminathan fw->kern = *wptr; 794*82527734SSukumar Swaminathan fw->stub = *wptr; 795*82527734SSukumar Swaminathan 796*82527734SSukumar Swaminathan /* Read version label */ 797*82527734SSukumar Swaminathan xfer_size = 32; 798*82527734SSukumar Swaminathan block_offset = 0x30; 799*82527734SSukumar Swaminathan 800*82527734SSukumar Swaminathan bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 801*82527734SSukumar Swaminathan bzero((void *) mp->virt, mp->size); 802*82527734SSukumar Swaminathan 803*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.embedded = 0; 804*82527734SSukumar Swaminathan mbq->nonembed = (uint8_t *)mp; 805*82527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 806*82527734SSukumar Swaminathan 807*82527734SSukumar Swaminathan mb->mbxCommand = MBX_SLI_CONFIG; 808*82527734SSukumar Swaminathan mb->mbxOwner = OWN_HOST; 809*82527734SSukumar Swaminathan 810*82527734SSukumar Swaminathan hdr_req = (mbox_req_hdr_t *)mp->virt; 811*82527734SSukumar Swaminathan hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON; 812*82527734SSukumar Swaminathan hdr_req->opcode = COMMON_OPCODE_READ_FLASHROM; 813*82527734SSukumar Swaminathan hdr_req->timeout = 0; 814*82527734SSukumar Swaminathan hdr_req->req_length = sizeof (IOCTL_COMMON_FLASHROM) + 815*82527734SSukumar Swaminathan xfer_size; 816*82527734SSukumar Swaminathan 817*82527734SSukumar Swaminathan flashrom = (IOCTL_COMMON_FLASHROM *)(hdr_req + 1); 818*82527734SSukumar Swaminathan flashrom->params.opcode = MGMT_FLASHROM_OPCODE_REPORT; 819*82527734SSukumar Swaminathan flashrom->params.optype = MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE; 820*82527734SSukumar Swaminathan flashrom->params.data_buffer_size = xfer_size; 821*82527734SSukumar Swaminathan flashrom->params.offset = block_offset; 822*82527734SSukumar Swaminathan 823*82527734SSukumar Swaminathan /* Send read request */ 824*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 825*82527734SSukumar Swaminathan MBX_SUCCESS) { 826*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 827*82527734SSukumar Swaminathan "read_fw_version: Unable to read version string. status=%x", 828*82527734SSukumar Swaminathan mb->mbxStatus); 829*82527734SSukumar Swaminathan 830*82527734SSukumar Swaminathan rval = 1; 831*82527734SSukumar Swaminathan goto done; 832*82527734SSukumar Swaminathan } 833*82527734SSukumar Swaminathan 834*82527734SSukumar Swaminathan payload = (uint8_t *)(&flashrom->params.data_buffer); 835*82527734SSukumar Swaminathan BE_SWAP32_BCOPY(payload, (uint8_t *)fw->label, 32); 836*82527734SSukumar Swaminathan 837*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 838*82527734SSukumar Swaminathan "FCOE FIRMWARE: size=%x version=%s (0x%08x)", 839*82527734SSukumar Swaminathan fw->size, fw->label, fw->sli4); 840*82527734SSukumar Swaminathan 841*82527734SSukumar Swaminathan done: 842*82527734SSukumar Swaminathan 843*82527734SSukumar Swaminathan if (mbq) { 844*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq); 845*82527734SSukumar Swaminathan } 846*82527734SSukumar Swaminathan 847*82527734SSukumar Swaminathan if (mp) { 848*82527734SSukumar Swaminathan (void) emlxs_mem_buf_free(hba, mp); 849*82527734SSukumar Swaminathan } 850*82527734SSukumar Swaminathan 851*82527734SSukumar Swaminathan return (rval); 852*82527734SSukumar Swaminathan 853*82527734SSukumar Swaminathan } /* emlxs_sli4_read_fw_version() */ 854*82527734SSukumar Swaminathan 855*82527734SSukumar Swaminathan 856*82527734SSukumar Swaminathan static uint32_t 857*82527734SSukumar Swaminathan emlxs_sli4_validate_image(emlxs_hba_t *hba, caddr_t buffer, 858*82527734SSukumar Swaminathan uint32_t len, emlxs_be_fw_image_t *fw_image) 859*82527734SSukumar Swaminathan { 860*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 861*82527734SSukumar Swaminathan emlxs_sli4_ufi_header_t *ufi_hdr; 862*82527734SSukumar Swaminathan emlxs_sli4_flash_dir_t *flash_dir; 863*82527734SSukumar Swaminathan emlxs_sli4_flash_entry_t *entry; 864*82527734SSukumar Swaminathan uint8_t *bptr; 865*82527734SSukumar Swaminathan uint32_t *wptr; 866*82527734SSukumar Swaminathan uint32_t i; 867*82527734SSukumar Swaminathan uint32_t k; 868*82527734SSukumar Swaminathan uint32_t mask; 869*82527734SSukumar Swaminathan uint32_t value; 870*82527734SSukumar Swaminathan uint32_t image_size; 871*82527734SSukumar Swaminathan emlxs_be_fw_file_t *file; 872*82527734SSukumar Swaminathan emlxs_be_fw_file_t *file2; 873*82527734SSukumar Swaminathan char signature[BE_SIGNATURE_SIZE]; 874*82527734SSukumar Swaminathan uint32_t ufi_plus = 0; 875*82527734SSukumar Swaminathan 876*82527734SSukumar Swaminathan bzero(fw_image, sizeof (emlxs_be_fw_image_t)); 877*82527734SSukumar Swaminathan 878*82527734SSukumar Swaminathan if (hba->model_info.chip != EMLXS_TIGERSHARK_CHIP) { 879*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 880*82527734SSukumar Swaminathan "Invalid adapter model."); 881*82527734SSukumar Swaminathan return (EMLXS_IMAGE_INCOMPATIBLE); 882*82527734SSukumar Swaminathan } 883*82527734SSukumar Swaminathan 884*82527734SSukumar Swaminathan if (len < (sizeof (emlxs_sli4_ufi_header_t) + 885*82527734SSukumar Swaminathan sizeof (emlxs_sli4_flash_dir_t))) { 886*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 887*82527734SSukumar Swaminathan "Image too small. (%d < %d)", 888*82527734SSukumar Swaminathan len, (sizeof (emlxs_sli4_ufi_header_t) + 889*82527734SSukumar Swaminathan sizeof (emlxs_sli4_flash_dir_t))); 890*82527734SSukumar Swaminathan return (EMLXS_IMAGE_BAD); 891*82527734SSukumar Swaminathan } 892*82527734SSukumar Swaminathan ufi_hdr = (emlxs_sli4_ufi_header_t *)buffer; 893*82527734SSukumar Swaminathan 894*82527734SSukumar Swaminathan /* Check if this is a standard UFI image */ 895*82527734SSukumar Swaminathan if (strncmp(BE_SIGNATURE, ufi_hdr->signature, 896*82527734SSukumar Swaminathan sizeof (BE_SIGNATURE)-1) != 0) { 897*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 898*82527734SSukumar Swaminathan "Invalid image provided."); 899*82527734SSukumar Swaminathan return (EMLXS_IMAGE_INCOMPATIBLE); 900*82527734SSukumar Swaminathan } 901*82527734SSukumar Swaminathan 902*82527734SSukumar Swaminathan /* Check for special deflated format */ 903*82527734SSukumar Swaminathan (void) sprintf(signature, "%s+", BE_SIGNATURE); 904*82527734SSukumar Swaminathan if (strncmp(signature, ufi_hdr->signature, 905*82527734SSukumar Swaminathan sizeof (signature)-1) == 0) { 906*82527734SSukumar Swaminathan ufi_plus = 1; 907*82527734SSukumar Swaminathan } 908*82527734SSukumar Swaminathan 909*82527734SSukumar Swaminathan #ifdef EMLXS_BIG_ENDIAN 910*82527734SSukumar Swaminathan /* Big Endian Swapping */ 911*82527734SSukumar Swaminathan /* Swap ufi header */ 912*82527734SSukumar Swaminathan ufi_hdr->checksum = 913*82527734SSukumar Swaminathan SWAP32(ufi_hdr->checksum); 914*82527734SSukumar Swaminathan ufi_hdr->antidote = 915*82527734SSukumar Swaminathan SWAP32(ufi_hdr->antidote); 916*82527734SSukumar Swaminathan ufi_hdr->controller.vendor_id = 917*82527734SSukumar Swaminathan SWAP32(ufi_hdr->controller.vendor_id); 918*82527734SSukumar Swaminathan ufi_hdr->controller.device_id = 919*82527734SSukumar Swaminathan SWAP32(ufi_hdr->controller.device_id); 920*82527734SSukumar Swaminathan ufi_hdr->controller.sub_vendor_id = 921*82527734SSukumar Swaminathan SWAP32(ufi_hdr->controller.sub_vendor_id); 922*82527734SSukumar Swaminathan ufi_hdr->controller.sub_device_id = 923*82527734SSukumar Swaminathan SWAP32(ufi_hdr->controller.sub_device_id); 924*82527734SSukumar Swaminathan ufi_hdr->file_length = 925*82527734SSukumar Swaminathan SWAP32(ufi_hdr->file_length); 926*82527734SSukumar Swaminathan ufi_hdr->chunk_num = 927*82527734SSukumar Swaminathan SWAP32(ufi_hdr->chunk_num); 928*82527734SSukumar Swaminathan ufi_hdr->chunk_cnt = 929*82527734SSukumar Swaminathan SWAP32(ufi_hdr->chunk_cnt); 930*82527734SSukumar Swaminathan ufi_hdr->image_cnt = 931*82527734SSukumar Swaminathan SWAP32(ufi_hdr->image_cnt); 932*82527734SSukumar Swaminathan #endif /* EMLXS_BIG_ENDIAN */ 933*82527734SSukumar Swaminathan 934*82527734SSukumar Swaminathan if (len != ufi_hdr->file_length) { 935*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 936*82527734SSukumar Swaminathan "Invalid image size (%d != %d)", 937*82527734SSukumar Swaminathan len, ufi_hdr->file_length); 938*82527734SSukumar Swaminathan 939*82527734SSukumar Swaminathan return (EMLXS_IMAGE_BAD); 940*82527734SSukumar Swaminathan } 941*82527734SSukumar Swaminathan 942*82527734SSukumar Swaminathan /* Scan for flash dir signature */ 943*82527734SSukumar Swaminathan bptr = (uint8_t *)buffer; 944*82527734SSukumar Swaminathan flash_dir = NULL; 945*82527734SSukumar Swaminathan for (i = 0; i < len; i++, bptr++) { 946*82527734SSukumar Swaminathan if (strncmp((char *)bptr, BE_DIR_SIGNATURE, 947*82527734SSukumar Swaminathan sizeof (BE_DIR_SIGNATURE)) == 0) { 948*82527734SSukumar Swaminathan flash_dir = (emlxs_sli4_flash_dir_t *)bptr; 949*82527734SSukumar Swaminathan break; 950*82527734SSukumar Swaminathan } 951*82527734SSukumar Swaminathan } 952*82527734SSukumar Swaminathan 953*82527734SSukumar Swaminathan if (!flash_dir) { 954*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 955*82527734SSukumar Swaminathan "Unable to find flash directory."); 956*82527734SSukumar Swaminathan 957*82527734SSukumar Swaminathan return (EMLXS_IMAGE_BAD); 958*82527734SSukumar Swaminathan } 959*82527734SSukumar Swaminathan 960*82527734SSukumar Swaminathan #ifdef EMLXS_BIG_ENDIAN 961*82527734SSukumar Swaminathan /* Big Endian Swapping */ 962*82527734SSukumar Swaminathan /* Swap flash dir */ 963*82527734SSukumar Swaminathan flash_dir->header.format_rev = 964*82527734SSukumar Swaminathan SWAP32(flash_dir->header.format_rev); 965*82527734SSukumar Swaminathan flash_dir->header.checksum = 966*82527734SSukumar Swaminathan SWAP32(flash_dir->header.checksum); 967*82527734SSukumar Swaminathan flash_dir->header.antidote = 968*82527734SSukumar Swaminathan SWAP32(flash_dir->header.antidote); 969*82527734SSukumar Swaminathan flash_dir->header.build_num = 970*82527734SSukumar Swaminathan SWAP32(flash_dir->header.build_num); 971*82527734SSukumar Swaminathan flash_dir->header.active_entry_mask = 972*82527734SSukumar Swaminathan SWAP32(flash_dir->header.active_entry_mask); 973*82527734SSukumar Swaminathan flash_dir->header.valid_entry_mask = 974*82527734SSukumar Swaminathan SWAP32(flash_dir->header.valid_entry_mask); 975*82527734SSukumar Swaminathan flash_dir->header.orig_content_mask = 976*82527734SSukumar Swaminathan SWAP32(flash_dir->header.orig_content_mask); 977*82527734SSukumar Swaminathan flash_dir->header.resv0 = SWAP32(flash_dir->header.resv0); 978*82527734SSukumar Swaminathan flash_dir->header.resv1 = SWAP32(flash_dir->header.resv1); 979*82527734SSukumar Swaminathan flash_dir->header.resv2 = SWAP32(flash_dir->header.resv2); 980*82527734SSukumar Swaminathan flash_dir->header.resv3 = SWAP32(flash_dir->header.resv3); 981*82527734SSukumar Swaminathan flash_dir->header.resv4 = SWAP32(flash_dir->header.resv4); 982*82527734SSukumar Swaminathan 983*82527734SSukumar Swaminathan for (i = 0; i < BE_CONTROLLER_SIZE; i++) { 984*82527734SSukumar Swaminathan flash_dir->header.controller[i].vendor_id = 985*82527734SSukumar Swaminathan SWAP32(flash_dir->header.controller[i].vendor_id); 986*82527734SSukumar Swaminathan flash_dir->header.controller[i].device_id = 987*82527734SSukumar Swaminathan SWAP32(flash_dir->header.controller[i].device_id); 988*82527734SSukumar Swaminathan flash_dir->header.controller[i].sub_vendor_id = 989*82527734SSukumar Swaminathan SWAP32(flash_dir->header.controller[i].sub_vendor_id); 990*82527734SSukumar Swaminathan flash_dir->header.controller[i].sub_device_id = 991*82527734SSukumar Swaminathan SWAP32(flash_dir->header.controller[i].sub_device_id); 992*82527734SSukumar Swaminathan } 993*82527734SSukumar Swaminathan 994*82527734SSukumar Swaminathan for (i = 0, mask = 1; i < BE_FLASH_ENTRIES; i++, mask <<= 1) { 995*82527734SSukumar Swaminathan 996*82527734SSukumar Swaminathan if (!(flash_dir->header.valid_entry_mask & mask)) { 997*82527734SSukumar Swaminathan continue; 998*82527734SSukumar Swaminathan } 999*82527734SSukumar Swaminathan 1000*82527734SSukumar Swaminathan entry = &flash_dir->entry[i]; 1001*82527734SSukumar Swaminathan if (entry->image_size == 0) { 1002*82527734SSukumar Swaminathan continue; 1003*82527734SSukumar Swaminathan } 1004*82527734SSukumar Swaminathan 1005*82527734SSukumar Swaminathan flash_dir->entry[i].type = 1006*82527734SSukumar Swaminathan SWAP32(flash_dir->entry[i].type); 1007*82527734SSukumar Swaminathan flash_dir->entry[i].offset = 1008*82527734SSukumar Swaminathan SWAP32(flash_dir->entry[i].offset); 1009*82527734SSukumar Swaminathan flash_dir->entry[i].pad_size = 1010*82527734SSukumar Swaminathan SWAP32(flash_dir->entry[i].pad_size); 1011*82527734SSukumar Swaminathan flash_dir->entry[i].image_size = 1012*82527734SSukumar Swaminathan SWAP32(flash_dir->entry[i].image_size); 1013*82527734SSukumar Swaminathan flash_dir->entry[i].checksum = 1014*82527734SSukumar Swaminathan SWAP32(flash_dir->entry[i].checksum); 1015*82527734SSukumar Swaminathan flash_dir->entry[i].entry_point = 1016*82527734SSukumar Swaminathan SWAP32(flash_dir->entry[i].entry_point); 1017*82527734SSukumar Swaminathan flash_dir->entry[i].resv0 = 1018*82527734SSukumar Swaminathan SWAP32(flash_dir->entry[i].resv0); 1019*82527734SSukumar Swaminathan flash_dir->entry[i].resv1 = 1020*82527734SSukumar Swaminathan SWAP32(flash_dir->entry[i].resv1); 1021*82527734SSukumar Swaminathan } 1022*82527734SSukumar Swaminathan #endif /* EMLXS_BIG_ENDIAN */ 1023*82527734SSukumar Swaminathan 1024*82527734SSukumar Swaminathan /* Build fw_image table */ 1025*82527734SSukumar Swaminathan for (i = 0, mask = 1; i < BE_FLASH_ENTRIES; i++, mask <<= 1) { 1026*82527734SSukumar Swaminathan 1027*82527734SSukumar Swaminathan if (!(flash_dir->header.valid_entry_mask & mask)) { 1028*82527734SSukumar Swaminathan continue; 1029*82527734SSukumar Swaminathan } 1030*82527734SSukumar Swaminathan 1031*82527734SSukumar Swaminathan entry = &flash_dir->entry[i]; 1032*82527734SSukumar Swaminathan if (entry->image_size == 0) { 1033*82527734SSukumar Swaminathan continue; 1034*82527734SSukumar Swaminathan } 1035*82527734SSukumar Swaminathan 1036*82527734SSukumar Swaminathan switch (entry->type) { 1037*82527734SSukumar Swaminathan case BE_FLASHTYPE_REDBOOT: 1038*82527734SSukumar Swaminathan file = &fw_image->file[REDBOOT_FLASHTYPE]; 1039*82527734SSukumar Swaminathan (void) strcpy(file->label, "REDBOOT"); 1040*82527734SSukumar Swaminathan file->type = MGMT_FLASHROM_OPTYPE_REDBOOT; 1041*82527734SSukumar Swaminathan break; 1042*82527734SSukumar Swaminathan case BE_FLASHTYPE_ISCSI_BIOS: 1043*82527734SSukumar Swaminathan file = &fw_image->file[ISCSI_BIOS_FLASHTYPE]; 1044*82527734SSukumar Swaminathan (void) strcpy(file->label, "ISCSI BIOS"); 1045*82527734SSukumar Swaminathan file->type = MGMT_FLASHROM_OPTYPE_ISCSI_BIOS; 1046*82527734SSukumar Swaminathan break; 1047*82527734SSukumar Swaminathan case BE_FLASHTYPE_PXE_BIOS: 1048*82527734SSukumar Swaminathan file = &fw_image->file[PXE_BIOS_FLASHTYPE]; 1049*82527734SSukumar Swaminathan (void) strcpy(file->label, "PXE BIOS"); 1050*82527734SSukumar Swaminathan file->type = MGMT_FLASHROM_OPTYPE_PXE_BIOS; 1051*82527734SSukumar Swaminathan break; 1052*82527734SSukumar Swaminathan case BE_FLASHTYPE_FCOE_BIOS: 1053*82527734SSukumar Swaminathan file = &fw_image->file[FCOE_BIOS_FLASHTYPE]; 1054*82527734SSukumar Swaminathan (void) strcpy(file->label, "FCOE BIOS"); 1055*82527734SSukumar Swaminathan file->type = MGMT_FLASHROM_OPTYPE_FCOE_BIOS; 1056*82527734SSukumar Swaminathan break; 1057*82527734SSukumar Swaminathan case BE_FLASHTYPE_ISCSI_FIRMWARE: 1058*82527734SSukumar Swaminathan file = &fw_image->file[ISCSI_FIRMWARE_FLASHTYPE]; 1059*82527734SSukumar Swaminathan (void) strcpy(file->label, "ISCSI FIRMWARE"); 1060*82527734SSukumar Swaminathan file->type = MGMT_FLASHROM_OPTYPE_ISCSI_FIRMWARE; 1061*82527734SSukumar Swaminathan break; 1062*82527734SSukumar Swaminathan case BE_FLASHTYPE_FCOE_FIRMWARE: 1063*82527734SSukumar Swaminathan file = &fw_image->file[FCOE_FIRMWARE_FLASHTYPE]; 1064*82527734SSukumar Swaminathan (void) strcpy(file->label, "FCOE FIRMWARE"); 1065*82527734SSukumar Swaminathan file->type = MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE; 1066*82527734SSukumar Swaminathan break; 1067*82527734SSukumar Swaminathan case BE_FLASHTYPE_FCOE_BACKUP: 1068*82527734SSukumar Swaminathan case BE_FLASHTYPE_ISCSI_BACKUP: 1069*82527734SSukumar Swaminathan continue; 1070*82527734SSukumar Swaminathan 1071*82527734SSukumar Swaminathan default: 1072*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1073*82527734SSukumar Swaminathan "Unknown image type found. type=%x", 1074*82527734SSukumar Swaminathan entry->type); 1075*82527734SSukumar Swaminathan continue; 1076*82527734SSukumar Swaminathan } 1077*82527734SSukumar Swaminathan 1078*82527734SSukumar Swaminathan file->image_size = entry->image_size; 1079*82527734SSukumar Swaminathan image_size = BE_SWAP32(entry->image_size); 1080*82527734SSukumar Swaminathan 1081*82527734SSukumar Swaminathan if (ufi_plus) { 1082*82527734SSukumar Swaminathan file->image_offset = entry->offset; 1083*82527734SSukumar Swaminathan file->block_size = entry->pad_size; 1084*82527734SSukumar Swaminathan file->block_crc = entry->checksum; 1085*82527734SSukumar Swaminathan } else { 1086*82527734SSukumar Swaminathan file->image_offset = entry->offset + 1087*82527734SSukumar Swaminathan sizeof (emlxs_sli4_ufi_header_t); 1088*82527734SSukumar Swaminathan 1089*82527734SSukumar Swaminathan /* Get entry block size and crc */ 1090*82527734SSukumar Swaminathan k = file->image_offset + file->image_size; 1091*82527734SSukumar Swaminathan k &= 0xFFFFFFFC; 1092*82527734SSukumar Swaminathan 1093*82527734SSukumar Swaminathan wptr = (uint32_t *)(buffer + k); 1094*82527734SSukumar Swaminathan for (; k < len; k += 4) { 1095*82527734SSukumar Swaminathan if (*wptr++ == image_size) { 1096*82527734SSukumar Swaminathan /* Calculate block_size */ 1097*82527734SSukumar Swaminathan file->block_size = (k + 8) - 1098*82527734SSukumar Swaminathan file->image_offset; 1099*82527734SSukumar Swaminathan 1100*82527734SSukumar Swaminathan /* Read block_crc */ 1101*82527734SSukumar Swaminathan value = *wptr; 1102*82527734SSukumar Swaminathan file->block_crc = BE_SWAP32(value); 1103*82527734SSukumar Swaminathan 1104*82527734SSukumar Swaminathan break; 1105*82527734SSukumar Swaminathan } 1106*82527734SSukumar Swaminathan } 1107*82527734SSukumar Swaminathan 1108*82527734SSukumar Swaminathan if (k >= len) { 1109*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1110*82527734SSukumar Swaminathan "%s: End of block not found. offset=%x", 1111*82527734SSukumar Swaminathan file->label, file->image_offset); 1112*82527734SSukumar Swaminathan 1113*82527734SSukumar Swaminathan bzero(fw_image, sizeof (emlxs_be_fw_image_t)); 1114*82527734SSukumar Swaminathan return (EMLXS_IMAGE_BAD); 1115*82527734SSukumar Swaminathan } 1116*82527734SSukumar Swaminathan } 1117*82527734SSukumar Swaminathan 1118*82527734SSukumar Swaminathan /* Make sure image will fit in block specified */ 1119*82527734SSukumar Swaminathan if (file->image_size + 8 > file->block_size) { 1120*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1121*82527734SSukumar Swaminathan "%s: Image too large for block. image=%x block=%x", 1122*82527734SSukumar Swaminathan file->label, file->image_size, file->block_size); 1123*82527734SSukumar Swaminathan 1124*82527734SSukumar Swaminathan bzero(fw_image, sizeof (emlxs_be_fw_image_t)); 1125*82527734SSukumar Swaminathan return (EMLXS_IMAGE_BAD); 1126*82527734SSukumar Swaminathan } 1127*82527734SSukumar Swaminathan 1128*82527734SSukumar Swaminathan /* Automatically create a backup file entry for firmware */ 1129*82527734SSukumar Swaminathan if (file->type == MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE) { 1130*82527734SSukumar Swaminathan file2 = &fw_image->file[FCOE_BACKUP_FLASHTYPE]; 1131*82527734SSukumar Swaminathan (void) strcpy(file2->label, "FCOE BACKUP"); 1132*82527734SSukumar Swaminathan file2->type = MGMT_FLASHROM_OPTYPE_FCOE_BACKUP; 1133*82527734SSukumar Swaminathan file2->image_offset = file->image_offset; 1134*82527734SSukumar Swaminathan file2->image_size = file->image_size; 1135*82527734SSukumar Swaminathan file2->block_size = file->block_size; 1136*82527734SSukumar Swaminathan file2->block_crc = file->block_crc; 1137*82527734SSukumar Swaminathan 1138*82527734SSukumar Swaminathan /* Save FCOE version info */ 1139*82527734SSukumar Swaminathan bptr = (uint8_t *)buffer + file->image_offset + 0x30; 1140*82527734SSukumar Swaminathan (void) strncpy(fw_image->label, (char *)bptr, 1141*82527734SSukumar Swaminathan BE_VERSION_SIZE); 1142*82527734SSukumar Swaminathan fw_image->version = file->block_crc; 1143*82527734SSukumar Swaminathan 1144*82527734SSukumar Swaminathan } else if (file->type == 1145*82527734SSukumar Swaminathan MGMT_FLASHROM_OPTYPE_ISCSI_FIRMWARE) { 1146*82527734SSukumar Swaminathan file2 = &fw_image->file[ISCSI_BACKUP_FLASHTYPE]; 1147*82527734SSukumar Swaminathan (void) strcpy(file2->label, "ISCSI BACKUP"); 1148*82527734SSukumar Swaminathan file2->type = MGMT_FLASHROM_OPTYPE_ISCSI_BACKUP; 1149*82527734SSukumar Swaminathan file2->image_offset = file->image_offset; 1150*82527734SSukumar Swaminathan file2->image_size = file->image_size; 1151*82527734SSukumar Swaminathan file2->block_size = file->block_size; 1152*82527734SSukumar Swaminathan file2->block_crc = file->block_crc; 1153*82527734SSukumar Swaminathan } 1154*82527734SSukumar Swaminathan } 1155*82527734SSukumar Swaminathan 1156*82527734SSukumar Swaminathan if (fw_image->version == 0) { 1157*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1158*82527734SSukumar Swaminathan "Unable to find FCOE firmware component."); 1159*82527734SSukumar Swaminathan 1160*82527734SSukumar Swaminathan bzero(fw_image, sizeof (emlxs_be_fw_image_t)); 1161*82527734SSukumar Swaminathan return (EMLXS_IMAGE_BAD); 1162*82527734SSukumar Swaminathan } 1163*82527734SSukumar Swaminathan 1164*82527734SSukumar Swaminathan /* Display contents */ 1165*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1166*82527734SSukumar Swaminathan "UFI Image: %08x, %s", fw_image->version, fw_image->label); 1167*82527734SSukumar Swaminathan 1168*82527734SSukumar Swaminathan for (i = 0; i < BE_MAX_FLASHTYPES; i++) { 1169*82527734SSukumar Swaminathan file = &fw_image->file[i]; 1170*82527734SSukumar Swaminathan 1171*82527734SSukumar Swaminathan if (file->image_size == 0) { 1172*82527734SSukumar Swaminathan continue; 1173*82527734SSukumar Swaminathan } 1174*82527734SSukumar Swaminathan 1175*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1176*82527734SSukumar Swaminathan "%s: type=%x block=%x image=%x offset=%x crc=%x", 1177*82527734SSukumar Swaminathan file->label, file->type, file->block_size, 1178*82527734SSukumar Swaminathan file->image_size, file->image_offset, file->block_crc); 1179*82527734SSukumar Swaminathan } 1180*82527734SSukumar Swaminathan 1181*82527734SSukumar Swaminathan return (0); 1182*82527734SSukumar Swaminathan 1183*82527734SSukumar Swaminathan } /* emlxs_sli4_validate_image() */ 1184*82527734SSukumar Swaminathan 1185*82527734SSukumar Swaminathan 1186*82527734SSukumar Swaminathan static int32_t 1187*82527734SSukumar Swaminathan emlxs_sli4_fw_download(emlxs_hba_t *hba, caddr_t buffer, uint32_t len, 1188*82527734SSukumar Swaminathan uint32_t offline) 1189*82527734SSukumar Swaminathan { 1190*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 1191*82527734SSukumar Swaminathan uint32_t i; 1192*82527734SSukumar Swaminathan uint32_t update = 0; 1193*82527734SSukumar Swaminathan uint32_t rval = 0; 1194*82527734SSukumar Swaminathan MAILBOXQ *mbq = NULL; 1195*82527734SSukumar Swaminathan MATCHMAP *mp = NULL; 1196*82527734SSukumar Swaminathan emlxs_be_fw_image_t fw_image; 1197*82527734SSukumar Swaminathan emlxs_be_fw_file_t *file; 1198*82527734SSukumar Swaminathan 1199*82527734SSukumar Swaminathan /* For now we will not take the driver offline during a download */ 1200*82527734SSukumar Swaminathan offline = 0; 1201*82527734SSukumar Swaminathan 1202*82527734SSukumar Swaminathan if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) { 1203*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 1204*82527734SSukumar Swaminathan "Invalid sli_mode. mode=%d", hba->sli_mode); 1205*82527734SSukumar Swaminathan return (EMLXS_IMAGE_INCOMPATIBLE); 1206*82527734SSukumar Swaminathan } 1207*82527734SSukumar Swaminathan 1208*82527734SSukumar Swaminathan if (buffer == NULL || len == 0) { 1209*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1210*82527734SSukumar Swaminathan "Empty buffer provided. buf=%p size=%d", buffer, len); 1211*82527734SSukumar Swaminathan return (EMLXS_IMAGE_BAD); 1212*82527734SSukumar Swaminathan } 1213*82527734SSukumar Swaminathan 1214*82527734SSukumar Swaminathan /* Validate image */ 1215*82527734SSukumar Swaminathan if ((rval = emlxs_sli4_validate_image(hba, buffer, len, &fw_image))) { 1216*82527734SSukumar Swaminathan return (rval); 1217*82527734SSukumar Swaminathan } 1218*82527734SSukumar Swaminathan 1219*82527734SSukumar Swaminathan /* Allocate resources */ 1220*82527734SSukumar Swaminathan 1221*82527734SSukumar Swaminathan if ((mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1222*82527734SSukumar Swaminathan KM_SLEEP)) == NULL) { 1223*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1224*82527734SSukumar Swaminathan "Unable to allocate mailbox buffer."); 1225*82527734SSukumar Swaminathan 1226*82527734SSukumar Swaminathan offline = 0; 1227*82527734SSukumar Swaminathan rval = EMLXS_IMAGE_FAILED; 1228*82527734SSukumar Swaminathan goto done; 1229*82527734SSukumar Swaminathan } 1230*82527734SSukumar Swaminathan 1231*82527734SSukumar Swaminathan if ((mp = emlxs_mem_buf_alloc(hba, (sizeof (mbox_req_hdr_t) + 1232*82527734SSukumar Swaminathan sizeof (IOCTL_COMMON_FLASHROM) + BE_MAX_XFER_SIZE))) == NULL) { 1233*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1234*82527734SSukumar Swaminathan "Unable to allocate flash buffer."); 1235*82527734SSukumar Swaminathan 1236*82527734SSukumar Swaminathan offline = 0; 1237*82527734SSukumar Swaminathan rval = EMLXS_IMAGE_FAILED; 1238*82527734SSukumar Swaminathan goto done; 1239*82527734SSukumar Swaminathan } 1240*82527734SSukumar Swaminathan 1241*82527734SSukumar Swaminathan /* Check if update is required */ 1242*82527734SSukumar Swaminathan for (i = 0; i < BE_MAX_FLASHTYPES; i++) { 1243*82527734SSukumar Swaminathan file = &fw_image.file[i]; 1244*82527734SSukumar Swaminathan 1245*82527734SSukumar Swaminathan if (file->image_size == 0) { 1246*82527734SSukumar Swaminathan continue; 1247*82527734SSukumar Swaminathan } 1248*82527734SSukumar Swaminathan 1249*82527734SSukumar Swaminathan rval = emlxs_sli4_verify_crc(hba, file, mbq, mp); 1250fcf3ce44SJohn Forte 1251*82527734SSukumar Swaminathan if (rval == 0) { 1252*82527734SSukumar Swaminathan file->image_size = 0; 1253*82527734SSukumar Swaminathan continue; 1254*82527734SSukumar Swaminathan } 1255*82527734SSukumar Swaminathan 1256*82527734SSukumar Swaminathan update++; 1257*82527734SSukumar Swaminathan } 1258*82527734SSukumar Swaminathan 1259*82527734SSukumar Swaminathan if (!update) { 1260*82527734SSukumar Swaminathan offline = 0; 1261*82527734SSukumar Swaminathan goto done; 1262*82527734SSukumar Swaminathan } 1263*82527734SSukumar Swaminathan 1264*82527734SSukumar Swaminathan /* 1265*82527734SSukumar Swaminathan * Everything checks out, now to just do it 1266*82527734SSukumar Swaminathan */ 1267*82527734SSukumar Swaminathan if (offline) { 1268*82527734SSukumar Swaminathan if (emlxs_offline(hba) != FC_SUCCESS) { 1269*82527734SSukumar Swaminathan 1270*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1271*82527734SSukumar Swaminathan "Unable to take adapter offline."); 1272*82527734SSukumar Swaminathan 1273*82527734SSukumar Swaminathan offline = 0; 1274*82527734SSukumar Swaminathan rval = EMLXS_OFFLINE_FAILED; 1275*82527734SSukumar Swaminathan goto done; 1276*82527734SSukumar Swaminathan } 1277*82527734SSukumar Swaminathan } 1278*82527734SSukumar Swaminathan 1279*82527734SSukumar Swaminathan /* Download entries which require update */ 1280*82527734SSukumar Swaminathan for (i = 0; i < BE_MAX_FLASHTYPES; i++) { 1281*82527734SSukumar Swaminathan file = &fw_image.file[i]; 1282*82527734SSukumar Swaminathan 1283*82527734SSukumar Swaminathan if (file->image_size == 0) { 1284*82527734SSukumar Swaminathan continue; 1285*82527734SSukumar Swaminathan } 1286*82527734SSukumar Swaminathan 1287*82527734SSukumar Swaminathan rval = emlxs_sli4_flash_image(hba, buffer, file, mbq, mp); 1288*82527734SSukumar Swaminathan 1289*82527734SSukumar Swaminathan if (rval != 0) { 1290*82527734SSukumar Swaminathan goto done; 1291*82527734SSukumar Swaminathan } 1292*82527734SSukumar Swaminathan } 1293*82527734SSukumar Swaminathan 1294*82527734SSukumar Swaminathan done: 1295*82527734SSukumar Swaminathan if (mbq) { 1296*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq); 1297*82527734SSukumar Swaminathan } 1298*82527734SSukumar Swaminathan 1299*82527734SSukumar Swaminathan if (mp) { 1300*82527734SSukumar Swaminathan (void) emlxs_mem_buf_free(hba, mp); 1301*82527734SSukumar Swaminathan } 1302*82527734SSukumar Swaminathan 1303*82527734SSukumar Swaminathan if (offline) { 1304*82527734SSukumar Swaminathan (void) emlxs_online(hba); 1305*82527734SSukumar Swaminathan } 1306*82527734SSukumar Swaminathan 1307*82527734SSukumar Swaminathan if (rval == 0) { 1308*82527734SSukumar Swaminathan if (update) { 1309*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_complete_msg, 1310*82527734SSukumar Swaminathan "Status good."); 1311*82527734SSukumar Swaminathan 1312*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_updated_msg, 1313*82527734SSukumar Swaminathan "Please reboot system or power cycle adapter " 1314*82527734SSukumar Swaminathan "to activate new firmware: %s", fw_image.label); 1315*82527734SSukumar Swaminathan 1316*82527734SSukumar Swaminathan } else { 1317*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1318*82527734SSukumar Swaminathan "No firmware update required."); 1319*82527734SSukumar Swaminathan } 1320*82527734SSukumar Swaminathan } 1321*82527734SSukumar Swaminathan 1322*82527734SSukumar Swaminathan return (rval); 1323*82527734SSukumar Swaminathan 1324*82527734SSukumar Swaminathan } /* emlxs_sli4_fw_download() */ 1325fcf3ce44SJohn Forte 1326fcf3ce44SJohn Forte 1327fcf3ce44SJohn Forte extern int32_t 1328fcf3ce44SJohn Forte emlxs_cfl_download(emlxs_hba_t *hba, uint32_t region, caddr_t buffer, 1329fcf3ce44SJohn Forte uint32_t len) 1330fcf3ce44SJohn Forte { 1331fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1332fcf3ce44SJohn Forte MAILBOXQ *mbox = NULL; 1333fcf3ce44SJohn Forte MAILBOX *mb; 1334fcf3ce44SJohn Forte uint32_t rval = 0; 1335fcf3ce44SJohn Forte uint32_t region_id; 1336fcf3ce44SJohn Forte uint32_t id; 1337*82527734SSukumar Swaminathan #ifdef EMLXS_BIG_ENDIAN 1338fcf3ce44SJohn Forte caddr_t local_buffer; 1339fcf3ce44SJohn Forte uint32_t *bptr1; 1340fcf3ce44SJohn Forte uint32_t *bptr2; 1341fcf3ce44SJohn Forte uint32_t i; 1342*82527734SSukumar Swaminathan #endif /* EMLXS_BIG_ENDIAN */ 1343fcf3ce44SJohn Forte 1344fcf3ce44SJohn Forte if (buffer == NULL || len == 0) { 1345fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 1346fcf3ce44SJohn Forte } 1347*82527734SSukumar Swaminathan 1348*82527734SSukumar Swaminathan #ifdef EMLXS_BIG_ENDIAN 1349fcf3ce44SJohn Forte /* We need to swap the image buffer before we start */ 1350fcf3ce44SJohn Forte 1351fcf3ce44SJohn Forte /* 1352fcf3ce44SJohn Forte * Use KM_SLEEP to allocate a temporary buffer 1353fcf3ce44SJohn Forte */ 1354fcf3ce44SJohn Forte local_buffer = (caddr_t)kmem_zalloc(len, KM_SLEEP); 1355fcf3ce44SJohn Forte 1356fcf3ce44SJohn Forte /* Perform a 32 bit swap of the image */ 1357fcf3ce44SJohn Forte bptr1 = (uint32_t *)local_buffer; 1358fcf3ce44SJohn Forte bptr2 = (uint32_t *)buffer; 1359fcf3ce44SJohn Forte 1360fcf3ce44SJohn Forte for (i = 0; i < (len / 4); i++) { 1361*82527734SSukumar Swaminathan *bptr1 = SWAP32(*bptr2); 1362fcf3ce44SJohn Forte bptr1++; 1363fcf3ce44SJohn Forte bptr2++; 1364fcf3ce44SJohn Forte } 1365fcf3ce44SJohn Forte 1366fcf3ce44SJohn Forte /* Replace the original buffer */ 1367fcf3ce44SJohn Forte buffer = local_buffer; 1368fcf3ce44SJohn Forte 1369*82527734SSukumar Swaminathan #endif /* EMLXS_BIG_ENDIAN */ 1370fcf3ce44SJohn Forte 1371fcf3ce44SJohn Forte if (len > 128) { 1372fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1373291a2b48SSukumar Swaminathan "Invalid image length: 0x%x > 128", len); 1374fcf3ce44SJohn Forte 1375fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 1376fcf3ce44SJohn Forte } 1377291a2b48SSukumar Swaminathan 1378fcf3ce44SJohn Forte /* Check the region number */ 1379fcf3ce44SJohn Forte if ((region > 2) && (region != 0xff)) { 1380fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1381291a2b48SSukumar Swaminathan "Invalid region id: 0x%x", region); 1382fcf3ce44SJohn Forte 1383fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 1384fcf3ce44SJohn Forte 1385fcf3ce44SJohn Forte } 1386291a2b48SSukumar Swaminathan 1387fcf3ce44SJohn Forte /* Check the image vendor id */ 1388fcf3ce44SJohn Forte id = *(int32_t *)buffer; 1389fcf3ce44SJohn Forte if ((id & 0xffff) != 0x10df) { 1390fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 1391291a2b48SSukumar Swaminathan "Invalid image id: 0x%x", id); 1392fcf3ce44SJohn Forte 1393fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 1394fcf3ce44SJohn Forte } 1395291a2b48SSukumar Swaminathan 1396291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1397291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 1398fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1399fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 1400fcf3ce44SJohn Forte 1401fcf3ce44SJohn Forte rval = 1; 1402fcf3ce44SJohn Forte 1403fcf3ce44SJohn Forte goto done; 1404fcf3ce44SJohn Forte } 1405291a2b48SSukumar Swaminathan 1406fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 1407fcf3ce44SJohn Forte 1408fcf3ce44SJohn Forte /* 1409fcf3ce44SJohn Forte * Everything checks out, now to just do it 1410fcf3ce44SJohn Forte */ 1411fcf3ce44SJohn Forte if (emlxs_offline(hba) != FC_SUCCESS) { 1412fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1413fcf3ce44SJohn Forte "Unable to take HBA offline."); 1414fcf3ce44SJohn Forte 1415fcf3ce44SJohn Forte rval = EMLXS_OFFLINE_FAILED; 1416fcf3ce44SJohn Forte 1417fcf3ce44SJohn Forte goto done; 1418fcf3ce44SJohn Forte } 1419291a2b48SSukumar Swaminathan 1420*82527734SSukumar Swaminathan if (EMLXS_SLI_HBA_RESET(hba, 1, 1, 0) != FC_SUCCESS) { 1421fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1422fcf3ce44SJohn Forte "Unable to restart adapter."); 1423fcf3ce44SJohn Forte 1424fcf3ce44SJohn Forte rval = EMLXS_OFFLINE_FAILED; 1425fcf3ce44SJohn Forte 1426fcf3ce44SJohn Forte goto done; 1427fcf3ce44SJohn Forte } 1428291a2b48SSukumar Swaminathan 1429fcf3ce44SJohn Forte /* Check if default region is requested */ 1430fcf3ce44SJohn Forte if (region == 0xff) { 1431fcf3ce44SJohn Forte /* 1432291a2b48SSukumar Swaminathan * Sun-branded Helios and Zypher have different 1433291a2b48SSukumar Swaminathan * default PCI region 1434fcf3ce44SJohn Forte */ 1435fcf3ce44SJohn Forte if ((hba->model_info.flags & EMLXS_SUN_BRANDED) && 1436fcf3ce44SJohn Forte (hba->model_info.chip & 1437fcf3ce44SJohn Forte (EMLXS_HELIOS_CHIP | EMLXS_ZEPHYR_CHIP))) { 1438fcf3ce44SJohn Forte region = 2; 1439fcf3ce44SJohn Forte } else { 1440fcf3ce44SJohn Forte region = 0; 1441fcf3ce44SJohn Forte } 1442fcf3ce44SJohn Forte } 1443291a2b48SSukumar Swaminathan 1444fcf3ce44SJohn Forte /* Set region id based on PCI region requested */ 1445fcf3ce44SJohn Forte region_id = DEF_PCI_CFG_REGION_ID + region; 1446fcf3ce44SJohn Forte 1447fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1448291a2b48SSukumar Swaminathan "PCI configuration: PCI%d region=%d id=0x%x size=%d", region, 1449291a2b48SSukumar Swaminathan region_id, id, len); 1450fcf3ce44SJohn Forte 1451fcf3ce44SJohn Forte /* Copy the data buffer to SLIM */ 1452fcf3ce44SJohn Forte WRITE_SLIM_COPY(hba, (uint32_t *)buffer, 1453*82527734SSukumar Swaminathan (volatile uint32_t *)((volatile char *)hba->sli.sli3.slim_addr + 1454291a2b48SSukumar Swaminathan sizeof (MAILBOX)), (len / sizeof (uint32_t))); 1455fcf3ce44SJohn Forte 14564baa2c25SSukumar Swaminathan #ifdef FMA_SUPPORT 1457*82527734SSukumar Swaminathan if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle) 14584baa2c25SSukumar Swaminathan != DDI_FM_OK) { 14594baa2c25SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 14604baa2c25SSukumar Swaminathan &emlxs_invalid_access_handle_msg, NULL); 14614baa2c25SSukumar Swaminathan rval = 1; 14624baa2c25SSukumar Swaminathan } 14634baa2c25SSukumar Swaminathan #endif /* FMA_SUPPORT */ 14644baa2c25SSukumar Swaminathan 1465*82527734SSukumar Swaminathan emlxs_format_update_pci_cfg(hba, mbox, region_id, len); 1466fcf3ce44SJohn Forte 1467*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 1468fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1469291a2b48SSukumar Swaminathan "Unable to update PCI configuration: Mailbox cmd=%x " 1470291a2b48SSukumar Swaminathan "status=%x info=%d", mb->mbxCommand, mb->mbxStatus, 1471fcf3ce44SJohn Forte mb->un.varUpdateCfg.rsp_info); 1472fcf3ce44SJohn Forte 1473fcf3ce44SJohn Forte rval = 1; 1474fcf3ce44SJohn Forte } 1475291a2b48SSukumar Swaminathan 1476fcf3ce44SJohn Forte (void) emlxs_online(hba); 1477fcf3ce44SJohn Forte 1478fcf3ce44SJohn Forte if (rval == 0) { 1479fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_complete_msg, 1480fcf3ce44SJohn Forte "Status good."); 1481fcf3ce44SJohn Forte } 1482291a2b48SSukumar Swaminathan 1483fcf3ce44SJohn Forte done: 1484fcf3ce44SJohn Forte 1485fcf3ce44SJohn Forte if (mbox) { 1486fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 1487fcf3ce44SJohn Forte } 1488*82527734SSukumar Swaminathan 1489*82527734SSukumar Swaminathan #ifdef EMLXS_BIG_ENDIAN 1490fcf3ce44SJohn Forte /* Free the local buffer */ 1491fcf3ce44SJohn Forte kmem_free(local_buffer, len); 1492*82527734SSukumar Swaminathan #endif /* EMLXS_BIG_ENDIAN */ 1493fcf3ce44SJohn Forte 1494fcf3ce44SJohn Forte return (rval); 1495fcf3ce44SJohn Forte 1496*82527734SSukumar Swaminathan } /* emlxs_cfl_download */ 1497fcf3ce44SJohn Forte 1498fcf3ce44SJohn Forte 1499fcf3ce44SJohn Forte static uint32_t 1500fcf3ce44SJohn Forte emlxs_valid_cksum(uint32_t *StartAddr, uint32_t *EndAddr) 1501fcf3ce44SJohn Forte { 1502fcf3ce44SJohn Forte uint32_t Temp; 1503fcf3ce44SJohn Forte uint32_t CkSum; 1504fcf3ce44SJohn Forte 1505fcf3ce44SJohn Forte EndAddr++; 1506fcf3ce44SJohn Forte CkSum = SLI_CKSUM_SEED; 1507fcf3ce44SJohn Forte 1508fcf3ce44SJohn Forte CkSum = (CkSum >> 1) | (CkSum << 31); 1509fcf3ce44SJohn Forte while (StartAddr != EndAddr) { 1510fcf3ce44SJohn Forte CkSum = (CkSum << 1) | (CkSum >> 31); 1511fcf3ce44SJohn Forte Temp = *StartAddr; 1512fcf3ce44SJohn Forte 1513fcf3ce44SJohn Forte CkSum ^= Temp; 1514fcf3ce44SJohn Forte StartAddr++; 1515fcf3ce44SJohn Forte } 1516fcf3ce44SJohn Forte 1517fcf3ce44SJohn Forte return (CkSum << 1) | (CkSum >> 31); 1518fcf3ce44SJohn Forte 1519*82527734SSukumar Swaminathan } /* emlxs_valid_cksum() */ 1520fcf3ce44SJohn Forte 1521fcf3ce44SJohn Forte 1522fcf3ce44SJohn Forte static void 1523fcf3ce44SJohn Forte emlxs_disp_aif_header(emlxs_hba_t *hba, PAIF_HDR AifHdr) 1524fcf3ce44SJohn Forte { 1525fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1526fcf3ce44SJohn Forte 1527291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "AIF Header: "); 1528fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1529fcf3ce44SJohn Forte "AIF Header: compress_br = 0x%x", AifHdr->CompressBr); 1530fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1531fcf3ce44SJohn Forte "AIF Header: reloc_br = 0x%x", AifHdr->RelocBr); 1532fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1533fcf3ce44SJohn Forte "AIF Header: zinit_br = 0x%x", AifHdr->ZinitBr); 1534fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1535fcf3ce44SJohn Forte "AIF Header: entry_br = 0x%x", AifHdr->EntryBr); 1536fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1537fcf3ce44SJohn Forte "AIF Header: area_id = 0x%x", AifHdr->Area_ID); 1538fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1539fcf3ce44SJohn Forte "AIF Header: rosize = 0x%x", AifHdr->RoSize); 1540fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1541fcf3ce44SJohn Forte "AIF Header: dbgsize = 0x%x", AifHdr->DbgSize); 1542fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1543fcf3ce44SJohn Forte "AIF Header: zinitsize = 0x%x", AifHdr->ZinitSize); 1544fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1545fcf3ce44SJohn Forte "AIF Header: dbgtype = 0x%x", AifHdr->DbgType); 1546fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1547fcf3ce44SJohn Forte "AIF Header: imagebase = 0x%x", AifHdr->ImageBase); 1548fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1549fcf3ce44SJohn Forte "AIF Header: area_size = 0x%x", AifHdr->Area_Size); 1550fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1551fcf3ce44SJohn Forte "AIF Header: address_mode = 0x%x", AifHdr->AddressMode); 1552fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1553fcf3ce44SJohn Forte "AIF Header: database = 0x%x", AifHdr->DataBase); 1554fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1555fcf3ce44SJohn Forte "AIF Header: aversion = 0x%x", AifHdr->AVersion); 1556fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1557fcf3ce44SJohn Forte "AIF Header: spare2 = 0x%x", AifHdr->Spare2); 1558fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1559fcf3ce44SJohn Forte "AIF Header: debug_swi = 0x%x", AifHdr->DebugSwi); 1560fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1561fcf3ce44SJohn Forte "AIF Header: zinitcode[0] = 0x%x", AifHdr->ZinitCode[0]); 1562fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1563fcf3ce44SJohn Forte "AIF Header: zinitcode[1] = 0x%x", AifHdr->ZinitCode[1]); 1564fcf3ce44SJohn Forte 1565*82527734SSukumar Swaminathan } /* emlxs_disp_aif_header() */ 1566fcf3ce44SJohn Forte 1567fcf3ce44SJohn Forte 1568fcf3ce44SJohn Forte 1569fcf3ce44SJohn Forte static void 1570fcf3ce44SJohn Forte emlxs_dump_image_header(emlxs_hba_t *hba, PIMAGE_HDR image) 1571fcf3ce44SJohn Forte { 1572fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1573fcf3ce44SJohn Forte 1574291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "Img Header: "); 1575fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1576fcf3ce44SJohn Forte "Img Header: BlockSize = 0x%x", image->BlockSize); 1577fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1578fcf3ce44SJohn Forte "Img Header: PROG_ID Type = 0x%x", image->Id.Type); 1579fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1580fcf3ce44SJohn Forte "Img Header: PROG_ID Id = 0x%x", image->Id.Id); 1581fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1582fcf3ce44SJohn Forte "Img Header: PROG_ID Ver = 0x%x", image->Id.Ver); 1583fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1584fcf3ce44SJohn Forte "Img Header: PROG_ID Rev = 0x%x", image->Id.Rev); 1585fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1586fcf3ce44SJohn Forte "Img Header: PROG_ID revcomp = 0x%x", image->Id.un.revcomp); 1587fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1588fcf3ce44SJohn Forte "Img Header: Flags = 0x%x", image->Flags); 1589fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1590fcf3ce44SJohn Forte "Img Header: EntryAdr = 0x%x", image->EntryAdr); 1591fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1592fcf3ce44SJohn Forte "Img Header: InitAdr = 0x%x", image->InitAdr); 1593fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1594fcf3ce44SJohn Forte "Img Header: ExitAdr = 0x%x", image->ExitAdr); 1595fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1596fcf3ce44SJohn Forte "Img Header: ImageBase = 0x%x", image->ImageBase); 1597fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1598fcf3ce44SJohn Forte "Img Header: ImageSize = 0x%x", image->ImageSize); 1599fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1600fcf3ce44SJohn Forte "Img Header: ZinitSize = 0x%x", image->ZinitSize); 1601fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1602fcf3ce44SJohn Forte "Img Header: RelocSize = 0x%x", image->RelocSize); 1603fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 1604fcf3ce44SJohn Forte "Img Header: HdrCks = 0x%x", image->HdrCks); 1605fcf3ce44SJohn Forte 1606*82527734SSukumar Swaminathan } /* emlxs_dump_image_header() */ 1607fcf3ce44SJohn Forte 1608fcf3ce44SJohn Forte 1609fcf3ce44SJohn Forte static void 1610*82527734SSukumar Swaminathan emlxs_format_dump(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t Type, 1611*82527734SSukumar Swaminathan uint32_t RegionId, uint32_t WordCount, uint32_t BaseAddr) 1612fcf3ce44SJohn Forte { 1613fcf3ce44SJohn Forte 1614*82527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 1615*82527734SSukumar Swaminathan MAILBOX4 *mb = (MAILBOX4 *)mbq; 1616*82527734SSukumar Swaminathan 1617*82527734SSukumar Swaminathan /* Clear the local dump_region */ 1618*82527734SSukumar Swaminathan bzero(hba->sli.sli4.dump_region.virt, 1619*82527734SSukumar Swaminathan hba->sli.sli4.dump_region.size); 1620*82527734SSukumar Swaminathan 1621*82527734SSukumar Swaminathan bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 1622*82527734SSukumar Swaminathan 1623*82527734SSukumar Swaminathan mb->mbxCommand = MBX_DUMP_MEMORY; 1624*82527734SSukumar Swaminathan mb->un.varDmp4.type = Type; 1625*82527734SSukumar Swaminathan mb->un.varDmp4.entry_index = BaseAddr; 1626*82527734SSukumar Swaminathan mb->un.varDmp4.region_id = RegionId; 1627*82527734SSukumar Swaminathan 1628*82527734SSukumar Swaminathan mb->un.varDmp4.available_cnt = min((WordCount*4), 1629*82527734SSukumar Swaminathan hba->sli.sli4.dump_region.size); 1630*82527734SSukumar Swaminathan mb->un.varDmp4.addrHigh = 1631*82527734SSukumar Swaminathan PADDR_HI(hba->sli.sli4.dump_region.phys); 1632*82527734SSukumar Swaminathan mb->un.varDmp4.addrLow = 1633*82527734SSukumar Swaminathan PADDR_LO(hba->sli.sli4.dump_region.phys); 1634*82527734SSukumar Swaminathan mb->un.varDmp4.rsp_cnt = 0; 1635*82527734SSukumar Swaminathan 1636*82527734SSukumar Swaminathan mb->mbxOwner = OWN_HOST; 1637*82527734SSukumar Swaminathan 1638*82527734SSukumar Swaminathan } else { 1639*82527734SSukumar Swaminathan MAILBOX *mb = (MAILBOX *)mbq; 1640*82527734SSukumar Swaminathan 1641*82527734SSukumar Swaminathan bzero((void *)mb, MAILBOX_CMD_BSIZE); 1642*82527734SSukumar Swaminathan 1643*82527734SSukumar Swaminathan mb->mbxCommand = MBX_DUMP_MEMORY; 1644*82527734SSukumar Swaminathan mb->un.varDmp.type = Type; 1645*82527734SSukumar Swaminathan mb->un.varDmp.region_id = RegionId; 1646*82527734SSukumar Swaminathan mb->un.varDmp.word_cnt = WordCount; 1647*82527734SSukumar Swaminathan mb->un.varDmp.base_adr = BaseAddr; 1648*82527734SSukumar Swaminathan mb->mbxOwner = OWN_HOST; 1649*82527734SSukumar Swaminathan } 1650*82527734SSukumar Swaminathan 1651*82527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; /* no cmpl needed */ 1652fcf3ce44SJohn Forte 1653fcf3ce44SJohn Forte return; 1654fcf3ce44SJohn Forte 1655*82527734SSukumar Swaminathan } /* emlxs_format_dump() */ 1656fcf3ce44SJohn Forte 1657fcf3ce44SJohn Forte 1658fcf3ce44SJohn Forte /* ARGSUSED */ 1659fcf3ce44SJohn Forte static uint32_t 1660291a2b48SSukumar Swaminathan emlxs_start_abs_download(emlxs_hba_t *hba, 1661291a2b48SSukumar Swaminathan PAIF_HDR AifHdr, 1662291a2b48SSukumar Swaminathan caddr_t Buffer, 1663291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, 1664291a2b48SSukumar Swaminathan uint32_t MaxRbusSramSize, 1665fcf3ce44SJohn Forte uint32_t MaxIbusSramSize, PWAKE_UP_PARMS AbsWakeUpParms, int32_t DwcFile) 1666fcf3ce44SJohn Forte { 1667fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1668fcf3ce44SJohn Forte uint32_t DlByteCount = AifHdr->RoSize + AifHdr->RwSize; 1669fcf3ce44SJohn Forte IMAGE_HDR ImageHdr; 1670fcf3ce44SJohn Forte uint32_t *Src; 1671fcf3ce44SJohn Forte uint32_t *Dst; 1672fcf3ce44SJohn Forte caddr_t DataBuffer = NULL; 1673fcf3ce44SJohn Forte MAILBOXQ *mbox; 1674fcf3ce44SJohn Forte MAILBOX *mb; 1675fcf3ce44SJohn Forte uint32_t rval = 1; 1676fcf3ce44SJohn Forte uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT; 1677fcf3ce44SJohn Forte uint32_t DlToAddr = AifHdr->ImageBase; 1678fcf3ce44SJohn Forte uint32_t DlCount; 1679fcf3ce44SJohn Forte uint32_t i; 1680fcf3ce44SJohn Forte 1681fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1682fcf3ce44SJohn Forte "Performing absolute download..."); 1683fcf3ce44SJohn Forte 1684291a2b48SSukumar Swaminathan if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT, 1685291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 1686fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1687fcf3ce44SJohn Forte "Unable to allocate data buffer."); 1688fcf3ce44SJohn Forte 1689fcf3ce44SJohn Forte return (rval); 1690fcf3ce44SJohn Forte } 1691291a2b48SSukumar Swaminathan 1692291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1693291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 1694fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1695fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 1696fcf3ce44SJohn Forte 1697fcf3ce44SJohn Forte kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 1698fcf3ce44SJohn Forte 1699fcf3ce44SJohn Forte return (rval); 1700fcf3ce44SJohn Forte } 1701291a2b48SSukumar Swaminathan 1702fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 1703fcf3ce44SJohn Forte 1704fcf3ce44SJohn Forte Buffer += sizeof (AIF_HDR); 1705fcf3ce44SJohn Forte 1706291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, "Erasing flash..."); 1707fcf3ce44SJohn Forte 1708fcf3ce44SJohn Forte if (DwcFile) { 1709*82527734SSukumar Swaminathan emlxs_format_prog_flash(mbox, 0x20000, 0x50000, ERASE_FLASH, 0, 1710291a2b48SSukumar Swaminathan 0, 0, NULL); 1711fcf3ce44SJohn Forte } else { 1712*82527734SSukumar Swaminathan emlxs_format_prog_flash(mbox, DlToAddr, DlByteCount, 1713291a2b48SSukumar Swaminathan ERASE_FLASH, 0, 0, 0, NULL); 1714fcf3ce44SJohn Forte } 1715fcf3ce44SJohn Forte 1716*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 1717fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1718fcf3ce44SJohn Forte "Unable to erase Flash: Mailbox cmd=%x status=%x", 1719fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 1720fcf3ce44SJohn Forte 1721fcf3ce44SJohn Forte rval = 1; 1722fcf3ce44SJohn Forte 1723fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 1724fcf3ce44SJohn Forte } 1725291a2b48SSukumar Swaminathan 1726291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1727291a2b48SSukumar Swaminathan "Programming flash..."); 1728fcf3ce44SJohn Forte 1729fcf3ce44SJohn Forte while (DlByteCount) { 1730fcf3ce44SJohn Forte 1731fcf3ce44SJohn Forte if (DlByteCount > SegSize) { 1732fcf3ce44SJohn Forte DlCount = SegSize; 1733fcf3ce44SJohn Forte } else { 1734fcf3ce44SJohn Forte DlCount = DlByteCount; 1735fcf3ce44SJohn Forte } 1736fcf3ce44SJohn Forte DlByteCount -= DlCount; 1737fcf3ce44SJohn Forte 1738fcf3ce44SJohn Forte Dst = (uint32_t *)DataBuffer; 1739fcf3ce44SJohn Forte Src = (uint32_t *)Buffer; 1740fcf3ce44SJohn Forte 1741fcf3ce44SJohn Forte for (i = 0; i < (DlCount / 4); i++) { 1742fcf3ce44SJohn Forte *Dst = *Src; 1743fcf3ce44SJohn Forte Dst++; 1744fcf3ce44SJohn Forte Src++; 1745fcf3ce44SJohn Forte } 1746fcf3ce44SJohn Forte 1747fcf3ce44SJohn Forte WRITE_SLIM_COPY(hba, (uint32_t *)DataBuffer, 1748*82527734SSukumar Swaminathan (volatile uint32_t *) 1749*82527734SSukumar Swaminathan ((volatile char *)hba->sli.sli3.slim_addr + 1750291a2b48SSukumar Swaminathan sizeof (MAILBOX)), (DlCount / sizeof (uint32_t))); 1751fcf3ce44SJohn Forte 1752*82527734SSukumar Swaminathan emlxs_format_prog_flash(mbox, DlToAddr, DlCount, 1753291a2b48SSukumar Swaminathan PROGRAM_FLASH, (DlByteCount) ? 0 : 1, 0, DlCount, NULL); 1754fcf3ce44SJohn Forte 1755*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 1756291a2b48SSukumar Swaminathan MBX_SUCCESS) { 1757fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1758fcf3ce44SJohn Forte "Unable to program Flash: Mailbox cmd=%x status=%x", 1759fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 1760fcf3ce44SJohn Forte 1761fcf3ce44SJohn Forte rval = 1; 1762fcf3ce44SJohn Forte 1763fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 1764fcf3ce44SJohn Forte } 1765291a2b48SSukumar Swaminathan 1766fcf3ce44SJohn Forte Buffer += DlCount; 1767fcf3ce44SJohn Forte DlToAddr += DlCount; 1768fcf3ce44SJohn Forte } 1769fcf3ce44SJohn Forte 17704baa2c25SSukumar Swaminathan #ifdef FMA_SUPPORT 1771*82527734SSukumar Swaminathan if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle) 17724baa2c25SSukumar Swaminathan != DDI_FM_OK) { 17734baa2c25SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 17744baa2c25SSukumar Swaminathan &emlxs_invalid_access_handle_msg, NULL); 17754baa2c25SSukumar Swaminathan 17764baa2c25SSukumar Swaminathan rval = 1; 17774baa2c25SSukumar Swaminathan 17784baa2c25SSukumar Swaminathan goto EXIT_ABS_DOWNLOAD; 17794baa2c25SSukumar Swaminathan } 17804baa2c25SSukumar Swaminathan #endif /* FMA_SUPPORT */ 17814baa2c25SSukumar Swaminathan 1782fcf3ce44SJohn Forte bzero((caddr_t)&ImageHdr, sizeof (IMAGE_HDR)); 1783fcf3ce44SJohn Forte ImageHdr.Id.Type = FUNC_FIRMWARE; 1784fcf3ce44SJohn Forte 1785fcf3ce44SJohn Forte switch (MaxRbusSramSize) { 1786fcf3ce44SJohn Forte case REDUCED_RBUS_SRAM_CFG: 1787fcf3ce44SJohn Forte ImageHdr.Id.Id = REDUCED_SRAM_CFG_PROG_ID; 1788fcf3ce44SJohn Forte break; 1789fcf3ce44SJohn Forte case FULL_RBUS_SRAM_CFG: 1790fcf3ce44SJohn Forte ImageHdr.Id.Id = FULL_SRAM_CFG_PROG_ID; 1791fcf3ce44SJohn Forte break; 1792fcf3ce44SJohn Forte default: 1793fcf3ce44SJohn Forte ImageHdr.Id.Id = OTHER_SRAM_CFG_PROG_ID; 1794fcf3ce44SJohn Forte break; 1795fcf3ce44SJohn Forte } 1796fcf3ce44SJohn Forte 1797fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, "Updating params..."); 1798fcf3ce44SJohn Forte 1799fcf3ce44SJohn Forte if (AbsWakeUpParms) { 1800291a2b48SSukumar Swaminathan rval = 1801291a2b48SSukumar Swaminathan emlxs_update_wakeup_parms(hba, AbsWakeUpParms, 1802fcf3ce44SJohn Forte WakeUpParms); 1803fcf3ce44SJohn Forte } else { 1804291a2b48SSukumar Swaminathan rval = 1805291a2b48SSukumar Swaminathan emlxs_update_boot_wakeup_parms(hba, WakeUpParms, 1806fcf3ce44SJohn Forte &ImageHdr.Id, 1); 1807fcf3ce44SJohn Forte } 1808fcf3ce44SJohn Forte 1809fcf3ce44SJohn Forte EXIT_ABS_DOWNLOAD: 1810fcf3ce44SJohn Forte if (DataBuffer) { 1811fcf3ce44SJohn Forte kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 1812fcf3ce44SJohn Forte } 1813291a2b48SSukumar Swaminathan 1814fcf3ce44SJohn Forte if (mbox) { 1815fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 1816fcf3ce44SJohn Forte } 1817291a2b48SSukumar Swaminathan 1818fcf3ce44SJohn Forte return (rval); 1819fcf3ce44SJohn Forte 1820*82527734SSukumar Swaminathan } /* emlxs_start_abs_download() */ 1821fcf3ce44SJohn Forte 1822fcf3ce44SJohn Forte 1823fcf3ce44SJohn Forte /* ARGSUSED */ 1824fcf3ce44SJohn Forte static void 1825*82527734SSukumar Swaminathan emlxs_format_prog_flash(MAILBOXQ *mbq, 1826291a2b48SSukumar Swaminathan uint32_t Base, 1827291a2b48SSukumar Swaminathan uint32_t DlByteCount, 1828291a2b48SSukumar Swaminathan uint32_t Function, 1829291a2b48SSukumar Swaminathan uint32_t Complete, 1830291a2b48SSukumar Swaminathan uint32_t BdeAddress, uint32_t BdeSize, PROG_ID *ProgId) 1831fcf3ce44SJohn Forte { 1832*82527734SSukumar Swaminathan MAILBOX *mb = (MAILBOX *)mbq; 1833*82527734SSukumar Swaminathan 1834291a2b48SSukumar Swaminathan bzero((void *)mb, MAILBOX_CMD_BSIZE); 1835fcf3ce44SJohn Forte 1836fcf3ce44SJohn Forte if (ProgId) 1837fcf3ce44SJohn Forte mb->mbxCommand = MBX_DOWN_LOAD; 1838fcf3ce44SJohn Forte else 1839fcf3ce44SJohn Forte mb->mbxCommand = MBX_LOAD_SM; 1840fcf3ce44SJohn Forte 1841fcf3ce44SJohn Forte mb->un.varLdSM.load_cmplt = Complete; 1842fcf3ce44SJohn Forte mb->un.varLdSM.method = DL_FROM_SLIM; 1843fcf3ce44SJohn Forte mb->un.varLdSM.update_flash = 1; 1844fcf3ce44SJohn Forte mb->un.varLdSM.erase_or_prog = Function; 1845fcf3ce44SJohn Forte mb->un.varLdSM.dl_to_adr = Base; 1846fcf3ce44SJohn Forte mb->un.varLdSM.dl_len = DlByteCount; 1847fcf3ce44SJohn Forte 1848fcf3ce44SJohn Forte if (BdeSize) { 1849fcf3ce44SJohn Forte mb->un.varLdSM.un.dl_from_slim_offset = DL_FROM_SLIM_OFFSET; 1850fcf3ce44SJohn Forte } else if (ProgId) { 1851fcf3ce44SJohn Forte mb->un.varLdSM.un.prog_id = *ProgId; 1852fcf3ce44SJohn Forte } else { 1853fcf3ce44SJohn Forte mb->un.varLdSM.un.dl_from_slim_offset = 0; 1854fcf3ce44SJohn Forte } 1855fcf3ce44SJohn Forte 1856fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 1857*82527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 1858fcf3ce44SJohn Forte 1859*82527734SSukumar Swaminathan } /* emlxs_format_prog_flash() */ 1860fcf3ce44SJohn Forte 1861fcf3ce44SJohn Forte 1862fcf3ce44SJohn Forte static void 1863*82527734SSukumar Swaminathan emlxs_format_update_parms(MAILBOXQ *mbq, PWAKE_UP_PARMS WakeUpParms) 1864fcf3ce44SJohn Forte { 1865*82527734SSukumar Swaminathan MAILBOX *mb = (MAILBOX *)mbq; 1866*82527734SSukumar Swaminathan 1867fcf3ce44SJohn Forte bzero((void *)mb, MAILBOX_CMD_BSIZE); 1868fcf3ce44SJohn Forte 1869fcf3ce44SJohn Forte mb->mbxCommand = MBX_UPDATE_CFG; 1870fcf3ce44SJohn Forte mb->un.varUpdateCfg.req_type = UPDATE_DATA; 1871fcf3ce44SJohn Forte mb->un.varUpdateCfg.region_id = WAKE_UP_PARMS_REGION_ID; 1872fcf3ce44SJohn Forte mb->un.varUpdateCfg.entry_len = sizeof (WAKE_UP_PARMS); 1873fcf3ce44SJohn Forte mb->un.varUpdateCfg.byte_len = sizeof (WAKE_UP_PARMS); 1874fcf3ce44SJohn Forte 1875291a2b48SSukumar Swaminathan bcopy((caddr_t)WakeUpParms, 1876291a2b48SSukumar Swaminathan (caddr_t)&(mb->un.varUpdateCfg.cfg_data), 1877fcf3ce44SJohn Forte sizeof (WAKE_UP_PARMS)); 1878*82527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 1879fcf3ce44SJohn Forte 1880*82527734SSukumar Swaminathan } /* emlxs_format_update_parms () */ 1881fcf3ce44SJohn Forte 1882fcf3ce44SJohn Forte 1883fcf3ce44SJohn Forte /* ARGSUSED */ 1884fcf3ce44SJohn Forte static void 1885*82527734SSukumar Swaminathan emlxs_format_update_pci_cfg(emlxs_hba_t *hba, MAILBOXQ *mbq, 1886fcf3ce44SJohn Forte uint32_t region_id, uint32_t size) 1887fcf3ce44SJohn Forte { 1888*82527734SSukumar Swaminathan MAILBOX *mb = (MAILBOX *)mbq; 1889*82527734SSukumar Swaminathan 1890fcf3ce44SJohn Forte bzero((void *)mb, MAILBOX_CMD_BSIZE); 1891fcf3ce44SJohn Forte 1892fcf3ce44SJohn Forte mb->mbxCommand = MBX_UPDATE_CFG; 1893fcf3ce44SJohn Forte mb->un.varUpdateCfg.Vbit = 1; 1894fcf3ce44SJohn Forte mb->un.varUpdateCfg.Obit = 1; 1895fcf3ce44SJohn Forte mb->un.varUpdateCfg.cfg_data = DL_FROM_SLIM_OFFSET; 1896fcf3ce44SJohn Forte mb->un.varUpdateCfg.req_type = UPDATE_DATA; 1897fcf3ce44SJohn Forte mb->un.varUpdateCfg.region_id = region_id; 1898fcf3ce44SJohn Forte mb->un.varUpdateCfg.entry_len = size; 1899fcf3ce44SJohn Forte mb->un.varUpdateCfg.byte_len = size; 1900*82527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 1901fcf3ce44SJohn Forte 1902*82527734SSukumar Swaminathan } /* emlxs_format_update_pci_cfg() */ 1903fcf3ce44SJohn Forte 1904fcf3ce44SJohn Forte 1905fcf3ce44SJohn Forte 1906fcf3ce44SJohn Forte static uint32_t 1907fcf3ce44SJohn Forte emlxs_update_boot_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 1908fcf3ce44SJohn Forte PROG_ID * prog_id, uint32_t proc_erom) 1909fcf3ce44SJohn Forte { 1910fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1911fcf3ce44SJohn Forte MAILBOX *mb; 1912fcf3ce44SJohn Forte MAILBOXQ *mbox; 1913fcf3ce44SJohn Forte uint32_t rval = 0; 1914fcf3ce44SJohn Forte 1915291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1916291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 1917fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1918fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 1919fcf3ce44SJohn Forte 1920fcf3ce44SJohn Forte return (1); 1921fcf3ce44SJohn Forte } 1922fcf3ce44SJohn Forte 1923291a2b48SSukumar Swaminathan mb = (MAILBOX *)mbox; 1924291a2b48SSukumar Swaminathan 1925291a2b48SSukumar Swaminathan if (proc_erom && !(hba->model_info.chip & 1926fcf3ce44SJohn Forte (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 1927fcf3ce44SJohn Forte WakeUpParms->u1.EROM_prog_id = *prog_id; 1928fcf3ce44SJohn Forte (void) emlxs_update_exp_rom(hba, WakeUpParms); 1929fcf3ce44SJohn Forte } 1930291a2b48SSukumar Swaminathan 1931fcf3ce44SJohn Forte WakeUpParms->u0.boot_bios_id = *prog_id; 1932fcf3ce44SJohn Forte 1933*82527734SSukumar Swaminathan emlxs_format_update_parms(mbox, WakeUpParms); 1934fcf3ce44SJohn Forte 1935*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 1936fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1937291a2b48SSukumar Swaminathan "Unable to update boot wakeup parms: Mailbox cmd=%x " 1938291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 1939fcf3ce44SJohn Forte 1940fcf3ce44SJohn Forte rval = 1; 1941fcf3ce44SJohn Forte } 1942291a2b48SSukumar Swaminathan 1943fcf3ce44SJohn Forte if (mbox) { 1944fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 1945fcf3ce44SJohn Forte } 1946291a2b48SSukumar Swaminathan 1947fcf3ce44SJohn Forte return (rval); 1948fcf3ce44SJohn Forte 1949*82527734SSukumar Swaminathan } /* emlxs_update_boot_wakeup_parms() */ 1950fcf3ce44SJohn Forte 1951fcf3ce44SJohn Forte 1952fcf3ce44SJohn Forte 1953fcf3ce44SJohn Forte static uint32_t 1954fcf3ce44SJohn Forte emlxs_update_ff_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 1955fcf3ce44SJohn Forte PROG_ID *prog_id) 1956fcf3ce44SJohn Forte { 1957fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1958fcf3ce44SJohn Forte uint32_t rval = 0; 1959fcf3ce44SJohn Forte MAILBOXQ *mbox; 1960fcf3ce44SJohn Forte MAILBOX *mb; 1961fcf3ce44SJohn Forte 1962291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1963291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 1964fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1965fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 1966fcf3ce44SJohn Forte 1967fcf3ce44SJohn Forte return (1); 1968fcf3ce44SJohn Forte } 1969291a2b48SSukumar Swaminathan 1970fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 1971fcf3ce44SJohn Forte 1972fcf3ce44SJohn Forte WakeUpParms->prog_id = *prog_id; 1973fcf3ce44SJohn Forte 1974*82527734SSukumar Swaminathan emlxs_format_update_parms(mbox, WakeUpParms); 1975fcf3ce44SJohn Forte 1976*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 1977fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1978291a2b48SSukumar Swaminathan "Unable to update wakeup parameters: Mailbox cmd=%x " 1979291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 1980fcf3ce44SJohn Forte 1981fcf3ce44SJohn Forte rval = 1; 1982fcf3ce44SJohn Forte } 1983291a2b48SSukumar Swaminathan 1984fcf3ce44SJohn Forte if (mbox) { 1985fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 1986fcf3ce44SJohn Forte } 1987291a2b48SSukumar Swaminathan 1988fcf3ce44SJohn Forte return (rval); 1989fcf3ce44SJohn Forte 1990*82527734SSukumar Swaminathan } /* emlxs_update_ff_wakeup_parms() */ 1991fcf3ce44SJohn Forte 1992fcf3ce44SJohn Forte 1993fcf3ce44SJohn Forte static uint32_t 1994fcf3ce44SJohn Forte emlxs_update_sli1_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 1995291a2b48SSukumar Swaminathan PROG_ID * prog_id) 1996fcf3ce44SJohn Forte { 1997fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1998fcf3ce44SJohn Forte uint32_t rval = 0; 1999fcf3ce44SJohn Forte MAILBOXQ *mbox; 2000fcf3ce44SJohn Forte MAILBOX *mb; 2001fcf3ce44SJohn Forte 2002291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2003291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2004fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2005fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 2006fcf3ce44SJohn Forte 2007fcf3ce44SJohn Forte return (1); 2008fcf3ce44SJohn Forte } 2009291a2b48SSukumar Swaminathan 2010fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 2011fcf3ce44SJohn Forte 2012fcf3ce44SJohn Forte WakeUpParms->sli1_prog_id = *prog_id; 2013fcf3ce44SJohn Forte 2014*82527734SSukumar Swaminathan emlxs_format_update_parms(mbox, WakeUpParms); 2015fcf3ce44SJohn Forte 2016*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2017fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2018291a2b48SSukumar Swaminathan "Unable to update wakeup parameters. Mailbox cmd=%x " 2019291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 2020fcf3ce44SJohn Forte 2021fcf3ce44SJohn Forte rval = 1; 2022fcf3ce44SJohn Forte } 2023291a2b48SSukumar Swaminathan 2024fcf3ce44SJohn Forte if (mbox) { 2025fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 2026fcf3ce44SJohn Forte } 2027291a2b48SSukumar Swaminathan 2028fcf3ce44SJohn Forte return (rval); 2029fcf3ce44SJohn Forte 2030*82527734SSukumar Swaminathan } /* emlxs_update_sli1_wakeup_parms() */ 2031fcf3ce44SJohn Forte 2032fcf3ce44SJohn Forte 2033fcf3ce44SJohn Forte static uint32_t 2034fcf3ce44SJohn Forte emlxs_update_sli2_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 2035291a2b48SSukumar Swaminathan PROG_ID * prog_id) 2036fcf3ce44SJohn Forte { 2037fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2038fcf3ce44SJohn Forte uint32_t rval = 0; 2039fcf3ce44SJohn Forte MAILBOXQ *mbox; 2040fcf3ce44SJohn Forte MAILBOX *mb; 2041fcf3ce44SJohn Forte 2042291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2043291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2044fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2045fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 2046fcf3ce44SJohn Forte 2047fcf3ce44SJohn Forte return (1); 2048fcf3ce44SJohn Forte } 2049291a2b48SSukumar Swaminathan 2050fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 2051fcf3ce44SJohn Forte 2052fcf3ce44SJohn Forte WakeUpParms->sli2_prog_id = *prog_id; 2053fcf3ce44SJohn Forte 2054*82527734SSukumar Swaminathan emlxs_format_update_parms(mbox, WakeUpParms); 2055fcf3ce44SJohn Forte 2056*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2057fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2058291a2b48SSukumar Swaminathan "Unable to update wakeup parameters. Mailbox cmd=%x " 2059291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 2060fcf3ce44SJohn Forte 2061fcf3ce44SJohn Forte rval = 1; 2062fcf3ce44SJohn Forte } 2063291a2b48SSukumar Swaminathan 2064fcf3ce44SJohn Forte if (mbox) { 2065fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 2066fcf3ce44SJohn Forte } 2067291a2b48SSukumar Swaminathan 2068fcf3ce44SJohn Forte return (rval); 2069fcf3ce44SJohn Forte 2070*82527734SSukumar Swaminathan } /* emlxs_update_sli2_wakeup_parms() */ 2071fcf3ce44SJohn Forte 2072fcf3ce44SJohn Forte 2073fcf3ce44SJohn Forte static uint32_t 2074fcf3ce44SJohn Forte emlxs_update_sli3_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 2075fcf3ce44SJohn Forte PROG_ID *prog_id) 2076fcf3ce44SJohn Forte { 2077fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2078fcf3ce44SJohn Forte uint32_t rval = 0; 2079fcf3ce44SJohn Forte MAILBOXQ *mbox; 2080fcf3ce44SJohn Forte MAILBOX *mb; 2081fcf3ce44SJohn Forte 2082291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2083291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2084fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2085fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 2086fcf3ce44SJohn Forte 2087fcf3ce44SJohn Forte return (1); 2088fcf3ce44SJohn Forte } 2089291a2b48SSukumar Swaminathan 2090fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 2091fcf3ce44SJohn Forte 2092fcf3ce44SJohn Forte WakeUpParms->sli3_prog_id = *prog_id; 2093fcf3ce44SJohn Forte 2094*82527734SSukumar Swaminathan emlxs_format_update_parms(mbox, WakeUpParms); 2095fcf3ce44SJohn Forte 2096*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2097fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2098291a2b48SSukumar Swaminathan "Unable to update wakeup parameters. Mailbox cmd=%x " 2099291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 2100fcf3ce44SJohn Forte 2101fcf3ce44SJohn Forte rval = 1; 2102fcf3ce44SJohn Forte } 2103291a2b48SSukumar Swaminathan 2104fcf3ce44SJohn Forte if (mbox) { 2105fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 2106fcf3ce44SJohn Forte } 2107291a2b48SSukumar Swaminathan 2108fcf3ce44SJohn Forte return (rval); 2109fcf3ce44SJohn Forte 2110*82527734SSukumar Swaminathan } /* emlxs_update_sli3_wakeup_parms() */ 2111fcf3ce44SJohn Forte 2112fcf3ce44SJohn Forte 2113fcf3ce44SJohn Forte static uint32_t 2114fcf3ce44SJohn Forte emlxs_update_sli4_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 2115fcf3ce44SJohn Forte PROG_ID *prog_id) 2116fcf3ce44SJohn Forte { 2117fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2118fcf3ce44SJohn Forte uint32_t rval = 0; 2119fcf3ce44SJohn Forte MAILBOXQ *mbox; 2120fcf3ce44SJohn Forte MAILBOX *mb; 2121fcf3ce44SJohn Forte 2122291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2123291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2124fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2125fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 2126fcf3ce44SJohn Forte 2127fcf3ce44SJohn Forte return (1); 2128fcf3ce44SJohn Forte } 2129291a2b48SSukumar Swaminathan 2130fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 2131fcf3ce44SJohn Forte 2132fcf3ce44SJohn Forte WakeUpParms->sli4_prog_id = *prog_id; 2133fcf3ce44SJohn Forte 2134*82527734SSukumar Swaminathan emlxs_format_update_parms(mbox, WakeUpParms); 2135fcf3ce44SJohn Forte 2136*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2137fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2138291a2b48SSukumar Swaminathan "Unable to update wakeup parameters. Mailbox cmd=%x " 2139291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 2140fcf3ce44SJohn Forte 2141fcf3ce44SJohn Forte rval = 1; 2142fcf3ce44SJohn Forte } 2143291a2b48SSukumar Swaminathan 2144fcf3ce44SJohn Forte if (mbox) { 2145fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 2146fcf3ce44SJohn Forte } 2147291a2b48SSukumar Swaminathan 2148fcf3ce44SJohn Forte return (rval); 2149fcf3ce44SJohn Forte 2150*82527734SSukumar Swaminathan } /* emlxs_update_sli4_wakeup_parms() */ 2151fcf3ce44SJohn Forte 2152fcf3ce44SJohn Forte 2153fcf3ce44SJohn Forte /* ARGSUSED */ 2154fcf3ce44SJohn Forte static uint32_t 2155291a2b48SSukumar Swaminathan emlxs_start_rel_download(emlxs_hba_t *hba, 2156291a2b48SSukumar Swaminathan PIMAGE_HDR ImageHdr, 2157291a2b48SSukumar Swaminathan caddr_t Buffer, 2158291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, 2159fcf3ce44SJohn Forte uint32_t MaxRbusSramSize, uint32_t MaxIbusSramSize) 2160fcf3ce44SJohn Forte { 2161fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2162fcf3ce44SJohn Forte MAILBOXQ *mbox; 2163fcf3ce44SJohn Forte MAILBOX *mb; 2164fcf3ce44SJohn Forte uint32_t *Src; 2165fcf3ce44SJohn Forte uint32_t *Dst; 2166fcf3ce44SJohn Forte caddr_t DataBuffer = NULL; 2167fcf3ce44SJohn Forte uint32_t rval = 1; 2168fcf3ce44SJohn Forte uint32_t DlByteCount = ImageHdr->BlockSize; 2169fcf3ce44SJohn Forte uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT; 2170fcf3ce44SJohn Forte uint32_t DlCount; 2171fcf3ce44SJohn Forte uint32_t i; 2172fcf3ce44SJohn Forte 2173fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2174fcf3ce44SJohn Forte "Performing relative download..."); 2175fcf3ce44SJohn Forte 2176291a2b48SSukumar Swaminathan if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT, 2177291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2178fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2179fcf3ce44SJohn Forte "Unable to allocate data buffer."); 2180fcf3ce44SJohn Forte 2181fcf3ce44SJohn Forte return (rval); 2182fcf3ce44SJohn Forte } 2183291a2b48SSukumar Swaminathan 2184291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2185291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2186fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2187fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 2188fcf3ce44SJohn Forte 2189fcf3ce44SJohn Forte kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 2190fcf3ce44SJohn Forte 2191fcf3ce44SJohn Forte return (rval); 2192fcf3ce44SJohn Forte } 2193291a2b48SSukumar Swaminathan 2194fcf3ce44SJohn Forte if (ImageHdr->Id.Type == FUNC_FIRMWARE) { 2195fcf3ce44SJohn Forte switch (MaxRbusSramSize) { 2196fcf3ce44SJohn Forte case REDUCED_RBUS_SRAM_CFG: 2197fcf3ce44SJohn Forte if (ImageHdr->Id.Id != REDUCED_SRAM_CFG_PROG_ID) { 2198291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 2199291a2b48SSukumar Swaminathan &emlxs_image_bad_msg, 2200fcf3ce44SJohn Forte "Invalid header id."); 2201fcf3ce44SJohn Forte 2202fcf3ce44SJohn Forte return (1); 2203fcf3ce44SJohn Forte } 2204fcf3ce44SJohn Forte break; 2205fcf3ce44SJohn Forte case FULL_RBUS_SRAM_CFG: 2206fcf3ce44SJohn Forte if (ImageHdr->Id.Id != FULL_SRAM_CFG_PROG_ID) { 2207291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 2208291a2b48SSukumar Swaminathan &emlxs_image_bad_msg, 2209fcf3ce44SJohn Forte "Invalid header id."); 2210fcf3ce44SJohn Forte 2211fcf3ce44SJohn Forte return (1); 2212fcf3ce44SJohn Forte } 2213fcf3ce44SJohn Forte break; 2214fcf3ce44SJohn Forte default: 2215fcf3ce44SJohn Forte if (ImageHdr->Id.Id != OTHER_SRAM_CFG_PROG_ID) { 2216291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 2217291a2b48SSukumar Swaminathan &emlxs_image_bad_msg, 2218fcf3ce44SJohn Forte "Invalid header id."); 2219fcf3ce44SJohn Forte 2220fcf3ce44SJohn Forte return (1); 2221fcf3ce44SJohn Forte } 2222fcf3ce44SJohn Forte break; 2223fcf3ce44SJohn Forte } 2224fcf3ce44SJohn Forte } 2225291a2b48SSukumar Swaminathan 2226fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 2227fcf3ce44SJohn Forte 2228*82527734SSukumar Swaminathan emlxs_format_prog_flash(mbox, 0, DlByteCount, ERASE_FLASH, 0, 0, 0, 2229291a2b48SSukumar Swaminathan &ImageHdr->Id); 2230fcf3ce44SJohn Forte 2231fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, "Erasing flash..."); 2232fcf3ce44SJohn Forte 2233*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2234fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2235fcf3ce44SJohn Forte "Unable to erase flash. Mailbox cmd=%x status=%x", 2236fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 2237fcf3ce44SJohn Forte 2238fcf3ce44SJohn Forte rval = 1; 2239fcf3ce44SJohn Forte 2240fcf3ce44SJohn Forte goto EXIT_REL_DOWNLOAD; 2241fcf3ce44SJohn Forte } 2242291a2b48SSukumar Swaminathan 2243291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2244291a2b48SSukumar Swaminathan "Programming flash..."); 2245fcf3ce44SJohn Forte 2246fcf3ce44SJohn Forte while (DlByteCount) { 2247fcf3ce44SJohn Forte if (DlByteCount > SegSize) { 2248fcf3ce44SJohn Forte DlCount = SegSize; 2249fcf3ce44SJohn Forte } else { 2250fcf3ce44SJohn Forte DlCount = DlByteCount; 2251fcf3ce44SJohn Forte } 2252fcf3ce44SJohn Forte DlByteCount -= DlCount; 2253fcf3ce44SJohn Forte 2254fcf3ce44SJohn Forte Dst = (uint32_t *)DataBuffer; 2255fcf3ce44SJohn Forte Src = (uint32_t *)Buffer; 2256fcf3ce44SJohn Forte 2257fcf3ce44SJohn Forte for (i = 0; i < (DlCount / 4); i++) { 2258fcf3ce44SJohn Forte *Dst = *Src; 2259fcf3ce44SJohn Forte Dst++; 2260fcf3ce44SJohn Forte Src++; 2261fcf3ce44SJohn Forte } 2262fcf3ce44SJohn Forte 2263fcf3ce44SJohn Forte WRITE_SLIM_COPY(hba, (uint32_t *)DataBuffer, 2264*82527734SSukumar Swaminathan (volatile uint32_t *) 2265*82527734SSukumar Swaminathan ((volatile char *)hba->sli.sli3.slim_addr + 2266291a2b48SSukumar Swaminathan sizeof (MAILBOX)), (DlCount / sizeof (uint32_t))); 2267fcf3ce44SJohn Forte 2268*82527734SSukumar Swaminathan emlxs_format_prog_flash(mbox, 2269291a2b48SSukumar Swaminathan 0, 2270291a2b48SSukumar Swaminathan DlCount, 2271291a2b48SSukumar Swaminathan PROGRAM_FLASH, 2272fcf3ce44SJohn Forte (DlByteCount) ? 0 : 1, 0, DlCount, &ImageHdr->Id); 2273fcf3ce44SJohn Forte 2274*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 2275291a2b48SSukumar Swaminathan MBX_SUCCESS) { 2276fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2277fcf3ce44SJohn Forte "Unable to program flash. Mailbox cmd=%x status=%x", 2278fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 2279fcf3ce44SJohn Forte 2280fcf3ce44SJohn Forte rval = 1; 2281fcf3ce44SJohn Forte 2282fcf3ce44SJohn Forte goto EXIT_REL_DOWNLOAD; 2283fcf3ce44SJohn Forte } 2284291a2b48SSukumar Swaminathan 2285fcf3ce44SJohn Forte Buffer += DlCount; 2286fcf3ce44SJohn Forte } 2287fcf3ce44SJohn Forte 22884baa2c25SSukumar Swaminathan #ifdef FMA_SUPPORT 2289*82527734SSukumar Swaminathan if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle) 22904baa2c25SSukumar Swaminathan != DDI_FM_OK) { 22914baa2c25SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 22924baa2c25SSukumar Swaminathan &emlxs_invalid_access_handle_msg, NULL); 22934baa2c25SSukumar Swaminathan 22944baa2c25SSukumar Swaminathan rval = 1; 22954baa2c25SSukumar Swaminathan 22964baa2c25SSukumar Swaminathan goto EXIT_REL_DOWNLOAD; 22974baa2c25SSukumar Swaminathan } 22984baa2c25SSukumar Swaminathan #endif /* FMA_SUPPORT */ 22994baa2c25SSukumar Swaminathan 2300fcf3ce44SJohn Forte switch (ImageHdr->Id.Type) { 2301fcf3ce44SJohn Forte case TEST_PROGRAM: 2302fcf3ce44SJohn Forte rval = 0; 2303fcf3ce44SJohn Forte break; 2304fcf3ce44SJohn Forte 2305fcf3ce44SJohn Forte case FUNC_FIRMWARE: 2306fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2307fcf3ce44SJohn Forte "FF: Updating parms..."); 2308291a2b48SSukumar Swaminathan rval = 2309291a2b48SSukumar Swaminathan emlxs_update_ff_wakeup_parms(hba, WakeUpParms, 2310fcf3ce44SJohn Forte &ImageHdr->Id); 2311fcf3ce44SJohn Forte break; 2312fcf3ce44SJohn Forte 2313fcf3ce44SJohn Forte case BOOT_BIOS: 2314fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2315fcf3ce44SJohn Forte "BOOT: Updating parms..."); 2316291a2b48SSukumar Swaminathan rval = 2317291a2b48SSukumar Swaminathan emlxs_update_boot_wakeup_parms(hba, WakeUpParms, 2318fcf3ce44SJohn Forte &ImageHdr->Id, 1); 2319fcf3ce44SJohn Forte break; 2320fcf3ce44SJohn Forte 2321fcf3ce44SJohn Forte case SLI1_OVERLAY: 2322fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2323fcf3ce44SJohn Forte "SLI1: Updating parms..."); 2324291a2b48SSukumar Swaminathan rval = 2325291a2b48SSukumar Swaminathan emlxs_update_sli1_wakeup_parms(hba, WakeUpParms, 2326fcf3ce44SJohn Forte &ImageHdr->Id); 2327fcf3ce44SJohn Forte break; 2328fcf3ce44SJohn Forte 2329fcf3ce44SJohn Forte case SLI2_OVERLAY: 2330fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2331fcf3ce44SJohn Forte "SLI2: Updating parms..."); 2332291a2b48SSukumar Swaminathan rval = 2333291a2b48SSukumar Swaminathan emlxs_update_sli2_wakeup_parms(hba, WakeUpParms, 2334fcf3ce44SJohn Forte &ImageHdr->Id); 2335fcf3ce44SJohn Forte break; 2336fcf3ce44SJohn Forte 2337fcf3ce44SJohn Forte case SLI3_OVERLAY: 2338fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2339fcf3ce44SJohn Forte "SLI3: Updating parms..."); 2340291a2b48SSukumar Swaminathan rval = 2341291a2b48SSukumar Swaminathan emlxs_update_sli3_wakeup_parms(hba, WakeUpParms, 2342fcf3ce44SJohn Forte &ImageHdr->Id); 2343fcf3ce44SJohn Forte break; 2344fcf3ce44SJohn Forte 2345fcf3ce44SJohn Forte case SLI4_OVERLAY: 2346fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2347fcf3ce44SJohn Forte "SLI4: Updating parms..."); 2348291a2b48SSukumar Swaminathan rval = 2349291a2b48SSukumar Swaminathan emlxs_update_sli4_wakeup_parms(hba, WakeUpParms, 2350fcf3ce44SJohn Forte &ImageHdr->Id); 2351fcf3ce44SJohn Forte break; 2352fcf3ce44SJohn Forte 2353fcf3ce44SJohn Forte default: 2354fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2355291a2b48SSukumar Swaminathan "Image type not supported. Type=%x", ImageHdr->Id.Type); 2356fcf3ce44SJohn Forte 2357fcf3ce44SJohn Forte break; 2358fcf3ce44SJohn Forte } 2359fcf3ce44SJohn Forte 2360fcf3ce44SJohn Forte EXIT_REL_DOWNLOAD: 2361fcf3ce44SJohn Forte if (DataBuffer) { 2362fcf3ce44SJohn Forte kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 2363fcf3ce44SJohn Forte } 2364291a2b48SSukumar Swaminathan 2365fcf3ce44SJohn Forte if (mbox) { 2366fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 2367fcf3ce44SJohn Forte } 2368291a2b48SSukumar Swaminathan 2369fcf3ce44SJohn Forte return (rval); 2370fcf3ce44SJohn Forte 2371*82527734SSukumar Swaminathan } /* emlxs_start_rel_download() */ 2372fcf3ce44SJohn Forte 2373fcf3ce44SJohn Forte 2374fcf3ce44SJohn Forte #define FLASH_POLLING_BIT 0x80 2375fcf3ce44SJohn Forte #define FLASH_ERROR_BIT 0x20 2376fcf3ce44SJohn Forte 2377291a2b48SSukumar Swaminathan typedef struct _flash_t 2378291a2b48SSukumar Swaminathan { 2379291a2b48SSukumar Swaminathan uint32_t offset; 2380291a2b48SSukumar Swaminathan uint8_t val; 2381fcf3ce44SJohn Forte } flash_t; 2382fcf3ce44SJohn Forte 2383fcf3ce44SJohn Forte 2384fcf3ce44SJohn Forte 2385fcf3ce44SJohn Forte static uint32_t 2386291a2b48SSukumar Swaminathan emlxs_write_fcode_flash(emlxs_hba_t *hba, 2387291a2b48SSukumar Swaminathan PIMAGE_HDR ImageHdr, caddr_t Buffer) 2388fcf3ce44SJohn Forte { 2389fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2390fcf3ce44SJohn Forte uint8_t bb; 2391fcf3ce44SJohn Forte uint8_t cc; 2392fcf3ce44SJohn Forte uint8_t *src; 2393fcf3ce44SJohn Forte uint32_t DlByteCount = ImageHdr->BlockSize; 2394fcf3ce44SJohn Forte uint32_t i; 2395fcf3ce44SJohn Forte uint32_t j; 2396fcf3ce44SJohn Forte uint32_t k; 2397fcf3ce44SJohn Forte 2398291a2b48SSukumar Swaminathan flash_t wr[3] = { 2399fcf3ce44SJohn Forte {0x555, 0xaa}, 2400fcf3ce44SJohn Forte {0x2aa, 0x55}, 2401fcf3ce44SJohn Forte {0x555, 0xa0} 2402fcf3ce44SJohn Forte }; 2403fcf3ce44SJohn Forte 2404fcf3ce44SJohn Forte /* Load Fcode */ 2405fcf3ce44SJohn Forte src = (uint8_t *)Buffer + sizeof (IMAGE_HDR); 2406fcf3ce44SJohn Forte for (i = 0; i < DlByteCount; i++) { 2407fcf3ce44SJohn Forte for (k = 0; k < 3; k++) { 2408fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, wr[k].offset, wr[k].val); 2409fcf3ce44SJohn Forte } 2410fcf3ce44SJohn Forte 2411fcf3ce44SJohn Forte /* Reverse Endian word alignment */ 2412fcf3ce44SJohn Forte j = (i & 3) ^ 3; 2413fcf3ce44SJohn Forte 2414fcf3ce44SJohn Forte bb = src[j]; 2415fcf3ce44SJohn Forte 2416fcf3ce44SJohn Forte if (j == 0) { 2417fcf3ce44SJohn Forte src += 4; 2418fcf3ce44SJohn Forte } 2419291a2b48SSukumar Swaminathan 2420fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, i, bb); 2421fcf3ce44SJohn Forte 2422fcf3ce44SJohn Forte /* check for complete */ 2423fcf3ce44SJohn Forte for (;;) { 2424fcf3ce44SJohn Forte DELAYUS(20); 2425fcf3ce44SJohn Forte 2426fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, i); 2427fcf3ce44SJohn Forte 2428fcf3ce44SJohn Forte /* If data matches then continue */ 2429fcf3ce44SJohn Forte if (cc == bb) { 2430fcf3ce44SJohn Forte break; 2431fcf3ce44SJohn Forte } 2432291a2b48SSukumar Swaminathan 2433291a2b48SSukumar Swaminathan /* Polling bit will be inverse final value */ 2434291a2b48SSukumar Swaminathan /* while active */ 2435fcf3ce44SJohn Forte if ((cc ^ bb) & FLASH_POLLING_BIT) { 2436fcf3ce44SJohn Forte /* Still busy */ 2437fcf3ce44SJohn Forte 2438fcf3ce44SJohn Forte /* Check for error bit */ 2439fcf3ce44SJohn Forte if (cc & FLASH_ERROR_BIT) { 2440fcf3ce44SJohn Forte /* Read data one more time */ 2441fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, i); 2442fcf3ce44SJohn Forte 2443fcf3ce44SJohn Forte /* Check if data matches */ 2444fcf3ce44SJohn Forte if (cc == bb) { 2445fcf3ce44SJohn Forte break; 2446fcf3ce44SJohn Forte } 2447291a2b48SSukumar Swaminathan 2448fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2449fcf3ce44SJohn Forte &emlxs_download_failed_msg, 2450fcf3ce44SJohn Forte "FCode write error: offset:%x " 2451291a2b48SSukumar Swaminathan "wrote:%x read:%x\n", i, bb, cc); 2452fcf3ce44SJohn Forte 2453fcf3ce44SJohn Forte return (1); 2454fcf3ce44SJohn Forte } 2455fcf3ce44SJohn Forte } 2456fcf3ce44SJohn Forte } 2457fcf3ce44SJohn Forte } 2458fcf3ce44SJohn Forte 2459fcf3ce44SJohn Forte /* Load Header */ 2460fcf3ce44SJohn Forte src = (uint8_t *)ImageHdr; 2461fcf3ce44SJohn Forte 2462fcf3ce44SJohn Forte for (i = (0xFFFF - sizeof (IMAGE_HDR)); i < 0xFFFF; i++) { 2463fcf3ce44SJohn Forte for (k = 0; k < 3; k++) { 2464fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, wr[k].offset, wr[k].val); 2465fcf3ce44SJohn Forte } 2466fcf3ce44SJohn Forte 2467fcf3ce44SJohn Forte /* Reverse Endian word alignment */ 2468fcf3ce44SJohn Forte j = (i & 3) ^ 3; 2469fcf3ce44SJohn Forte 2470fcf3ce44SJohn Forte bb = src[j]; 2471fcf3ce44SJohn Forte 2472fcf3ce44SJohn Forte if (j == 0) { 2473fcf3ce44SJohn Forte src += 4; 2474fcf3ce44SJohn Forte } 2475291a2b48SSukumar Swaminathan 2476fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, i, bb); 2477fcf3ce44SJohn Forte 2478fcf3ce44SJohn Forte /* check for complete */ 2479fcf3ce44SJohn Forte for (;;) { 2480fcf3ce44SJohn Forte DELAYUS(20); 2481fcf3ce44SJohn Forte 2482fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, i); 2483fcf3ce44SJohn Forte 2484fcf3ce44SJohn Forte /* If data matches then continue */ 2485fcf3ce44SJohn Forte if (cc == bb) { 2486fcf3ce44SJohn Forte break; 2487fcf3ce44SJohn Forte } 2488291a2b48SSukumar Swaminathan 2489291a2b48SSukumar Swaminathan /* Polling bit will be inverse final value */ 2490291a2b48SSukumar Swaminathan /* while active */ 2491fcf3ce44SJohn Forte if ((cc ^ bb) & FLASH_POLLING_BIT) { 2492fcf3ce44SJohn Forte /* Still busy */ 2493fcf3ce44SJohn Forte 2494fcf3ce44SJohn Forte /* Check for error bit */ 2495fcf3ce44SJohn Forte if (cc & FLASH_ERROR_BIT) { 2496fcf3ce44SJohn Forte /* Read data one more time */ 2497fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, i); 2498fcf3ce44SJohn Forte 2499fcf3ce44SJohn Forte /* Check if data matches */ 2500fcf3ce44SJohn Forte if (cc == bb) { 2501fcf3ce44SJohn Forte break; 2502fcf3ce44SJohn Forte } 2503291a2b48SSukumar Swaminathan 2504fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2505fcf3ce44SJohn Forte &emlxs_download_failed_msg, 2506fcf3ce44SJohn Forte "FCode write error: offset:%x " 2507291a2b48SSukumar Swaminathan "wrote:%x read:%x\n", i, bb, cc); 2508fcf3ce44SJohn Forte 2509fcf3ce44SJohn Forte return (1); 2510fcf3ce44SJohn Forte } 2511fcf3ce44SJohn Forte } 2512fcf3ce44SJohn Forte } 2513fcf3ce44SJohn Forte } 2514fcf3ce44SJohn Forte 25154baa2c25SSukumar Swaminathan #ifdef FMA_SUPPORT 2516*82527734SSukumar Swaminathan if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.sbus_flash_acc_handle) 25174baa2c25SSukumar Swaminathan != DDI_FM_OK) { 25184baa2c25SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 25194baa2c25SSukumar Swaminathan &emlxs_invalid_access_handle_msg, NULL); 25204baa2c25SSukumar Swaminathan return (1); 25214baa2c25SSukumar Swaminathan } 25224baa2c25SSukumar Swaminathan #endif /* FMA_SUPPORT */ 2523291a2b48SSukumar Swaminathan 2524fcf3ce44SJohn Forte return (0); 2525fcf3ce44SJohn Forte 2526*82527734SSukumar Swaminathan } /* emlxs_write_fcode_flash() */ 2527fcf3ce44SJohn Forte 2528fcf3ce44SJohn Forte 2529fcf3ce44SJohn Forte 2530fcf3ce44SJohn Forte static uint32_t 2531fcf3ce44SJohn Forte emlxs_erase_fcode_flash(emlxs_hba_t *hba) 2532fcf3ce44SJohn Forte { 2533fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2534fcf3ce44SJohn Forte int32_t i, j; 2535fcf3ce44SJohn Forte uint8_t cc; 2536fcf3ce44SJohn Forte uint32_t offset; 2537fcf3ce44SJohn Forte 2538291a2b48SSukumar Swaminathan flash_t ef[6] = { 2539fcf3ce44SJohn Forte {0x555, 0xaa}, 2540fcf3ce44SJohn Forte {0x2aa, 0x55}, 2541fcf3ce44SJohn Forte {0x555, 0x80}, 2542fcf3ce44SJohn Forte {0x555, 0xaa}, 2543fcf3ce44SJohn Forte {0x2aa, 0x55}, 2544fcf3ce44SJohn Forte {0x555, 0x10} 2545fcf3ce44SJohn Forte }; 2546fcf3ce44SJohn Forte 2547fcf3ce44SJohn Forte /* Auto select */ 2548291a2b48SSukumar Swaminathan flash_t as[3] = { 2549fcf3ce44SJohn Forte {0x555, 0xaa}, 2550fcf3ce44SJohn Forte {0x2aa, 0x55}, 2551fcf3ce44SJohn Forte {0x555, 0x90} 2552fcf3ce44SJohn Forte }; 2553fcf3ce44SJohn Forte 2554fcf3ce44SJohn Forte 2555fcf3ce44SJohn Forte /* Check Manufacturers Code */ 2556fcf3ce44SJohn Forte for (i = 0; i < 3; i++) { 2557fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, as[i].offset, as[i].val); 2558fcf3ce44SJohn Forte } 2559fcf3ce44SJohn Forte 2560fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, 0); 2561fcf3ce44SJohn Forte 2562fcf3ce44SJohn Forte /* Check Device Code */ 2563fcf3ce44SJohn Forte for (i = 0; i < 3; i++) { 2564fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, as[i].offset, as[i].val); 2565fcf3ce44SJohn Forte } 2566fcf3ce44SJohn Forte 2567fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, 1); 2568fcf3ce44SJohn Forte 2569fcf3ce44SJohn Forte 2570fcf3ce44SJohn Forte /* Check block protections (up to 4 16K blocks = 64K) */ 2571fcf3ce44SJohn Forte for (j = 0; j < 4; j++) { 2572fcf3ce44SJohn Forte for (i = 0; i < 3; i++) { 2573fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, as[i].offset, as[i].val); 2574fcf3ce44SJohn Forte } 2575fcf3ce44SJohn Forte 2576fcf3ce44SJohn Forte offset = (j << 14) | 0x2; 2577fcf3ce44SJohn Forte 2578fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, offset); 2579fcf3ce44SJohn Forte 2580fcf3ce44SJohn Forte if (cc == 0x01) { 2581fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2582fcf3ce44SJohn Forte "Block %d is protected and can't be erased.", j); 2583fcf3ce44SJohn Forte } 2584fcf3ce44SJohn Forte } 2585fcf3ce44SJohn Forte 2586fcf3ce44SJohn Forte /* Write erase flash sequence */ 2587fcf3ce44SJohn Forte for (i = 0; i < 6; i++) { 2588fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, ef[i].offset, ef[i].val); 2589fcf3ce44SJohn Forte } 2590fcf3ce44SJohn Forte 2591fcf3ce44SJohn Forte /* check for complete */ 2592fcf3ce44SJohn Forte for (;;) { 2593fcf3ce44SJohn Forte /* Delay 3 seconds */ 2594fcf3ce44SJohn Forte DELAYMS(3000); 2595fcf3ce44SJohn Forte 2596fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, 0); 2597fcf3ce44SJohn Forte 2598fcf3ce44SJohn Forte 2599fcf3ce44SJohn Forte /* If data matches then continue; */ 2600fcf3ce44SJohn Forte if (cc == 0xff) { 2601fcf3ce44SJohn Forte break; 2602fcf3ce44SJohn Forte } 2603291a2b48SSukumar Swaminathan 2604fcf3ce44SJohn Forte /* Polling bit will be inverse final value while active */ 2605fcf3ce44SJohn Forte if ((cc ^ 0xff) & FLASH_POLLING_BIT) { 2606fcf3ce44SJohn Forte /* Still busy */ 2607fcf3ce44SJohn Forte 2608fcf3ce44SJohn Forte /* Check for error bit */ 2609fcf3ce44SJohn Forte if (cc & FLASH_ERROR_BIT) { 2610fcf3ce44SJohn Forte /* Read data one more time */ 2611fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, 0); 2612fcf3ce44SJohn Forte 2613fcf3ce44SJohn Forte /* Check if data matches */ 2614fcf3ce44SJohn Forte if (cc == 0xff) { 2615fcf3ce44SJohn Forte break; 2616fcf3ce44SJohn Forte } 2617291a2b48SSukumar Swaminathan 2618fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2619fcf3ce44SJohn Forte &emlxs_download_failed_msg, 2620291a2b48SSukumar Swaminathan "FCode write error: offset:%x wrote:%x " 2621291a2b48SSukumar Swaminathan "read:%x\n", i, 0xff, cc); 2622fcf3ce44SJohn Forte 2623fcf3ce44SJohn Forte return (1); 2624fcf3ce44SJohn Forte } 2625fcf3ce44SJohn Forte } 2626fcf3ce44SJohn Forte } 2627fcf3ce44SJohn Forte 26284baa2c25SSukumar Swaminathan #ifdef FMA_SUPPORT 2629*82527734SSukumar Swaminathan if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.sbus_flash_acc_handle) 26304baa2c25SSukumar Swaminathan != DDI_FM_OK) { 26314baa2c25SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 26324baa2c25SSukumar Swaminathan &emlxs_invalid_access_handle_msg, NULL); 26334baa2c25SSukumar Swaminathan return (1); 26344baa2c25SSukumar Swaminathan } 26354baa2c25SSukumar Swaminathan #endif /* FMA_SUPPORT */ 26364baa2c25SSukumar Swaminathan 2637fcf3ce44SJohn Forte return (0); 2638fcf3ce44SJohn Forte 2639*82527734SSukumar Swaminathan } /* emlxs_erase_fcode_flash() */ 2640fcf3ce44SJohn Forte 2641fcf3ce44SJohn Forte 2642fcf3ce44SJohn Forte extern uint32_t 2643fcf3ce44SJohn Forte emlxs_get_load_list(emlxs_hba_t *hba, PROG_ID *load_list) 2644fcf3ce44SJohn Forte { 2645fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2646fcf3ce44SJohn Forte LOAD_ENTRY *LoadEntry; 2647fcf3ce44SJohn Forte LOAD_LIST *LoadList = NULL; 2648fcf3ce44SJohn Forte uint32_t i; 2649fcf3ce44SJohn Forte uint32_t rval = 0; 2650fcf3ce44SJohn Forte 2651fcf3ce44SJohn Forte bzero(load_list, (sizeof (PROG_ID) * MAX_LOAD_ENTRY)); 2652fcf3ce44SJohn Forte 2653291a2b48SSukumar Swaminathan if ((LoadList = (LOAD_LIST *)kmem_zalloc(sizeof (LOAD_LIST), 2654291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2655fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2656fcf3ce44SJohn Forte "Unable to allocate LOADLIST buffer."); 2657fcf3ce44SJohn Forte 2658fcf3ce44SJohn Forte rval = 1; 2659fcf3ce44SJohn Forte goto done; 2660fcf3ce44SJohn Forte } 2661291a2b48SSukumar Swaminathan 2662fcf3ce44SJohn Forte if (emlxs_read_load_list(hba, LoadList)) { 2663fcf3ce44SJohn Forte rval = 1; 2664fcf3ce44SJohn Forte goto done; 2665fcf3ce44SJohn Forte } 2666291a2b48SSukumar Swaminathan 2667fcf3ce44SJohn Forte for (i = 0; i < LoadList->entry_cnt; i++) { 2668fcf3ce44SJohn Forte LoadEntry = &LoadList->load_entry[i]; 2669fcf3ce44SJohn Forte if ((LoadEntry->un.wd[0] != 0) && 2670fcf3ce44SJohn Forte (LoadEntry->un.wd[0] != 0xffffffff)) { 2671fcf3ce44SJohn Forte load_list[i] = LoadEntry->un.id; 2672fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 2673291a2b48SSukumar Swaminathan "Load List[%d]: %08x %08x", i, 2674291a2b48SSukumar Swaminathan LoadEntry->un.wd[0], LoadEntry->un.wd[1]); 2675fcf3ce44SJohn Forte } 2676fcf3ce44SJohn Forte } 2677fcf3ce44SJohn Forte 2678fcf3ce44SJohn Forte done: 2679fcf3ce44SJohn Forte 2680fcf3ce44SJohn Forte if (LoadList) { 2681fcf3ce44SJohn Forte kmem_free(LoadList, sizeof (LOAD_LIST)); 2682fcf3ce44SJohn Forte } 2683291a2b48SSukumar Swaminathan 2684fcf3ce44SJohn Forte return (rval); 2685fcf3ce44SJohn Forte 2686*82527734SSukumar Swaminathan } /* emlxs_get_load_list() */ 2687fcf3ce44SJohn Forte 2688fcf3ce44SJohn Forte 2689fcf3ce44SJohn Forte extern uint32_t 2690fcf3ce44SJohn Forte emlxs_read_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 2691fcf3ce44SJohn Forte uint32_t verbose) 2692fcf3ce44SJohn Forte { 2693fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2694fcf3ce44SJohn Forte MAILBOXQ *mbox; 2695fcf3ce44SJohn Forte MAILBOX *mb; 2696fcf3ce44SJohn Forte uint32_t rval = 0; 2697fcf3ce44SJohn Forte uint32_t *wd; 2698fcf3ce44SJohn Forte 2699fcf3ce44SJohn Forte bzero(WakeUpParms, sizeof (WAKE_UP_PARMS)); 2700fcf3ce44SJohn Forte 2701291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2702291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2703fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2704fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 2705fcf3ce44SJohn Forte 2706fcf3ce44SJohn Forte return (1); 2707fcf3ce44SJohn Forte } 2708291a2b48SSukumar Swaminathan 2709fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 2710fcf3ce44SJohn Forte 2711*82527734SSukumar Swaminathan emlxs_format_dump(hba, mbox, 2712291a2b48SSukumar Swaminathan DMP_NV_PARAMS, 2713291a2b48SSukumar Swaminathan WAKE_UP_PARMS_REGION_ID, 2714fcf3ce44SJohn Forte sizeof (WAKE_UP_PARMS) / sizeof (uint32_t), 0); 2715fcf3ce44SJohn Forte 2716*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2717fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2718fcf3ce44SJohn Forte "Unable to get parameters: Mailbox cmd=%x status=%x", 2719fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 2720fcf3ce44SJohn Forte 2721fcf3ce44SJohn Forte if (mb->un.varDmp.word_cnt == (uint32_t)CFG_DATA_NO_REGION) { 2722fcf3ce44SJohn Forte rval = (uint32_t)CFG_DATA_NO_REGION; 2723fcf3ce44SJohn Forte } else { 2724fcf3ce44SJohn Forte rval = 1; 2725fcf3ce44SJohn Forte } 2726fcf3ce44SJohn Forte } else { 2727*82527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 2728*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle, 2729*82527734SSukumar Swaminathan 0, hba->sli.sli4.dump_region.size, 2730*82527734SSukumar Swaminathan DDI_DMA_SYNC_FORKERNEL); 2731*82527734SSukumar Swaminathan 2732*82527734SSukumar Swaminathan bcopy((caddr_t)hba->sli.sli4.dump_region.virt, 2733*82527734SSukumar Swaminathan (caddr_t)WakeUpParms, sizeof (WAKE_UP_PARMS)); 2734*82527734SSukumar Swaminathan } else { 2735*82527734SSukumar Swaminathan bcopy((caddr_t)&mb->un.varDmp.resp_offset, 2736*82527734SSukumar Swaminathan (caddr_t)WakeUpParms, sizeof (WAKE_UP_PARMS)); 2737*82527734SSukumar Swaminathan } 2738fcf3ce44SJohn Forte 2739fcf3ce44SJohn Forte if (verbose) { 2740fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->prog_id; 2741fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 2742291a2b48SSukumar Swaminathan "Wakeup: prog_id=%08x %08x", wd[0], wd[1]); 2743fcf3ce44SJohn Forte 2744fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->u0.boot_bios_id; 2745fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 2746291a2b48SSukumar Swaminathan "Wakeup: boot_bios_id=%08x %08x", wd[0], wd[1]); 2747fcf3ce44SJohn Forte 2748fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->sli1_prog_id; 2749fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 2750291a2b48SSukumar Swaminathan "Wakeup: sli1_prog_id=%08x %08x", wd[0], wd[1]); 2751fcf3ce44SJohn Forte 2752fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->sli2_prog_id; 2753fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 2754291a2b48SSukumar Swaminathan "Wakeup: sli2_prog_id=%08x %08x", wd[0], wd[1]); 2755fcf3ce44SJohn Forte 2756fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->sli3_prog_id; 2757fcf3ce44SJohn Forte if (wd[0] || wd[1]) { 2758291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 2759291a2b48SSukumar Swaminathan &emlxs_init_debug_msg, 2760291a2b48SSukumar Swaminathan "Wakeup: sli3_prog_id=%08x %08x", wd[0], 2761291a2b48SSukumar Swaminathan wd[1]); 2762fcf3ce44SJohn Forte } 2763291a2b48SSukumar Swaminathan 2764fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->sli4_prog_id; 2765fcf3ce44SJohn Forte if (wd[0] || wd[1]) { 2766291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 2767291a2b48SSukumar Swaminathan &emlxs_init_debug_msg, 2768291a2b48SSukumar Swaminathan "Wakeup: sli4_prog_id=%08x %08x", wd[0], 2769291a2b48SSukumar Swaminathan wd[1]); 2770fcf3ce44SJohn Forte } 2771291a2b48SSukumar Swaminathan 2772fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->u1.EROM_prog_id; 2773fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 2774291a2b48SSukumar Swaminathan "Wakeup: EROM_prog_id=%08x %08x", wd[0], wd[1]); 2775fcf3ce44SJohn Forte 2776fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 2777fcf3ce44SJohn Forte "Wakeup: pci_cfg_rsvd=%x", 2778fcf3ce44SJohn Forte WakeUpParms->pci_cfg_rsvd); 2779fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 2780fcf3ce44SJohn Forte "Wakeup: use_hdw_def=%x", 2781fcf3ce44SJohn Forte WakeUpParms->use_hdw_def); 2782fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 2783fcf3ce44SJohn Forte "Wakeup: pci_cfg_sel=%x", 2784fcf3ce44SJohn Forte WakeUpParms->pci_cfg_sel); 2785fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 2786fcf3ce44SJohn Forte "Wakeup: cfg_lookup=%x", 2787fcf3ce44SJohn Forte WakeUpParms->pci_cfg_lookup_sel); 2788fcf3ce44SJohn Forte } 2789fcf3ce44SJohn Forte } 2790fcf3ce44SJohn Forte 2791fcf3ce44SJohn Forte done: 2792fcf3ce44SJohn Forte 2793fcf3ce44SJohn Forte if (mbox) { 2794fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 2795fcf3ce44SJohn Forte } 2796291a2b48SSukumar Swaminathan 2797fcf3ce44SJohn Forte return (rval); 2798fcf3ce44SJohn Forte 2799*82527734SSukumar Swaminathan } /* emlxs_read_wakeup_parms() */ 2800fcf3ce44SJohn Forte 2801fcf3ce44SJohn Forte 2802fcf3ce44SJohn Forte static uint32_t 2803291a2b48SSukumar Swaminathan emlxs_read_load_list(emlxs_hba_t *hba, LOAD_LIST *LoadList) 2804fcf3ce44SJohn Forte { 2805fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2806fcf3ce44SJohn Forte LOAD_ENTRY *LoadEntry; 2807fcf3ce44SJohn Forte uint32_t *Uptr; 2808fcf3ce44SJohn Forte uint32_t CurEntryAddr; 2809fcf3ce44SJohn Forte MAILBOXQ *mbox = NULL; 2810fcf3ce44SJohn Forte MAILBOX *mb; 2811fcf3ce44SJohn Forte 2812fcf3ce44SJohn Forte bzero((caddr_t)LoadList, sizeof (LOAD_LIST)); 2813fcf3ce44SJohn Forte 2814291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2815291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2816fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2817fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 2818fcf3ce44SJohn Forte 2819fcf3ce44SJohn Forte return (1); 2820fcf3ce44SJohn Forte } 2821291a2b48SSukumar Swaminathan 2822fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 2823fcf3ce44SJohn Forte 2824*82527734SSukumar Swaminathan emlxs_format_dump(hba, mbox, DMP_MEM_REG, 0, 2, FLASH_LOAD_LIST_ADR); 2825fcf3ce44SJohn Forte 2826*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 2827fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2828fcf3ce44SJohn Forte "Unable to get load list: Mailbox cmd=%x status=%x", 2829fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 2830fcf3ce44SJohn Forte 2831fcf3ce44SJohn Forte goto done; 2832fcf3ce44SJohn Forte } 2833291a2b48SSukumar Swaminathan 2834*82527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 2835*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle, 0, 2836*82527734SSukumar Swaminathan hba->sli.sli4.dump_region.size, DDI_DMA_SYNC_FORKERNEL); 2837*82527734SSukumar Swaminathan Uptr = (uint32_t *)hba->sli.sli4.dump_region.virt; 2838*82527734SSukumar Swaminathan } else { 2839*82527734SSukumar Swaminathan Uptr = (uint32_t *)&mb->un.varDmp.resp_offset; 2840*82527734SSukumar Swaminathan } 2841fcf3ce44SJohn Forte 2842fcf3ce44SJohn Forte LoadList->head = Uptr[0]; 2843fcf3ce44SJohn Forte LoadList->tail = Uptr[1]; 2844fcf3ce44SJohn Forte 2845fcf3ce44SJohn Forte CurEntryAddr = LoadList->head; 2846fcf3ce44SJohn Forte 2847fcf3ce44SJohn Forte while ((CurEntryAddr != FLASH_LOAD_LIST_ADR) && 2848fcf3ce44SJohn Forte (LoadList->entry_cnt < MAX_LOAD_ENTRY)) { 2849fcf3ce44SJohn Forte LoadEntry = &LoadList->load_entry[LoadList->entry_cnt]; 2850fcf3ce44SJohn Forte LoadList->entry_cnt++; 2851fcf3ce44SJohn Forte 2852*82527734SSukumar Swaminathan emlxs_format_dump(hba, mbox, 2853291a2b48SSukumar Swaminathan DMP_MEM_REG, 0, FLASH_LOAD_ENTRY_SIZE, CurEntryAddr); 2854fcf3ce44SJohn Forte 2855*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 2856291a2b48SSukumar Swaminathan MBX_SUCCESS) { 2857fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2858291a2b48SSukumar Swaminathan "Unable to get load list (%d): Mailbox cmd=%x " 2859291a2b48SSukumar Swaminathan "status=%x", LoadList->entry_cnt, mb->mbxCommand, 2860291a2b48SSukumar Swaminathan mb->mbxStatus); 2861fcf3ce44SJohn Forte 2862fcf3ce44SJohn Forte goto done; 2863fcf3ce44SJohn Forte } 2864291a2b48SSukumar Swaminathan 2865*82527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 2866*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle, 2867*82527734SSukumar Swaminathan 0, hba->sli.sli4.dump_region.size, 2868*82527734SSukumar Swaminathan DDI_DMA_SYNC_FORKERNEL); 2869*82527734SSukumar Swaminathan Uptr = (uint32_t *)hba->sli.sli4.dump_region.virt; 2870*82527734SSukumar Swaminathan } else { 2871*82527734SSukumar Swaminathan Uptr = (uint32_t *)&mb->un.varDmp.resp_offset; 2872*82527734SSukumar Swaminathan } 2873fcf3ce44SJohn Forte 2874fcf3ce44SJohn Forte LoadEntry->next = Uptr[0]; 2875fcf3ce44SJohn Forte LoadEntry->prev = Uptr[1]; 2876fcf3ce44SJohn Forte LoadEntry->start_adr = Uptr[2]; 2877fcf3ce44SJohn Forte LoadEntry->len = Uptr[3]; 2878fcf3ce44SJohn Forte LoadEntry->un.wd[0] = Uptr[4]; 2879fcf3ce44SJohn Forte LoadEntry->un.wd[1] = Uptr[5]; 2880fcf3ce44SJohn Forte 2881fcf3ce44SJohn Forte /* update next current load entry address */ 2882fcf3ce44SJohn Forte CurEntryAddr = LoadEntry->next; 2883fcf3ce44SJohn Forte 2884fcf3ce44SJohn Forte } /* end of while (not end of list) */ 2885fcf3ce44SJohn Forte 2886fcf3ce44SJohn Forte done: 2887fcf3ce44SJohn Forte 2888fcf3ce44SJohn Forte if (mbox) { 2889fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 2890fcf3ce44SJohn Forte } 2891291a2b48SSukumar Swaminathan 2892fcf3ce44SJohn Forte return (0); 2893fcf3ce44SJohn Forte 2894*82527734SSukumar Swaminathan } /* emlxs_read_load_list() */ 2895fcf3ce44SJohn Forte 2896fcf3ce44SJohn Forte 2897fcf3ce44SJohn Forte static uint32_t 2898fcf3ce44SJohn Forte emlxs_get_abs_image_type(caddr_t Buffer, uint32_t BufferSize) 2899fcf3ce44SJohn Forte { 2900fcf3ce44SJohn Forte uint32_t Version; 2901fcf3ce44SJohn Forte 2902fcf3ce44SJohn Forte if (BufferSize < (SLI_VERSION_LOC + 4)) 2903fcf3ce44SJohn Forte return (0xffffffff); 2904fcf3ce44SJohn Forte 2905fcf3ce44SJohn Forte Buffer += SLI_VERSION_LOC; 2906fcf3ce44SJohn Forte Version = *((uint32_t *)Buffer); 2907fcf3ce44SJohn Forte 2908fcf3ce44SJohn Forte return (Version); 2909fcf3ce44SJohn Forte 2910*82527734SSukumar Swaminathan } /* emlxs_get_abs_image_type() */ 2911fcf3ce44SJohn Forte 2912fcf3ce44SJohn Forte 2913fcf3ce44SJohn Forte static uint32_t 2914fcf3ce44SJohn Forte emlxs_get_dwc_image_type(emlxs_hba_t *hba, caddr_t Buffer, 2915fcf3ce44SJohn Forte uint32_t BufferSize, PAIF_HDR AifHeader) 2916fcf3ce44SJohn Forte { 2917fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2918fcf3ce44SJohn Forte IMAGE_HDR ImageHdr; 2919fcf3ce44SJohn Forte uint32_t NextImage; 2920fcf3ce44SJohn Forte uint32_t i; 2921fcf3ce44SJohn Forte uint8_t *Sptr; 2922fcf3ce44SJohn Forte uint8_t *Dptr; 2923fcf3ce44SJohn Forte uint32_t HwId = 0xffffffff; 2924fcf3ce44SJohn Forte 2925fcf3ce44SJohn Forte NextImage = SLI_IMAGE_START - AifHeader->ImageBase; 2926fcf3ce44SJohn Forte 2927fcf3ce44SJohn Forte while (BufferSize > NextImage) { 2928fcf3ce44SJohn Forte Sptr = (uint8_t *)&Buffer[NextImage]; 2929fcf3ce44SJohn Forte Dptr = (uint8_t *)&ImageHdr; 2930fcf3ce44SJohn Forte for (i = 0; i < sizeof (IMAGE_HDR); i++) { 2931fcf3ce44SJohn Forte Dptr[i] = Sptr[i]; 2932fcf3ce44SJohn Forte } 2933fcf3ce44SJohn Forte 2934fcf3ce44SJohn Forte if (ImageHdr.BlockSize == 0xffffffff) 2935fcf3ce44SJohn Forte break; 2936fcf3ce44SJohn Forte 2937fcf3ce44SJohn Forte switch (ImageHdr.Id.Type) { 2938fcf3ce44SJohn Forte case 6: 2939fcf3ce44SJohn Forte case 7: 2940fcf3ce44SJohn Forte if (HwId == 0xffffffff) { 2941fcf3ce44SJohn Forte HwId = ImageHdr.Id.Id; 2942fcf3ce44SJohn Forte } 2943291a2b48SSukumar Swaminathan 2944fcf3ce44SJohn Forte if (HwId != ImageHdr.Id.Id) { 2945291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 2946291a2b48SSukumar Swaminathan &emlxs_image_bad_msg, 2947291a2b48SSukumar Swaminathan "Invalid hardware id. %x %x", HwId, 2948291a2b48SSukumar Swaminathan ImageHdr.Id.Id); 2949fcf3ce44SJohn Forte } 2950fcf3ce44SJohn Forte break; 2951fcf3ce44SJohn Forte } 2952fcf3ce44SJohn Forte 2953fcf3ce44SJohn Forte NextImage += ImageHdr.BlockSize; 2954fcf3ce44SJohn Forte } 2955fcf3ce44SJohn Forte 2956fcf3ce44SJohn Forte return (HwId); 2957fcf3ce44SJohn Forte 2958*82527734SSukumar Swaminathan } /* emlxs_get_dwc_image_type() */ 2959fcf3ce44SJohn Forte 2960fcf3ce44SJohn Forte 2961fcf3ce44SJohn Forte static int 2962291a2b48SSukumar Swaminathan emlxs_build_parms(caddr_t Buffer, 2963291a2b48SSukumar Swaminathan PWAKE_UP_PARMS AbsWakeUpParms, 2964fcf3ce44SJohn Forte uint32_t BufferSize, PAIF_HDR AifHeader, int32_t DwcFile) 2965fcf3ce44SJohn Forte { 2966fcf3ce44SJohn Forte IMAGE_HDR ImageHdr; 2967fcf3ce44SJohn Forte uint32_t NextImage; 2968fcf3ce44SJohn Forte uint32_t i; 2969fcf3ce44SJohn Forte int32_t ChangeParams = FALSE; 2970fcf3ce44SJohn Forte caddr_t Sptr; 2971fcf3ce44SJohn Forte caddr_t Dptr; 2972fcf3ce44SJohn Forte 2973fcf3ce44SJohn Forte bzero((caddr_t)AbsWakeUpParms, sizeof (WAKE_UP_PARMS)); 2974fcf3ce44SJohn Forte 2975fcf3ce44SJohn Forte if (!DwcFile && ((AifHeader->RoSize + AifHeader->RwSize) <= 0x20000)) { 2976fcf3ce44SJohn Forte return (FALSE); 2977fcf3ce44SJohn Forte } 2978291a2b48SSukumar Swaminathan 2979fcf3ce44SJohn Forte NextImage = SLI_IMAGE_START - AifHeader->ImageBase; 2980fcf3ce44SJohn Forte 2981fcf3ce44SJohn Forte while (BufferSize > NextImage) { 2982fcf3ce44SJohn Forte Sptr = &Buffer[NextImage]; 2983fcf3ce44SJohn Forte Dptr = (caddr_t)&ImageHdr; 2984fcf3ce44SJohn Forte for (i = 0; i < sizeof (IMAGE_HDR); i++) { 2985fcf3ce44SJohn Forte Dptr[i] = Sptr[i]; 2986fcf3ce44SJohn Forte } 2987fcf3ce44SJohn Forte 2988fcf3ce44SJohn Forte if (ImageHdr.BlockSize == 0xffffffff) 2989fcf3ce44SJohn Forte break; 2990fcf3ce44SJohn Forte 2991fcf3ce44SJohn Forte switch (ImageHdr.Id.Type) { 2992fcf3ce44SJohn Forte case TEST_PROGRAM: 2993fcf3ce44SJohn Forte break; 2994fcf3ce44SJohn Forte case FUNC_FIRMWARE: 2995fcf3ce44SJohn Forte AbsWakeUpParms->prog_id = ImageHdr.Id; 2996fcf3ce44SJohn Forte ChangeParams = TRUE; 2997fcf3ce44SJohn Forte break; 2998fcf3ce44SJohn Forte case BOOT_BIOS: 2999fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_id = ImageHdr.Id; 3000fcf3ce44SJohn Forte ChangeParams = TRUE; 3001fcf3ce44SJohn Forte break; 3002fcf3ce44SJohn Forte case SLI1_OVERLAY: 3003fcf3ce44SJohn Forte AbsWakeUpParms->sli1_prog_id = ImageHdr.Id; 3004fcf3ce44SJohn Forte ChangeParams = TRUE; 3005fcf3ce44SJohn Forte break; 3006fcf3ce44SJohn Forte case SLI2_OVERLAY: 3007fcf3ce44SJohn Forte AbsWakeUpParms->sli2_prog_id = ImageHdr.Id; 3008fcf3ce44SJohn Forte ChangeParams = TRUE; 3009fcf3ce44SJohn Forte break; 3010fcf3ce44SJohn Forte case SLI3_OVERLAY: 3011fcf3ce44SJohn Forte AbsWakeUpParms->sli3_prog_id = ImageHdr.Id; 3012fcf3ce44SJohn Forte ChangeParams = TRUE; 3013fcf3ce44SJohn Forte break; 3014fcf3ce44SJohn Forte case SLI4_OVERLAY: 3015fcf3ce44SJohn Forte AbsWakeUpParms->sli4_prog_id = ImageHdr.Id; 3016fcf3ce44SJohn Forte ChangeParams = TRUE; 3017fcf3ce44SJohn Forte break; 3018fcf3ce44SJohn Forte default: 3019fcf3ce44SJohn Forte break; 3020fcf3ce44SJohn Forte } 3021fcf3ce44SJohn Forte 3022fcf3ce44SJohn Forte NextImage += ImageHdr.BlockSize; 3023fcf3ce44SJohn Forte } 3024fcf3ce44SJohn Forte 3025fcf3ce44SJohn Forte return (ChangeParams); 3026fcf3ce44SJohn Forte 3027*82527734SSukumar Swaminathan } /* emlxs_build_parms() */ 3028fcf3ce44SJohn Forte 3029fcf3ce44SJohn Forte 3030fcf3ce44SJohn Forte static uint32_t 3031fcf3ce44SJohn Forte emlxs_update_wakeup_parms(emlxs_hba_t *hba, 3032fcf3ce44SJohn Forte PWAKE_UP_PARMS AbsWakeUpParms, PWAKE_UP_PARMS WakeUpParms) 3033fcf3ce44SJohn Forte { 3034fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3035fcf3ce44SJohn Forte MAILBOX *mb; 3036fcf3ce44SJohn Forte MAILBOXQ *mbox; 3037fcf3ce44SJohn Forte uint32_t rval = 0; 3038fcf3ce44SJohn Forte 3039291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 3040291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 3041fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3042fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 3043fcf3ce44SJohn Forte 3044fcf3ce44SJohn Forte return (1); 3045fcf3ce44SJohn Forte } 3046291a2b48SSukumar Swaminathan 3047fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 3048fcf3ce44SJohn Forte 3049fcf3ce44SJohn Forte WakeUpParms->prog_id = AbsWakeUpParms->prog_id; 3050fcf3ce44SJohn Forte WakeUpParms->u0.boot_bios_id = AbsWakeUpParms->u0.boot_bios_id; 3051fcf3ce44SJohn Forte WakeUpParms->sli1_prog_id = AbsWakeUpParms->sli1_prog_id; 3052fcf3ce44SJohn Forte WakeUpParms->sli2_prog_id = AbsWakeUpParms->sli2_prog_id; 3053fcf3ce44SJohn Forte WakeUpParms->sli3_prog_id = AbsWakeUpParms->sli3_prog_id; 3054fcf3ce44SJohn Forte WakeUpParms->sli4_prog_id = AbsWakeUpParms->sli4_prog_id; 3055fcf3ce44SJohn Forte 3056*82527734SSukumar Swaminathan emlxs_format_update_parms(mbox, WakeUpParms); 3057fcf3ce44SJohn Forte 3058*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 3059fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3060291a2b48SSukumar Swaminathan "Unable to update wakeup parameters: Mailbox cmd=%x " 3061291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 3062fcf3ce44SJohn Forte 3063fcf3ce44SJohn Forte rval = 1; 3064fcf3ce44SJohn Forte } 3065291a2b48SSukumar Swaminathan 3066fcf3ce44SJohn Forte if (mbox) { 3067fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 3068fcf3ce44SJohn Forte } 3069291a2b48SSukumar Swaminathan 3070fcf3ce44SJohn Forte return (rval); 3071fcf3ce44SJohn Forte 3072*82527734SSukumar Swaminathan } /* emlxs_update_wakeup_parms() */ 3073fcf3ce44SJohn Forte 3074fcf3ce44SJohn Forte 3075fcf3ce44SJohn Forte static uint32_t 3076291a2b48SSukumar Swaminathan emlxs_validate_version(emlxs_hba_t *hba, emlxs_fw_file_t *file, uint32_t id, 3077291a2b48SSukumar Swaminathan uint32_t type, char *file_type) 3078fcf3ce44SJohn Forte { 3079fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3080fcf3ce44SJohn Forte 3081fcf3ce44SJohn Forte /* Create the version label */ 3082fcf3ce44SJohn Forte emlxs_decode_version(file->version, file->label); 3083fcf3ce44SJohn Forte 3084fcf3ce44SJohn Forte /* Process the DWC type */ 3085fcf3ce44SJohn Forte switch (type) { 3086fcf3ce44SJohn Forte case TEST_PROGRAM: 3087fcf3ce44SJohn Forte 3088fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3089291a2b48SSukumar Swaminathan "%s: TEST: offset=%08x version=%08x, %s", file_type, 3090291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 3091fcf3ce44SJohn Forte 3092fcf3ce44SJohn Forte break; 3093fcf3ce44SJohn Forte 3094fcf3ce44SJohn Forte case BOOT_BIOS: 3095fcf3ce44SJohn Forte 3096fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3097291a2b48SSukumar Swaminathan "%s: BOOT: offset=%08x version=%08x, %s", file_type, 3098291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 3099fcf3ce44SJohn Forte 3100fcf3ce44SJohn Forte if (!emlxs_bios_check(hba, id)) { 3101fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3102fcf3ce44SJohn Forte "BOOT Check: Image not compatible with %s. id=%02x", 3103fcf3ce44SJohn Forte hba->model_info.model, id); 3104fcf3ce44SJohn Forte 3105fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 3106fcf3ce44SJohn Forte } 3107291a2b48SSukumar Swaminathan 3108fcf3ce44SJohn Forte break; 3109fcf3ce44SJohn Forte 3110fcf3ce44SJohn Forte case FUNC_FIRMWARE: /* Stub */ 3111fcf3ce44SJohn Forte 3112fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3113291a2b48SSukumar Swaminathan "%s: STUB: offset=%08x version=%08x, %s", file_type, 3114291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 3115fcf3ce44SJohn Forte 3116fcf3ce44SJohn Forte if (!emlxs_stub_check(hba, id)) { 3117fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3118fcf3ce44SJohn Forte "STUB Check: Image not compatible with %s. id=%02x", 3119fcf3ce44SJohn Forte hba->model_info.model, id); 3120fcf3ce44SJohn Forte 3121fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 3122fcf3ce44SJohn Forte } 3123291a2b48SSukumar Swaminathan 3124fcf3ce44SJohn Forte break; 3125fcf3ce44SJohn Forte 3126fcf3ce44SJohn Forte case SLI1_OVERLAY: 3127fcf3ce44SJohn Forte 3128fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3129291a2b48SSukumar Swaminathan "%s: SLI1: offset=%08x version=%08x, %s", file_type, 3130291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 3131fcf3ce44SJohn Forte 3132fcf3ce44SJohn Forte if (!emlxs_sli1_check(hba, id)) { 3133fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3134fcf3ce44SJohn Forte "SLI1 Check: Image not compatible with %s. id=%02x", 3135fcf3ce44SJohn Forte hba->model_info.model, id); 3136fcf3ce44SJohn Forte 3137fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 3138fcf3ce44SJohn Forte } 3139291a2b48SSukumar Swaminathan 3140fcf3ce44SJohn Forte break; 3141fcf3ce44SJohn Forte 3142fcf3ce44SJohn Forte case SLI2_OVERLAY: 3143fcf3ce44SJohn Forte 3144fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3145291a2b48SSukumar Swaminathan "%s: SLI2: offset=%08x version=%08x, %s", file_type, 3146291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 3147fcf3ce44SJohn Forte 3148fcf3ce44SJohn Forte if (!emlxs_sli2_check(hba, id)) { 3149fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3150fcf3ce44SJohn Forte "SLI2 Check: Image not compatible with %s. id=%02x", 3151fcf3ce44SJohn Forte hba->model_info.model, id); 3152fcf3ce44SJohn Forte 3153fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 3154fcf3ce44SJohn Forte } 3155291a2b48SSukumar Swaminathan 3156fcf3ce44SJohn Forte break; 3157fcf3ce44SJohn Forte 3158fcf3ce44SJohn Forte case SLI3_OVERLAY: 3159fcf3ce44SJohn Forte 3160fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3161291a2b48SSukumar Swaminathan "%s: SLI3: offset=%08x version=%08x, %s", file_type, 3162291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 3163fcf3ce44SJohn Forte 3164fcf3ce44SJohn Forte if (!emlxs_sli3_check(hba, id)) { 3165fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3166fcf3ce44SJohn Forte "SLI3 Check: Image not compatible with %s. id=%02x", 3167fcf3ce44SJohn Forte hba->model_info.model, id); 3168fcf3ce44SJohn Forte 3169fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 3170fcf3ce44SJohn Forte } 3171291a2b48SSukumar Swaminathan 3172fcf3ce44SJohn Forte break; 3173fcf3ce44SJohn Forte 3174fcf3ce44SJohn Forte case SLI4_OVERLAY: 3175fcf3ce44SJohn Forte 3176fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3177291a2b48SSukumar Swaminathan "%s: SLI4: offset=%08x version=%08x, %s", file_type, 3178291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 3179fcf3ce44SJohn Forte 3180fcf3ce44SJohn Forte if (!emlxs_sli4_check(hba, id)) { 3181fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3182fcf3ce44SJohn Forte "SLI4 Check: Image not compatible with %s. id=%02x", 3183fcf3ce44SJohn Forte hba->model_info.model, id); 3184fcf3ce44SJohn Forte 3185fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 3186fcf3ce44SJohn Forte } 3187291a2b48SSukumar Swaminathan 3188fcf3ce44SJohn Forte break; 3189fcf3ce44SJohn Forte 3190fcf3ce44SJohn Forte case SBUS_FCODE: 3191fcf3ce44SJohn Forte 3192fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3193fcf3ce44SJohn Forte "%s: SBUS FCODE: offset=%08x version=%08x, %s", 3194291a2b48SSukumar Swaminathan file_type, file->offset, file->version, file->label); 3195fcf3ce44SJohn Forte 3196fcf3ce44SJohn Forte if (!emlxs_sbus_fcode_check(hba, id)) { 3197fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3198fcf3ce44SJohn Forte "SBUS FCODE Check: Image not compatible with %s. " 3199291a2b48SSukumar Swaminathan "id=%02x", hba->model_info.model, id); 3200fcf3ce44SJohn Forte 3201fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 3202fcf3ce44SJohn Forte } 3203291a2b48SSukumar Swaminathan 3204fcf3ce44SJohn Forte break; 3205fcf3ce44SJohn Forte 3206fcf3ce44SJohn Forte case KERNEL_CODE: 3207fcf3ce44SJohn Forte 3208fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 3209291a2b48SSukumar Swaminathan "%s: KERN: offset=%08x version=%08x, %s", file_type, 3210291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 3211fcf3ce44SJohn Forte 3212fcf3ce44SJohn Forte if (!emlxs_kern_check(hba, id)) { 3213fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 3214fcf3ce44SJohn Forte "KERN Check: Image not compatible with %s. id=%02x", 3215fcf3ce44SJohn Forte hba->model_info.model, id); 3216fcf3ce44SJohn Forte 3217fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 3218fcf3ce44SJohn Forte } 3219291a2b48SSukumar Swaminathan 3220fcf3ce44SJohn Forte break; 3221fcf3ce44SJohn Forte 3222fcf3ce44SJohn Forte default: 3223fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 3224291a2b48SSukumar Swaminathan "%s: Image type not supported. type=%x", file_type, type); 3225fcf3ce44SJohn Forte 3226fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 3227fcf3ce44SJohn Forte } 3228fcf3ce44SJohn Forte 3229fcf3ce44SJohn Forte return (0); 3230fcf3ce44SJohn Forte 3231*82527734SSukumar Swaminathan } /* emlxs_validate_version() */ 3232fcf3ce44SJohn Forte 3233fcf3ce44SJohn Forte 3234fcf3ce44SJohn Forte static uint32_t 3235fcf3ce44SJohn Forte emlxs_validate_image(emlxs_hba_t *hba, caddr_t Buffer, uint32_t Size, 3236fcf3ce44SJohn Forte emlxs_fw_image_t *image) 3237fcf3ce44SJohn Forte { 3238fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3239fcf3ce44SJohn Forte uint32_t ImageType; 3240fcf3ce44SJohn Forte AIF_HDR AifHdr; 3241fcf3ce44SJohn Forte IMAGE_HDR ImageHdr; 3242fcf3ce44SJohn Forte uint32_t NextImage; 3243fcf3ce44SJohn Forte uint32_t FileType; 3244fcf3ce44SJohn Forte uint32_t FileLen = 0; 3245fcf3ce44SJohn Forte uint32_t TotalLen = 0; 3246fcf3ce44SJohn Forte uint32_t *CkSumEnd; 3247fcf3ce44SJohn Forte uint32_t id; 3248fcf3ce44SJohn Forte uint32_t type; 3249fcf3ce44SJohn Forte uint32_t ver; 3250fcf3ce44SJohn Forte uint32_t ImageLength; 3251fcf3ce44SJohn Forte uint32_t BufferSize; 3252fcf3ce44SJohn Forte uint32_t rval = 0; 3253fcf3ce44SJohn Forte caddr_t bptr; 3254fcf3ce44SJohn Forte emlxs_vpd_t *vpd; 3255fcf3ce44SJohn Forte 3256fcf3ce44SJohn Forte vpd = &VPD; 3257fcf3ce44SJohn Forte 3258fcf3ce44SJohn Forte /* Get image type */ 3259fcf3ce44SJohn Forte ImageType = *((uint32_t *)Buffer); 3260fcf3ce44SJohn Forte 3261fcf3ce44SJohn Forte /* Pegasus and beyond adapters */ 3262fcf3ce44SJohn Forte if ((ImageType == NOP_IMAGE_TYPE) && 3263fcf3ce44SJohn Forte !(hba->model_info.chip & 3264fcf3ce44SJohn Forte (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 3265fcf3ce44SJohn Forte bptr = Buffer; 3266fcf3ce44SJohn Forte TotalLen = sizeof (uint32_t); 3267fcf3ce44SJohn Forte 3268fcf3ce44SJohn Forte while (TotalLen < Size) { 3269fcf3ce44SJohn Forte if (Size < sizeof (AIF_HDR)) { 3270291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 3271291a2b48SSukumar Swaminathan &emlxs_image_bad_msg, 3272fcf3ce44SJohn Forte "Invalid image header length: 0x%x < 0x%x", 3273fcf3ce44SJohn Forte Size, sizeof (AIF_HDR)); 3274fcf3ce44SJohn Forte 3275fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 3276fcf3ce44SJohn Forte } 3277291a2b48SSukumar Swaminathan 3278fcf3ce44SJohn Forte bcopy(bptr, &AifHdr, sizeof (AIF_HDR)); 3279fcf3ce44SJohn Forte emlxs_disp_aif_header(hba, &AifHdr); 3280fcf3ce44SJohn Forte 3281fcf3ce44SJohn Forte ImageLength = AifHdr.RoSize; 3282fcf3ce44SJohn Forte 3283fcf3ce44SJohn Forte /* Validate checksum */ 3284291a2b48SSukumar Swaminathan CkSumEnd = 3285291a2b48SSukumar Swaminathan (uint32_t *)(bptr + ImageLength + 3286291a2b48SSukumar Swaminathan sizeof (AIF_HDR)); 3287fcf3ce44SJohn Forte if (emlxs_valid_cksum((uint32_t *)bptr, CkSumEnd)) { 3288291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 3289291a2b48SSukumar Swaminathan &emlxs_image_bad_msg, 3290fcf3ce44SJohn Forte "Invalid checksum found."); 3291fcf3ce44SJohn Forte 3292fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 3293fcf3ce44SJohn Forte } 3294291a2b48SSukumar Swaminathan 3295fcf3ce44SJohn Forte FileType = AifHdr.ZinitBr; 3296fcf3ce44SJohn Forte switch (FileType) { 3297fcf3ce44SJohn Forte case FILE_TYPE_AWC: 3298291a2b48SSukumar Swaminathan image->awc.offset = 3299291a2b48SSukumar Swaminathan (uint32_t)((uintptr_t)bptr - 3300291a2b48SSukumar Swaminathan (uintptr_t)Buffer); 3301fcf3ce44SJohn Forte image->awc.version = AifHdr.AVersion; 3302fcf3ce44SJohn Forte image->awc.revcomp = 0; 3303fcf3ce44SJohn Forte 3304fcf3ce44SJohn Forte id = (AifHdr.AVersion & 0x00ff0000) >> 16; 3305fcf3ce44SJohn Forte type = emlxs_type_check( 3306fcf3ce44SJohn Forte (AifHdr.AVersion & 0xff000000) >> 24); 3307fcf3ce44SJohn Forte 3308fcf3ce44SJohn Forte /* Validate the file version */ 3309fcf3ce44SJohn Forte if ((rval = emlxs_validate_version(hba, 3310fcf3ce44SJohn Forte &image->awc, id, type, "AWC file"))) { 3311fcf3ce44SJohn Forte return (rval); 3312fcf3ce44SJohn Forte } 3313291a2b48SSukumar Swaminathan 3314fcf3ce44SJohn Forte break; 3315fcf3ce44SJohn Forte 3316fcf3ce44SJohn Forte case FILE_TYPE_BWC: 3317291a2b48SSukumar Swaminathan image->bwc.offset = 3318291a2b48SSukumar Swaminathan (uint32_t)((uintptr_t)bptr - 3319291a2b48SSukumar Swaminathan (uintptr_t)Buffer); 3320fcf3ce44SJohn Forte image->bwc.version = AifHdr.AVersion; 3321fcf3ce44SJohn Forte image->bwc.revcomp = 0; 3322fcf3ce44SJohn Forte 3323fcf3ce44SJohn Forte id = (AifHdr.AVersion & 0x00ff0000) >> 16; 3324fcf3ce44SJohn Forte type = emlxs_type_check( 3325fcf3ce44SJohn Forte (AifHdr.AVersion & 0xff000000) >> 24); 3326fcf3ce44SJohn Forte 3327fcf3ce44SJohn Forte /* Validate the file version */ 3328fcf3ce44SJohn Forte if ((rval = emlxs_validate_version(hba, 3329fcf3ce44SJohn Forte &image->bwc, id, type, "BWC file"))) { 3330fcf3ce44SJohn Forte return (rval); 3331fcf3ce44SJohn Forte } 3332291a2b48SSukumar Swaminathan 3333fcf3ce44SJohn Forte break; 3334fcf3ce44SJohn Forte 3335fcf3ce44SJohn Forte case FILE_TYPE_DWC: 3336291a2b48SSukumar Swaminathan image->dwc.offset = 3337291a2b48SSukumar Swaminathan (uint32_t)((uintptr_t)bptr - 3338291a2b48SSukumar Swaminathan (uintptr_t)Buffer); 3339fcf3ce44SJohn Forte image->dwc.version = AifHdr.AVersion; 3340fcf3ce44SJohn Forte image->dwc.revcomp = 0; 3341fcf3ce44SJohn Forte 3342fcf3ce44SJohn Forte id = (AifHdr.AVersion & 0x00ff0000) >> 16; 3343fcf3ce44SJohn Forte type = emlxs_type_check( 3344fcf3ce44SJohn Forte (AifHdr.AVersion & 0xff000000) >> 24); 3345fcf3ce44SJohn Forte 3346fcf3ce44SJohn Forte /* Validate the file version */ 3347fcf3ce44SJohn Forte if ((rval = emlxs_validate_version(hba, 3348fcf3ce44SJohn Forte &image->dwc, id, type, "DWC file"))) { 3349fcf3ce44SJohn Forte return (rval); 3350fcf3ce44SJohn Forte } 3351291a2b48SSukumar Swaminathan 3352fcf3ce44SJohn Forte /* Scan for program types */ 3353fcf3ce44SJohn Forte NextImage = sizeof (AIF_HDR) + 4; 3354fcf3ce44SJohn Forte BufferSize = AifHdr.RoSize + AifHdr.RwSize; 3355fcf3ce44SJohn Forte 3356fcf3ce44SJohn Forte while (BufferSize > NextImage) { 3357fcf3ce44SJohn Forte bcopy(&bptr[NextImage], &ImageHdr, 3358fcf3ce44SJohn Forte sizeof (IMAGE_HDR)); 3359291a2b48SSukumar Swaminathan emlxs_dump_image_header(hba, 3360291a2b48SSukumar Swaminathan &ImageHdr); 3361fcf3ce44SJohn Forte 3362fcf3ce44SJohn Forte /* Validate block size */ 3363fcf3ce44SJohn Forte if (ImageHdr.BlockSize == 0xffffffff) { 3364fcf3ce44SJohn Forte break; 3365fcf3ce44SJohn Forte } 3366291a2b48SSukumar Swaminathan 3367fcf3ce44SJohn Forte type = emlxs_type_check( 3368fcf3ce44SJohn Forte ImageHdr.Id.Type); 3369fcf3ce44SJohn Forte 3370fcf3ce44SJohn Forte /* Calculate the program offset */ 3371291a2b48SSukumar Swaminathan image->prog[type].offset = 3372291a2b48SSukumar Swaminathan (uint32_t)((uintptr_t) 3373291a2b48SSukumar Swaminathan &bptr[NextImage] - 3374fcf3ce44SJohn Forte (uintptr_t)Buffer); 3375fcf3ce44SJohn Forte 3376fcf3ce44SJohn Forte /* Acquire the versions */ 3377fcf3ce44SJohn Forte image->prog[type].version = 3378fcf3ce44SJohn Forte (ImageHdr.Id.Type << 24) | 3379fcf3ce44SJohn Forte (ImageHdr.Id.Id << 16) | 3380fcf3ce44SJohn Forte (ImageHdr.Id.Ver << 8) | 3381fcf3ce44SJohn Forte ImageHdr.Id.Rev; 3382fcf3ce44SJohn Forte 3383fcf3ce44SJohn Forte image->prog[type].revcomp = 3384fcf3ce44SJohn Forte ImageHdr.Id.un.revcomp; 3385fcf3ce44SJohn Forte 3386fcf3ce44SJohn Forte /* Validate the file version */ 3387fcf3ce44SJohn Forte if ((rval = emlxs_validate_version(hba, 3388fcf3ce44SJohn Forte &image->prog[type], ImageHdr.Id.Id, 3389fcf3ce44SJohn Forte type, "DWC prog"))) { 3390fcf3ce44SJohn Forte return (rval); 3391fcf3ce44SJohn Forte } 3392291a2b48SSukumar Swaminathan 3393fcf3ce44SJohn Forte NextImage += ImageHdr.BlockSize; 3394fcf3ce44SJohn Forte 3395*82527734SSukumar Swaminathan } /* while () */ 3396fcf3ce44SJohn Forte 3397fcf3ce44SJohn Forte break; 3398fcf3ce44SJohn Forte } 3399fcf3ce44SJohn Forte 3400291a2b48SSukumar Swaminathan FileLen = 3401291a2b48SSukumar Swaminathan sizeof (AIF_HDR) + ImageLength + 3402fcf3ce44SJohn Forte sizeof (uint32_t); 3403fcf3ce44SJohn Forte TotalLen += FileLen; 3404fcf3ce44SJohn Forte bptr += FileLen; 3405fcf3ce44SJohn Forte } 3406fcf3ce44SJohn Forte } 3407291a2b48SSukumar Swaminathan 3408fcf3ce44SJohn Forte /* Pre-pegasus adapters */ 3409fcf3ce44SJohn Forte 3410fcf3ce44SJohn Forte else if (ImageType == NOP_IMAGE_TYPE) { 3411fcf3ce44SJohn Forte if (Size < sizeof (AIF_HDR)) { 3412fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 3413291a2b48SSukumar Swaminathan "Invalid image header length: 0x%x < 0x%x", Size, 3414291a2b48SSukumar Swaminathan sizeof (AIF_HDR)); 3415fcf3ce44SJohn Forte 3416fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 3417fcf3ce44SJohn Forte } 3418291a2b48SSukumar Swaminathan 3419fcf3ce44SJohn Forte bcopy(Buffer, &AifHdr, sizeof (AIF_HDR)); 3420fcf3ce44SJohn Forte emlxs_disp_aif_header(hba, &AifHdr); 3421fcf3ce44SJohn Forte 3422fcf3ce44SJohn Forte ImageLength = AifHdr.RoSize + AifHdr.RwSize; 3423fcf3ce44SJohn Forte 3424fcf3ce44SJohn Forte if (Size != (sizeof (AIF_HDR) + ImageLength + sizeof (int))) { 3425fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 3426291a2b48SSukumar Swaminathan "Image length incorrect: 0x%x != 0x%x", Size, 3427291a2b48SSukumar Swaminathan sizeof (AIF_HDR) + ImageLength + 3428291a2b48SSukumar Swaminathan sizeof (uint32_t)); 3429fcf3ce44SJohn Forte 3430fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 3431fcf3ce44SJohn Forte } 3432291a2b48SSukumar Swaminathan 3433fcf3ce44SJohn Forte if (AifHdr.ImageBase && AifHdr.ImageBase != 0x20000) { 3434fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 3435fcf3ce44SJohn Forte "Invalid imageBase value %x != 0x20000", 3436fcf3ce44SJohn Forte AifHdr.ImageBase); 3437fcf3ce44SJohn Forte 3438fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 3439fcf3ce44SJohn Forte } 3440291a2b48SSukumar Swaminathan 3441291a2b48SSukumar Swaminathan CkSumEnd = 3442291a2b48SSukumar Swaminathan (uint32_t *)(Buffer + ImageLength + sizeof (AIF_HDR)); 3443fcf3ce44SJohn Forte if (emlxs_valid_cksum((uint32_t *)Buffer, CkSumEnd)) { 3444fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 3445fcf3ce44SJohn Forte "Invalid checksum found."); 3446fcf3ce44SJohn Forte 3447fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 3448fcf3ce44SJohn Forte } 3449291a2b48SSukumar Swaminathan 3450fcf3ce44SJohn Forte image->dwc.offset = 0; 3451fcf3ce44SJohn Forte image->dwc.version = AifHdr.AVersion; 3452fcf3ce44SJohn Forte image->dwc.revcomp = 0; 3453fcf3ce44SJohn Forte 3454fcf3ce44SJohn Forte id = (AifHdr.AVersion & 0x00ff0000) >> 16; 3455fcf3ce44SJohn Forte type = emlxs_type_check((AifHdr.AVersion & 0xff000000) >> 24); 3456fcf3ce44SJohn Forte 3457fcf3ce44SJohn Forte /* Validate the file version */ 3458291a2b48SSukumar Swaminathan if ((rval = emlxs_validate_version(hba, &image->dwc, id, type, 3459291a2b48SSukumar Swaminathan "DWC file"))) { 3460fcf3ce44SJohn Forte return (rval); 3461fcf3ce44SJohn Forte } 3462291a2b48SSukumar Swaminathan 3463fcf3ce44SJohn Forte NextImage = SLI_IMAGE_START - AifHdr.ImageBase; 3464fcf3ce44SJohn Forte while (Size > NextImage) { 3465fcf3ce44SJohn Forte bcopy(&Buffer[NextImage], &ImageHdr, 3466fcf3ce44SJohn Forte sizeof (IMAGE_HDR)); 3467fcf3ce44SJohn Forte emlxs_dump_image_header(hba, &ImageHdr); 3468fcf3ce44SJohn Forte 3469fcf3ce44SJohn Forte /* Validate block size */ 3470fcf3ce44SJohn Forte if (ImageHdr.BlockSize == 0xffffffff) { 3471fcf3ce44SJohn Forte break; 3472fcf3ce44SJohn Forte } 3473291a2b48SSukumar Swaminathan 3474fcf3ce44SJohn Forte type = emlxs_type_check(ImageHdr.Id.Type); 3475fcf3ce44SJohn Forte 3476fcf3ce44SJohn Forte /* Calculate the program offset */ 3477fcf3ce44SJohn Forte image->prog[type].offset = NextImage; 3478fcf3ce44SJohn Forte 3479fcf3ce44SJohn Forte /* Acquire the versions */ 3480291a2b48SSukumar Swaminathan image->prog[type].version = 3481291a2b48SSukumar Swaminathan (ImageHdr.Id.Type << 24) | 3482291a2b48SSukumar Swaminathan (ImageHdr.Id.Id << 16) | 3483291a2b48SSukumar Swaminathan (ImageHdr.Id.Ver << 8) | 3484fcf3ce44SJohn Forte ImageHdr.Id.Rev; 3485fcf3ce44SJohn Forte 3486fcf3ce44SJohn Forte image->prog[type].revcomp = ImageHdr.Id.un.revcomp; 3487fcf3ce44SJohn Forte 3488fcf3ce44SJohn Forte /* Validate the file version */ 3489fcf3ce44SJohn Forte if ((rval = emlxs_validate_version(hba, 3490291a2b48SSukumar Swaminathan &image->prog[type], ImageHdr.Id.Id, type, 3491291a2b48SSukumar Swaminathan "DWC prog"))) { 3492fcf3ce44SJohn Forte return (rval); 3493fcf3ce44SJohn Forte } 3494291a2b48SSukumar Swaminathan 3495fcf3ce44SJohn Forte NextImage += ImageHdr.BlockSize; 3496fcf3ce44SJohn Forte } 3497fcf3ce44SJohn Forte } else { 3498fcf3ce44SJohn Forte /* Precheck image size */ 3499fcf3ce44SJohn Forte if (Size < sizeof (IMAGE_HDR)) { 3500fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 3501291a2b48SSukumar Swaminathan "Invalid image header length: 0x%x < 0x%x", Size, 3502291a2b48SSukumar Swaminathan sizeof (IMAGE_HDR)); 3503fcf3ce44SJohn Forte 3504fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 3505fcf3ce44SJohn Forte } 3506291a2b48SSukumar Swaminathan 3507fcf3ce44SJohn Forte bcopy(Buffer, &ImageHdr, sizeof (IMAGE_HDR)); 3508fcf3ce44SJohn Forte emlxs_dump_image_header(hba, &ImageHdr); 3509fcf3ce44SJohn Forte 3510fcf3ce44SJohn Forte /* Validate block size */ 3511fcf3ce44SJohn Forte if (ImageHdr.BlockSize == 0xffffffff) { 3512fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 3513fcf3ce44SJohn Forte "Invalid block size."); 3514fcf3ce44SJohn Forte 3515fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 3516fcf3ce44SJohn Forte } 3517291a2b48SSukumar Swaminathan 3518fcf3ce44SJohn Forte ImageLength = ImageHdr.BlockSize; 3519fcf3ce44SJohn Forte 3520fcf3ce44SJohn Forte /* Validate image length */ 3521fcf3ce44SJohn Forte if (Size != ImageLength) { 3522fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 3523291a2b48SSukumar Swaminathan "Invalid image length: 0x%x != 0x%x", Size, 3524291a2b48SSukumar Swaminathan ImageLength); 3525fcf3ce44SJohn Forte 3526fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 3527fcf3ce44SJohn Forte } 3528291a2b48SSukumar Swaminathan 3529fcf3ce44SJohn Forte /* Validate Checksum */ 3530291a2b48SSukumar Swaminathan CkSumEnd = 3531291a2b48SSukumar Swaminathan (uint32_t *)Buffer + (ImageLength / sizeof (uint32_t)) - 3532291a2b48SSukumar Swaminathan 1; 3533fcf3ce44SJohn Forte if (emlxs_valid_cksum((uint32_t *)Buffer, CkSumEnd)) { 3534fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 3535fcf3ce44SJohn Forte "Invalid checksum found."); 3536fcf3ce44SJohn Forte 3537fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 3538fcf3ce44SJohn Forte } 3539291a2b48SSukumar Swaminathan 3540fcf3ce44SJohn Forte type = emlxs_type_check(ImageHdr.Id.Type); 3541fcf3ce44SJohn Forte 3542fcf3ce44SJohn Forte /* Calculate the program offset */ 3543fcf3ce44SJohn Forte image->prog[type].offset = 0; 3544fcf3ce44SJohn Forte 3545fcf3ce44SJohn Forte /* Acquire the versions */ 3546291a2b48SSukumar Swaminathan image->prog[type].version = 3547291a2b48SSukumar Swaminathan (ImageHdr.Id.Type << 24) | (ImageHdr.Id. 3548291a2b48SSukumar Swaminathan Id << 16) | (ImageHdr.Id.Ver << 8) | ImageHdr.Id.Rev; 3549fcf3ce44SJohn Forte 3550fcf3ce44SJohn Forte image->prog[type].revcomp = ImageHdr.Id.un.revcomp; 3551fcf3ce44SJohn Forte 3552fcf3ce44SJohn Forte /* Validate the file version */ 3553fcf3ce44SJohn Forte if ((rval = emlxs_validate_version(hba, &image->prog[type], 3554fcf3ce44SJohn Forte ImageHdr.Id.Id, type, "DWC file"))) { 3555fcf3ce44SJohn Forte return (rval); 3556fcf3ce44SJohn Forte } 3557fcf3ce44SJohn Forte } 3558fcf3ce44SJohn Forte 3559fcf3ce44SJohn Forte /* 3560291a2b48SSukumar Swaminathan * This checks if a DragonFly (pre-V2 ASIC) SLI2 3561291a2b48SSukumar Swaminathan * image file is greater than version 3.8 3562fcf3ce44SJohn Forte */ 3563fcf3ce44SJohn Forte if (FC_JEDEC_ID(vpd->biuRev) == DRAGONFLY_JEDEC_ID) { 3564fcf3ce44SJohn Forte if (image->prog[SLI2_OVERLAY].version != 0) { 3565fcf3ce44SJohn Forte ver = (image->prog[SLI2_OVERLAY].version & 3566fcf3ce44SJohn Forte 0x0000ff00) >> 8; 3567fcf3ce44SJohn Forte 3568fcf3ce44SJohn Forte if ((((ver & 0xf0) == 0x30) && 3569fcf3ce44SJohn Forte ((ver & 0x0f) >= 0x08)) || 3570fcf3ce44SJohn Forte ((ver & 0xf0) > 0x30)) { 3571fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3572fcf3ce44SJohn Forte &emlxs_image_incompat_msg, 3573291a2b48SSukumar Swaminathan "ASIC Check: Image requires DragonFly " 3574291a2b48SSukumar Swaminathan "V2 ASIC"); 3575fcf3ce44SJohn Forte 3576fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 3577fcf3ce44SJohn Forte } 3578fcf3ce44SJohn Forte } 3579fcf3ce44SJohn Forte } 3580291a2b48SSukumar Swaminathan 3581fcf3ce44SJohn Forte return (0); 3582fcf3ce44SJohn Forte 3583*82527734SSukumar Swaminathan } /* emlxs_validate_image() */ 3584fcf3ce44SJohn Forte 3585fcf3ce44SJohn Forte 3586fcf3ce44SJohn Forte static uint32_t 3587fcf3ce44SJohn Forte emlxs_update_exp_rom(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms) 3588fcf3ce44SJohn Forte { 3589fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3590fcf3ce44SJohn Forte MAILBOXQ *mbox; 3591fcf3ce44SJohn Forte MAILBOX *mb; 3592fcf3ce44SJohn Forte uint32_t next_address; 3593fcf3ce44SJohn Forte uint32_t rval = 0; 3594fcf3ce44SJohn Forte 3595fcf3ce44SJohn Forte if (WakeUpParms->u1.EROM_prog_wd[0] == 0) { 3596fcf3ce44SJohn Forte return (1); 3597fcf3ce44SJohn Forte } 3598291a2b48SSukumar Swaminathan 3599291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 3600291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 3601fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3602fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 3603fcf3ce44SJohn Forte 3604fcf3ce44SJohn Forte return (1); 3605fcf3ce44SJohn Forte } 3606291a2b48SSukumar Swaminathan 3607fcf3ce44SJohn Forte bzero(mbox, sizeof (MAILBOXQ)); 3608fcf3ce44SJohn Forte 3609fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 3610fcf3ce44SJohn Forte mb->mbxCommand = MBX_LOAD_EXP_ROM; 3611fcf3ce44SJohn Forte mb->un.varLdExpRom.step = EROM_CMD_FIND_IMAGE; 3612fcf3ce44SJohn Forte mb->un.varLdExpRom.progress = 0; 3613fcf3ce44SJohn Forte mb->un.varLdExpRom.un.prog_id = WakeUpParms->u1.EROM_prog_id; 3614*82527734SSukumar Swaminathan mbox->mbox_cmpl = NULL; 3615fcf3ce44SJohn Forte 3616*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 3617fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3618fcf3ce44SJohn Forte "Unable to load exp ROM. Mailbox cmd=%x status=%x", 3619fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 3620fcf3ce44SJohn Forte 3621fcf3ce44SJohn Forte rval = 1; 3622fcf3ce44SJohn Forte 3623fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 3624fcf3ce44SJohn Forte } 3625291a2b48SSukumar Swaminathan 3626fcf3ce44SJohn Forte if (mb->un.varLdExpRom.progress == EROM_RSP_COPY_DONE) { 3627fcf3ce44SJohn Forte (void) emlxs_update_wakeup_parms(hba, WakeUpParms, WakeUpParms); 3628fcf3ce44SJohn Forte 3629fcf3ce44SJohn Forte rval = 1; 3630fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 3631fcf3ce44SJohn Forte } 3632291a2b48SSukumar Swaminathan 3633fcf3ce44SJohn Forte if (mb->un.varLdExpRom.progress != EROM_RSP_ERASE_STARTED) { 3634fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3635fcf3ce44SJohn Forte "Invalid exp ROM progress. progress=%x", 3636fcf3ce44SJohn Forte mb->un.varLdExpRom.progress); 3637fcf3ce44SJohn Forte 3638fcf3ce44SJohn Forte rval = 1; 3639fcf3ce44SJohn Forte 3640fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 3641fcf3ce44SJohn Forte } 3642291a2b48SSukumar Swaminathan 3643fcf3ce44SJohn Forte /* 3644fcf3ce44SJohn Forte * continue Erase 3645fcf3ce44SJohn Forte */ 3646fcf3ce44SJohn Forte while (mb->un.varLdExpRom.progress != EROM_RSP_ERASE_COMPLETE) { 3647fcf3ce44SJohn Forte 3648fcf3ce44SJohn Forte next_address = mb->un.varLdExpRom.dl_to_adr; 3649fcf3ce44SJohn Forte 3650fcf3ce44SJohn Forte bzero((void *)mb, MAILBOX_CMD_BSIZE); 3651fcf3ce44SJohn Forte 3652fcf3ce44SJohn Forte mb->mbxCommand = MBX_LOAD_EXP_ROM; 3653fcf3ce44SJohn Forte mb->un.varLdExpRom.step = EROM_CMD_CONTINUE_ERASE; 3654fcf3ce44SJohn Forte mb->un.varLdExpRom.dl_to_adr = next_address; 3655fcf3ce44SJohn Forte mb->un.varLdExpRom.progress = 0; 3656fcf3ce44SJohn Forte mb->un.varLdExpRom.un.prog_id = WakeUpParms->u1.EROM_prog_id; 3657*82527734SSukumar Swaminathan mbox->mbox_cmpl = NULL; 3658fcf3ce44SJohn Forte 3659*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 3660291a2b48SSukumar Swaminathan MBX_SUCCESS) { 3661fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3662fcf3ce44SJohn Forte "Unable to load exp ROM. Mailbox cmd=%x status=%x", 3663fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 3664fcf3ce44SJohn Forte 3665fcf3ce44SJohn Forte rval = 1; 3666fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 3667fcf3ce44SJohn Forte } 3668291a2b48SSukumar Swaminathan 3669fcf3ce44SJohn Forte } 3670fcf3ce44SJohn Forte 3671fcf3ce44SJohn Forte while (mb->un.varLdExpRom.progress != EROM_RSP_COPY_DONE) { 3672fcf3ce44SJohn Forte next_address = mb->un.varLdExpRom.dl_to_adr; 3673fcf3ce44SJohn Forte 3674fcf3ce44SJohn Forte bzero((void *)mb, MAILBOX_CMD_BSIZE); 3675fcf3ce44SJohn Forte 3676fcf3ce44SJohn Forte mb->mbxCommand = MBX_LOAD_EXP_ROM; 3677fcf3ce44SJohn Forte mb->un.varLdExpRom.step = EROM_CMD_COPY; 3678fcf3ce44SJohn Forte mb->un.varLdExpRom.dl_to_adr = next_address; 3679fcf3ce44SJohn Forte mb->un.varLdExpRom.progress = 0; 3680fcf3ce44SJohn Forte mb->un.varLdExpRom.un.prog_id = WakeUpParms->u1.EROM_prog_id; 3681*82527734SSukumar Swaminathan mbox->mbox_cmpl = NULL; 3682fcf3ce44SJohn Forte 3683*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 3684291a2b48SSukumar Swaminathan MBX_SUCCESS) { 3685fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3686fcf3ce44SJohn Forte "Unable to load exp ROM. Mailbox cmd=%x status=%x", 3687fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 3688fcf3ce44SJohn Forte 3689fcf3ce44SJohn Forte rval = 1; 3690fcf3ce44SJohn Forte 3691fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 3692fcf3ce44SJohn Forte } 3693fcf3ce44SJohn Forte } 3694fcf3ce44SJohn Forte 3695fcf3ce44SJohn Forte rval = emlxs_update_wakeup_parms(hba, WakeUpParms, WakeUpParms); 3696fcf3ce44SJohn Forte 3697fcf3ce44SJohn Forte SLI_DOWNLOAD_EXIT: 3698fcf3ce44SJohn Forte 3699fcf3ce44SJohn Forte if (mbox) { 3700fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 3701fcf3ce44SJohn Forte } 3702291a2b48SSukumar Swaminathan 3703fcf3ce44SJohn Forte return (rval); 3704fcf3ce44SJohn Forte 3705*82527734SSukumar Swaminathan } /* emlxs_update_exp_rom() */ 3706fcf3ce44SJohn Forte 3707fcf3ce44SJohn Forte 3708fcf3ce44SJohn Forte /* 3709fcf3ce44SJohn Forte * 3710fcf3ce44SJohn Forte * FUNCTION NAME: emlxs_start_abs_download_2mb 3711fcf3ce44SJohn Forte * 3712fcf3ce44SJohn Forte * DESCRIPTION: Perform absolute download for 2 MB flash. A incoming 3713fcf3ce44SJohn Forte * buffer may consist of more than 1 file. This function 3714fcf3ce44SJohn Forte * will parse the buffer to find all the files. 3715fcf3ce44SJohn Forte * 3716fcf3ce44SJohn Forte * 3717fcf3ce44SJohn Forte * PARAMETERS: 3718fcf3ce44SJohn Forte * 3719fcf3ce44SJohn Forte * 3720fcf3ce44SJohn Forte * RETURNS: 3721fcf3ce44SJohn Forte * 3722fcf3ce44SJohn Forte */ 3723fcf3ce44SJohn Forte /* ARGSUSED */ 3724fcf3ce44SJohn Forte static uint32_t 3725fcf3ce44SJohn Forte emlxs_start_abs_download_2mb(emlxs_hba_t *hba, caddr_t buffer, uint32_t len, 3726fcf3ce44SJohn Forte uint32_t offline, emlxs_fw_image_t *fw_image) 3727fcf3ce44SJohn Forte { 3728fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3729fcf3ce44SJohn Forte caddr_t AwcBuffer = NULL; 3730fcf3ce44SJohn Forte caddr_t BwcBuffer = NULL; 3731fcf3ce44SJohn Forte caddr_t DwcBuffer = NULL; 3732fcf3ce44SJohn Forte AIF_HDR *AwcAifHdr; 3733fcf3ce44SJohn Forte AIF_HDR *BwcAifHdr; 3734fcf3ce44SJohn Forte AIF_HDR *DwcAifHdr; 3735fcf3ce44SJohn Forte uint32_t BWCflag; 3736fcf3ce44SJohn Forte emlxs_vpd_t *vpd; 3737fcf3ce44SJohn Forte uint32_t i; 3738fcf3ce44SJohn Forte uint32_t count; 3739fcf3ce44SJohn Forte uint32_t extType = 0; 3740fcf3ce44SJohn Forte uint32_t rval = 0; 3741fcf3ce44SJohn Forte 3742fcf3ce44SJohn Forte vpd = &VPD; 3743fcf3ce44SJohn Forte 3744fcf3ce44SJohn Forte /* Check for AWC file */ 3745fcf3ce44SJohn Forte if (fw_image->awc.version) { 3746fcf3ce44SJohn Forte AwcBuffer = buffer + fw_image->awc.offset; 3747291a2b48SSukumar Swaminathan AwcAifHdr = (AIF_HDR *)AwcBuffer; 3748fcf3ce44SJohn Forte } 3749291a2b48SSukumar Swaminathan 3750fcf3ce44SJohn Forte /* Check for BWC file */ 3751fcf3ce44SJohn Forte if (fw_image->bwc.version) { 3752fcf3ce44SJohn Forte extType = BWCext; 3753fcf3ce44SJohn Forte BwcBuffer = buffer + fw_image->bwc.offset; 3754291a2b48SSukumar Swaminathan BwcAifHdr = (AIF_HDR *)BwcBuffer; 3755fcf3ce44SJohn Forte } 3756291a2b48SSukumar Swaminathan 3757fcf3ce44SJohn Forte /* Check for DWC file */ 3758fcf3ce44SJohn Forte if (fw_image->dwc.version) { 3759fcf3ce44SJohn Forte extType = DWCext; 3760fcf3ce44SJohn Forte DwcBuffer = buffer + fw_image->dwc.offset; 3761291a2b48SSukumar Swaminathan DwcAifHdr = (AIF_HDR *)DwcBuffer; 3762fcf3ce44SJohn Forte } 3763291a2b48SSukumar Swaminathan 3764fcf3ce44SJohn Forte /* Check for program files */ 3765fcf3ce44SJohn Forte count = 0; 3766fcf3ce44SJohn Forte for (i = 0; i < MAX_PROG_TYPES; i++) { 3767fcf3ce44SJohn Forte if (fw_image->prog[i].version) { 3768fcf3ce44SJohn Forte count++; 3769fcf3ce44SJohn Forte } 3770fcf3ce44SJohn Forte } 3771fcf3ce44SJohn Forte 3772fcf3ce44SJohn Forte if (count > 1) { 3773fcf3ce44SJohn Forte extType = ALLext; 3774fcf3ce44SJohn Forte 3775fcf3ce44SJohn Forte if (fw_image->bwc.version) { 3776fcf3ce44SJohn Forte BWCflag = ALL_WITH_BWC; 3777fcf3ce44SJohn Forte } else { 3778fcf3ce44SJohn Forte BWCflag = ALL_WITHOUT_BWC; 3779fcf3ce44SJohn Forte } 3780fcf3ce44SJohn Forte } else { 3781fcf3ce44SJohn Forte BWCflag = NO_ALL; 3782fcf3ce44SJohn Forte } 3783fcf3ce44SJohn Forte 3784fcf3ce44SJohn Forte /* If nothing to download then quit now */ 3785fcf3ce44SJohn Forte if (!AwcBuffer && !DwcBuffer && !BwcBuffer) { 3786fcf3ce44SJohn Forte return (0); 3787fcf3ce44SJohn Forte } 3788291a2b48SSukumar Swaminathan 3789fcf3ce44SJohn Forte /* 3790fcf3ce44SJohn Forte * Everything checks out, now to just do it 3791fcf3ce44SJohn Forte */ 3792fcf3ce44SJohn Forte if (offline) { 3793fcf3ce44SJohn Forte if (emlxs_offline(hba) != FC_SUCCESS) { 3794fcf3ce44SJohn Forte return (EMLXS_OFFLINE_FAILED); 3795fcf3ce44SJohn Forte } 3796291a2b48SSukumar Swaminathan 3797*82527734SSukumar Swaminathan if (EMLXS_SLI_HBA_RESET(hba, 1, 1, 0) != FC_SUCCESS) { 3798fcf3ce44SJohn Forte return (EMLXS_OFFLINE_FAILED); 3799fcf3ce44SJohn Forte } 3800fcf3ce44SJohn Forte } 3801291a2b48SSukumar Swaminathan 3802fcf3ce44SJohn Forte if (AwcBuffer) { 3803fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 3804291a2b48SSukumar Swaminathan "AWC file: KERN: old=%s new=%s ", vpd->postKernName, 3805291a2b48SSukumar Swaminathan fw_image->awc.label); 3806fcf3ce44SJohn Forte 3807291a2b48SSukumar Swaminathan rval = emlxs_proc_abs_2mb(hba, 3808291a2b48SSukumar Swaminathan AwcAifHdr, AwcBuffer, FILE_TYPE_AWC, BWCflag, extType); 3809fcf3ce44SJohn Forte 3810fcf3ce44SJohn Forte if (rval) { 3811fcf3ce44SJohn Forte goto SLI_DOWNLOAD_2MB_EXIT; 3812fcf3ce44SJohn Forte } 3813fcf3ce44SJohn Forte } 3814291a2b48SSukumar Swaminathan 3815fcf3ce44SJohn Forte if (DwcBuffer) { 3816fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 3817fcf3ce44SJohn Forte "DWC file: TEST: new=%s ", 3818fcf3ce44SJohn Forte fw_image->prog[TEST_PROGRAM].label); 3819fcf3ce44SJohn Forte 3820fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 3821291a2b48SSukumar Swaminathan "DWC file: STUB: old=%s new=%s ", vpd->opFwName, 3822291a2b48SSukumar Swaminathan fw_image->prog[FUNC_FIRMWARE].label); 3823fcf3ce44SJohn Forte 3824fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 3825291a2b48SSukumar Swaminathan "DWC file: SLI1: old=%s new=%s ", vpd->sli1FwName, 3826291a2b48SSukumar Swaminathan fw_image->prog[SLI1_OVERLAY].label); 3827fcf3ce44SJohn Forte 3828fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 3829291a2b48SSukumar Swaminathan "DWC file: SLI2: old=%s new=%s ", vpd->sli2FwName, 3830291a2b48SSukumar Swaminathan fw_image->prog[SLI2_OVERLAY].label); 3831fcf3ce44SJohn Forte 3832fcf3ce44SJohn Forte if (vpd->sli3FwRev || fw_image->prog[SLI3_OVERLAY].version) { 3833fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 3834fcf3ce44SJohn Forte "DWC file: SLI3: old=%s new=%s ", 3835fcf3ce44SJohn Forte vpd->sli3FwName, 3836fcf3ce44SJohn Forte fw_image->prog[SLI3_OVERLAY].label); 3837fcf3ce44SJohn Forte } 3838291a2b48SSukumar Swaminathan 3839fcf3ce44SJohn Forte if (vpd->sli4FwRev || fw_image->prog[SLI4_OVERLAY].version) { 3840fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 3841fcf3ce44SJohn Forte "DWC file: SLI4: old=%s new=%s ", 3842fcf3ce44SJohn Forte vpd->sli4FwName, 3843fcf3ce44SJohn Forte fw_image->prog[SLI4_OVERLAY].label); 3844fcf3ce44SJohn Forte } 3845291a2b48SSukumar Swaminathan 3846291a2b48SSukumar Swaminathan rval = emlxs_proc_abs_2mb(hba, 3847291a2b48SSukumar Swaminathan DwcAifHdr, DwcBuffer, FILE_TYPE_DWC, BWCflag, extType); 3848fcf3ce44SJohn Forte 3849fcf3ce44SJohn Forte if (rval) { 3850fcf3ce44SJohn Forte goto SLI_DOWNLOAD_2MB_EXIT; 3851fcf3ce44SJohn Forte } 3852fcf3ce44SJohn Forte } 3853291a2b48SSukumar Swaminathan 3854fcf3ce44SJohn Forte if (BwcBuffer) { 3855fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 3856291a2b48SSukumar Swaminathan "BWC file: BOOT: old=%s new=%s ", vpd->fcode_version, 3857291a2b48SSukumar Swaminathan fw_image->bwc.label); 3858fcf3ce44SJohn Forte 3859291a2b48SSukumar Swaminathan rval = emlxs_proc_abs_2mb(hba, 3860291a2b48SSukumar Swaminathan BwcAifHdr, BwcBuffer, FILE_TYPE_BWC, BWCflag, extType); 3861fcf3ce44SJohn Forte } 3862291a2b48SSukumar Swaminathan 3863fcf3ce44SJohn Forte SLI_DOWNLOAD_2MB_EXIT: 3864fcf3ce44SJohn Forte 3865fcf3ce44SJohn Forte if (offline) { 3866fcf3ce44SJohn Forte (void) emlxs_online(hba); 3867fcf3ce44SJohn Forte } 3868291a2b48SSukumar Swaminathan 3869fcf3ce44SJohn Forte return (rval); 3870fcf3ce44SJohn Forte 3871*82527734SSukumar Swaminathan } /* emlxs_start_abs_download_2mb() */ 3872fcf3ce44SJohn Forte 3873fcf3ce44SJohn Forte 3874fcf3ce44SJohn Forte /* 3875fcf3ce44SJohn Forte * 3876fcf3ce44SJohn Forte * FUNCTION NAME: emlxs_proc_abs_2mb 3877fcf3ce44SJohn Forte * 3878fcf3ce44SJohn Forte * DESCRIPTION: Given one of the 3 file types(awc/bwc/dwc), it will reset 3879fcf3ce44SJohn Forte * the port and download the file with sliIssueMbCommand() 3880fcf3ce44SJohn Forte * 3881fcf3ce44SJohn Forte * 3882fcf3ce44SJohn Forte * PARAMETERS: 3883fcf3ce44SJohn Forte * 3884fcf3ce44SJohn Forte * 3885fcf3ce44SJohn Forte * RETURNS: 3886fcf3ce44SJohn Forte * 3887fcf3ce44SJohn Forte */ 3888fcf3ce44SJohn Forte static uint32_t 3889291a2b48SSukumar Swaminathan emlxs_proc_abs_2mb(emlxs_hba_t *hba, 3890291a2b48SSukumar Swaminathan PAIF_HDR AifHdr, 3891291a2b48SSukumar Swaminathan caddr_t EntireBuffer, 3892fcf3ce44SJohn Forte uint32_t FileType, uint32_t BWCflag, uint32_t extType) 3893fcf3ce44SJohn Forte { 3894fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3895fcf3ce44SJohn Forte caddr_t Buffer = NULL; 3896fcf3ce44SJohn Forte caddr_t DataBuffer = NULL; 3897fcf3ce44SJohn Forte uint32_t *Src; 3898fcf3ce44SJohn Forte uint32_t *Dst; 3899fcf3ce44SJohn Forte MAILBOXQ *mbox; 3900fcf3ce44SJohn Forte MAILBOX *mb; 3901fcf3ce44SJohn Forte uint32_t DlByteCount = AifHdr->RoSize + AifHdr->RwSize; 3902fcf3ce44SJohn Forte uint32_t rval = 0; 3903fcf3ce44SJohn Forte uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT; 3904fcf3ce44SJohn Forte uint32_t DlToAddr = AifHdr->ImageBase; 3905fcf3ce44SJohn Forte uint32_t DlCount; 3906fcf3ce44SJohn Forte WAKE_UP_PARMS AbsWakeUpParms; 3907fcf3ce44SJohn Forte uint32_t i; 3908fcf3ce44SJohn Forte uint32_t NextAddr; 3909fcf3ce44SJohn Forte uint32_t EraseByteCount; 3910fcf3ce44SJohn Forte uint32_t AreaId; 3911fcf3ce44SJohn Forte uint32_t RspProgress = 0; 3912fcf3ce44SJohn Forte uint32_t numBootImage = 0; 3913fcf3ce44SJohn Forte uint32_t ParamsChg = 0; 3914fcf3ce44SJohn Forte uint32_t BufferSize; 3915fcf3ce44SJohn Forte 3916291a2b48SSukumar Swaminathan if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT, 3917291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 3918fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3919fcf3ce44SJohn Forte "%x: Unable to allocate data buffer.", FileType); 3920fcf3ce44SJohn Forte 3921fcf3ce44SJohn Forte return (EMLXS_IMAGE_FAILED); 3922fcf3ce44SJohn Forte } 3923291a2b48SSukumar Swaminathan 3924fcf3ce44SJohn Forte bzero(DataBuffer, sizeof (DL_SLIM_SEG_BYTE_COUNT)); 3925fcf3ce44SJohn Forte 3926291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 3927291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 3928fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3929fcf3ce44SJohn Forte "%x: Unable to allocate mailbox buffer.", FileType); 3930fcf3ce44SJohn Forte 3931fcf3ce44SJohn Forte kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 3932fcf3ce44SJohn Forte 3933fcf3ce44SJohn Forte return (EMLXS_IMAGE_FAILED); 3934fcf3ce44SJohn Forte } 3935291a2b48SSukumar Swaminathan 3936fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 3937fcf3ce44SJohn Forte 3938fcf3ce44SJohn Forte BufferSize = DlByteCount + sizeof (AIF_HDR) + sizeof (uint32_t); 3939fcf3ce44SJohn Forte Buffer = EntireBuffer + sizeof (AIF_HDR); 3940fcf3ce44SJohn Forte 3941fcf3ce44SJohn Forte switch (FileType) { 3942fcf3ce44SJohn Forte case FILE_TYPE_AWC: 3943fcf3ce44SJohn Forte break; 3944fcf3ce44SJohn Forte 3945fcf3ce44SJohn Forte case FILE_TYPE_BWC: 3946291a2b48SSukumar Swaminathan ParamsChg = emlxs_build_parms_2mb_bwc(hba, 3947291a2b48SSukumar Swaminathan AifHdr, extType, &AbsWakeUpParms); 3948fcf3ce44SJohn Forte 3949fcf3ce44SJohn Forte if (ParamsChg == FALSE) { 3950fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3951fcf3ce44SJohn Forte "BWC build parms failed."); 3952fcf3ce44SJohn Forte 3953fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 3954fcf3ce44SJohn Forte 3955fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 3956fcf3ce44SJohn Forte } 3957fcf3ce44SJohn Forte break; 3958fcf3ce44SJohn Forte 3959fcf3ce44SJohn Forte case FILE_TYPE_DWC: 3960291a2b48SSukumar Swaminathan ParamsChg = emlxs_build_parms_2mb_dwc(hba, 3961291a2b48SSukumar Swaminathan Buffer, 3962291a2b48SSukumar Swaminathan BufferSize, 3963291a2b48SSukumar Swaminathan AifHdr, &AbsWakeUpParms, BWCflag, extType, &numBootImage); 3964fcf3ce44SJohn Forte 3965fcf3ce44SJohn Forte if (ParamsChg == FALSE) { 3966fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3967fcf3ce44SJohn Forte "DWC build parms failed."); 3968fcf3ce44SJohn Forte 3969fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 3970fcf3ce44SJohn Forte 3971fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 3972fcf3ce44SJohn Forte } 3973fcf3ce44SJohn Forte break; 3974fcf3ce44SJohn Forte 3975fcf3ce44SJohn Forte default: 3976fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 3977fcf3ce44SJohn Forte "Invalid file type: %x", FileType); 3978fcf3ce44SJohn Forte 3979fcf3ce44SJohn Forte rval = EMLXS_IMAGE_BAD; 3980fcf3ce44SJohn Forte 3981fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 3982fcf3ce44SJohn Forte 3983fcf3ce44SJohn Forte } 3984fcf3ce44SJohn Forte 3985fcf3ce44SJohn Forte EraseByteCount = AifHdr->Area_Size; 3986fcf3ce44SJohn Forte AreaId = AifHdr->Area_ID; 3987fcf3ce44SJohn Forte 3988*82527734SSukumar Swaminathan emlxs_format_load_area_cmd(mbox, 3989291a2b48SSukumar Swaminathan DlToAddr, 3990291a2b48SSukumar Swaminathan EraseByteCount, 3991291a2b48SSukumar Swaminathan ERASE_FLASH, 3992fcf3ce44SJohn Forte 0, DL_FROM_SLIM_OFFSET, AreaId, MBX_LOAD_AREA, CMD_START_ERASE); 3993fcf3ce44SJohn Forte 3994*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) { 3995fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3996fcf3ce44SJohn Forte "%x: Could not erase 2MB Flash: Mailbox cmd=%x status=%x", 3997fcf3ce44SJohn Forte FileType, mb->mbxCommand, mb->mbxStatus); 3998fcf3ce44SJohn Forte 3999fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 4000fcf3ce44SJohn Forte 4001fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 4002fcf3ce44SJohn Forte } 4003291a2b48SSukumar Swaminathan 4004fcf3ce44SJohn Forte while (mb->un.varLdArea.progress != RSP_ERASE_COMPLETE) { 4005fcf3ce44SJohn Forte NextAddr = mb->un.varLdArea.dl_to_adr; 4006fcf3ce44SJohn Forte 4007*82527734SSukumar Swaminathan emlxs_format_load_area_cmd(mbox, 4008291a2b48SSukumar Swaminathan NextAddr, 4009291a2b48SSukumar Swaminathan EraseByteCount, 4010291a2b48SSukumar Swaminathan ERASE_FLASH, 4011291a2b48SSukumar Swaminathan 0, 4012291a2b48SSukumar Swaminathan DL_FROM_SLIM_OFFSET, 4013291a2b48SSukumar Swaminathan AreaId, MBX_LOAD_AREA, CMD_CONTINUE_ERASE); 4014fcf3ce44SJohn Forte 4015*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 4016291a2b48SSukumar Swaminathan MBX_SUCCESS) { 4017fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4018291a2b48SSukumar Swaminathan "%x: Could not erase 2MB Flash2: Mailbox cmd=%x " 4019291a2b48SSukumar Swaminathan "status=%x", FileType, mb->mbxCommand, 4020291a2b48SSukumar Swaminathan mb->mbxStatus); 4021fcf3ce44SJohn Forte 4022fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 4023fcf3ce44SJohn Forte 4024fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 4025fcf3ce44SJohn Forte } 4026fcf3ce44SJohn Forte } 4027fcf3ce44SJohn Forte 4028fcf3ce44SJohn Forte while (DlByteCount) { 4029fcf3ce44SJohn Forte if (DlByteCount >= SegSize) 4030fcf3ce44SJohn Forte DlCount = SegSize; 4031fcf3ce44SJohn Forte else 4032fcf3ce44SJohn Forte DlCount = DlByteCount; 4033fcf3ce44SJohn Forte 4034fcf3ce44SJohn Forte DlByteCount -= DlCount; 4035fcf3ce44SJohn Forte 4036fcf3ce44SJohn Forte Dst = (uint32_t *)DataBuffer; 4037fcf3ce44SJohn Forte Src = (uint32_t *)Buffer; 4038fcf3ce44SJohn Forte 4039fcf3ce44SJohn Forte for (i = 0; i < (DlCount / 4); i++) { 4040fcf3ce44SJohn Forte *Dst = *Src; 4041fcf3ce44SJohn Forte Dst++; 4042fcf3ce44SJohn Forte Src++; 4043fcf3ce44SJohn Forte } 4044fcf3ce44SJohn Forte 4045fcf3ce44SJohn Forte WRITE_SLIM_COPY(hba, (uint32_t *)DataBuffer, 4046*82527734SSukumar Swaminathan (volatile uint32_t *)((volatile char *) 4047*82527734SSukumar Swaminathan hba->sli.sli3.slim_addr + sizeof (MAILBOX)), 4048*82527734SSukumar Swaminathan (DlCount / sizeof (uint32_t))); 4049fcf3ce44SJohn Forte 4050fcf3ce44SJohn Forte if ((RspProgress == RSP_DOWNLOAD_MORE) || (RspProgress == 0)) { 4051*82527734SSukumar Swaminathan emlxs_format_load_area_cmd(mbox, 4052291a2b48SSukumar Swaminathan DlToAddr, 4053291a2b48SSukumar Swaminathan DlCount, 4054291a2b48SSukumar Swaminathan PROGRAM_FLASH, 4055291a2b48SSukumar Swaminathan (DlByteCount) ? 0 : 1, 4056291a2b48SSukumar Swaminathan DL_FROM_SLIM_OFFSET, 4057291a2b48SSukumar Swaminathan AreaId, 4058291a2b48SSukumar Swaminathan MBX_LOAD_AREA, 4059fcf3ce44SJohn Forte (DlByteCount) ? CMD_DOWNLOAD : CMD_END_DOWNLOAD); 4060fcf3ce44SJohn Forte 4061*82527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != 4062fcf3ce44SJohn Forte MBX_SUCCESS) { 4063fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 4064fcf3ce44SJohn Forte &emlxs_download_failed_msg, 4065291a2b48SSukumar Swaminathan "%x: Could not program 2MB Flash: Mailbox " 4066291a2b48SSukumar Swaminathan "cmd=%x status=%x", FileType, 4067291a2b48SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 4068fcf3ce44SJohn Forte 4069fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 4070fcf3ce44SJohn Forte 4071fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 4072fcf3ce44SJohn Forte } 4073fcf3ce44SJohn Forte } 4074291a2b48SSukumar Swaminathan 4075fcf3ce44SJohn Forte RspProgress = mb->un.varLdArea.progress; 4076fcf3ce44SJohn Forte 4077fcf3ce44SJohn Forte Buffer += DlCount; 4078fcf3ce44SJohn Forte DlToAddr += DlCount; 4079fcf3ce44SJohn Forte } 4080fcf3ce44SJohn Forte 40814baa2c25SSukumar Swaminathan #ifdef FMA_SUPPORT 4082*82527734SSukumar Swaminathan if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle) 40834baa2c25SSukumar Swaminathan != DDI_FM_OK) { 40844baa2c25SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 40854baa2c25SSukumar Swaminathan &emlxs_invalid_access_handle_msg, NULL); 40864baa2c25SSukumar Swaminathan 40874baa2c25SSukumar Swaminathan rval = EMLXS_IMAGE_FAILED; 40884baa2c25SSukumar Swaminathan 40894baa2c25SSukumar Swaminathan goto EXIT_ABS_DOWNLOAD; 40904baa2c25SSukumar Swaminathan } 40914baa2c25SSukumar Swaminathan #endif /* FMA_SUPPORT */ 40924baa2c25SSukumar Swaminathan 4093fcf3ce44SJohn Forte if (RspProgress != RSP_DOWNLOAD_DONE) { 4094fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4095291a2b48SSukumar Swaminathan "%x: Failed download response received. %x", FileType, 4096291a2b48SSukumar Swaminathan RspProgress); 4097fcf3ce44SJohn Forte 4098fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 4099fcf3ce44SJohn Forte 4100fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 4101fcf3ce44SJohn Forte } 4102291a2b48SSukumar Swaminathan 4103fcf3ce44SJohn Forte if (ParamsChg) { 4104fcf3ce44SJohn Forte if (emlxs_update_wakeup_parms(hba, &AbsWakeUpParms, 4105fcf3ce44SJohn Forte &AbsWakeUpParms)) { 4106fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4107fcf3ce44SJohn Forte "%x: Unable to update parms.", FileType); 4108fcf3ce44SJohn Forte 4109fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 4110fcf3ce44SJohn Forte } 4111fcf3ce44SJohn Forte } 4112291a2b48SSukumar Swaminathan 4113fcf3ce44SJohn Forte EXIT_ABS_DOWNLOAD: 4114fcf3ce44SJohn Forte 4115fcf3ce44SJohn Forte if (DataBuffer) { 4116fcf3ce44SJohn Forte kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 4117fcf3ce44SJohn Forte } 4118291a2b48SSukumar Swaminathan 4119fcf3ce44SJohn Forte if (mbox) { 4120fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 4121fcf3ce44SJohn Forte } 4122291a2b48SSukumar Swaminathan 4123fcf3ce44SJohn Forte return (rval); 4124fcf3ce44SJohn Forte 4125*82527734SSukumar Swaminathan } /* emlxs_proc_abs_2mb() */ 4126fcf3ce44SJohn Forte 4127fcf3ce44SJohn Forte 4128fcf3ce44SJohn Forte static void 4129*82527734SSukumar Swaminathan emlxs_format_load_area_cmd(MAILBOXQ * mbq, 4130291a2b48SSukumar Swaminathan uint32_t Base, 4131291a2b48SSukumar Swaminathan uint32_t DlByteCount, 4132291a2b48SSukumar Swaminathan uint32_t Function, 4133291a2b48SSukumar Swaminathan uint32_t Complete, 4134291a2b48SSukumar Swaminathan uint32_t DataOffset, uint32_t AreaId, uint8_t MbxCmd, uint32_t StepCmd) 4135fcf3ce44SJohn Forte { 4136*82527734SSukumar Swaminathan MAILBOX *mb = (MAILBOX *)mbq; 4137*82527734SSukumar Swaminathan 4138fcf3ce44SJohn Forte bzero((void *)mb, MAILBOX_CMD_BSIZE); 4139fcf3ce44SJohn Forte 4140fcf3ce44SJohn Forte mb->mbxCommand = MbxCmd; 4141fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 4142fcf3ce44SJohn Forte mb->un.varLdArea.update_flash = 1; 4143fcf3ce44SJohn Forte mb->un.varLdArea.erase_or_prog = Function; 4144fcf3ce44SJohn Forte mb->un.varLdArea.dl_to_adr = Base; 4145fcf3ce44SJohn Forte mb->un.varLdArea.dl_len = DlByteCount; 4146fcf3ce44SJohn Forte mb->un.varLdArea.load_cmplt = Complete; 4147fcf3ce44SJohn Forte mb->un.varLdArea.method = DL_FROM_SLIM; 4148fcf3ce44SJohn Forte mb->un.varLdArea.area_id = AreaId; 4149fcf3ce44SJohn Forte mb->un.varLdArea.step = StepCmd; 4150fcf3ce44SJohn Forte mb->un.varLdArea.un.dl_from_slim_offset = DataOffset; 4151*82527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 4152fcf3ce44SJohn Forte 4153*82527734SSukumar Swaminathan } /* emlxs_format_load_area_cmd() */ 4154fcf3ce44SJohn Forte 4155fcf3ce44SJohn Forte 4156291a2b48SSukumar Swaminathan /* ARGSUSED */ 4157fcf3ce44SJohn Forte static uint32_t 4158291a2b48SSukumar Swaminathan emlxs_build_parms_2mb_bwc(emlxs_hba_t *hba, 4159291a2b48SSukumar Swaminathan PAIF_HDR AifHdr, uint32_t extType, PWAKE_UP_PARMS AbsWakeUpParms) 4160fcf3ce44SJohn Forte { 4161fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 4162fcf3ce44SJohn Forte uint32_t pId[2]; 4163fcf3ce44SJohn Forte uint32_t returnStat; 4164fcf3ce44SJohn Forte 4165fcf3ce44SJohn Forte /* Read wakeup paramters */ 4166fcf3ce44SJohn Forte if (emlxs_read_wakeup_parms(hba, AbsWakeUpParms, 0) == 4167fcf3ce44SJohn Forte CFG_DATA_NO_REGION) { 4168fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4169fcf3ce44SJohn Forte "Unable to get BWC parameters."); 4170fcf3ce44SJohn Forte return (FALSE); 4171fcf3ce44SJohn Forte } 4172291a2b48SSukumar Swaminathan 4173fcf3ce44SJohn Forte pId[0] = AifHdr->AVersion; 4174fcf3ce44SJohn Forte pId[1] = 0; 4175fcf3ce44SJohn Forte 4176fcf3ce44SJohn Forte if (extType == BWCext) { 4177fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_wd[0] = pId[0]; 4178fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_wd[1] = pId[1]; 4179fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 4180fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 4181291a2b48SSukumar Swaminathan } 4182291a2b48SSukumar Swaminathan 4183291a2b48SSukumar Swaminathan else if (extType == ALLext) { 4184fcf3ce44SJohn Forte if (!AbsWakeUpParms->u0.boot_bios_wd[0]) { 4185fcf3ce44SJohn Forte /* case of EROM inactive */ 4186fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 4187fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 4188fcf3ce44SJohn Forte } else { 4189fcf3ce44SJohn Forte /* case of EROM active */ 4190fcf3ce44SJohn Forte if (AbsWakeUpParms->u0.boot_bios_wd[0] == pId[0]) { 4191fcf3ce44SJohn Forte /* same ID */ 4192fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_wd[0] = pId[0]; 4193fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_wd[1] = pId[1]; 4194fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 4195fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 4196fcf3ce44SJohn Forte } else { 4197fcf3ce44SJohn Forte /* different ID */ 4198fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 4199fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 4200fcf3ce44SJohn Forte 4201291a2b48SSukumar Swaminathan returnStat = 4202291a2b48SSukumar Swaminathan emlxs_update_exp_rom(hba, AbsWakeUpParms); 4203fcf3ce44SJohn Forte 4204fcf3ce44SJohn Forte if (returnStat) { 4205fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_wd[0] = 4206fcf3ce44SJohn Forte pId[0]; 4207fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_wd[1] = 4208fcf3ce44SJohn Forte pId[1]; 4209fcf3ce44SJohn Forte } 4210fcf3ce44SJohn Forte } 4211fcf3ce44SJohn Forte } 4212fcf3ce44SJohn Forte } 4213291a2b48SSukumar Swaminathan 4214fcf3ce44SJohn Forte return (TRUE); 4215fcf3ce44SJohn Forte 4216*82527734SSukumar Swaminathan } /* emlxs_build_parms_2mb_bwc() */ 4217fcf3ce44SJohn Forte 4218fcf3ce44SJohn Forte 4219fcf3ce44SJohn Forte /* ARGSUSED */ 4220fcf3ce44SJohn Forte static uint32_t 4221291a2b48SSukumar Swaminathan emlxs_build_parms_2mb_dwc(emlxs_hba_t *hba, 4222291a2b48SSukumar Swaminathan caddr_t Buffer, 4223291a2b48SSukumar Swaminathan uint32_t BufferSize, 4224291a2b48SSukumar Swaminathan PAIF_HDR AifHeader, 4225291a2b48SSukumar Swaminathan PWAKE_UP_PARMS AbsWakeUpParms, 4226291a2b48SSukumar Swaminathan uint32_t BWCflag, uint32_t extType, uint32_t *numBootImage) 4227fcf3ce44SJohn Forte { 4228fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 4229fcf3ce44SJohn Forte uint32_t NextImage; 4230fcf3ce44SJohn Forte uint32_t i; 4231fcf3ce44SJohn Forte IMAGE_HDR ImageHdr; 4232fcf3ce44SJohn Forte uint32_t *ptr1; 4233fcf3ce44SJohn Forte uint32_t *ptr2; 4234fcf3ce44SJohn Forte PROG_ID BootId[MAX_BOOTID]; 4235fcf3ce44SJohn Forte uint32_t ChangeParams = FALSE; 4236fcf3ce44SJohn Forte WAKE_UP_PARMS WakeUpParms; 4237fcf3ce44SJohn Forte caddr_t Sptr; 4238fcf3ce44SJohn Forte caddr_t Dptr; 4239fcf3ce44SJohn Forte 4240fcf3ce44SJohn Forte bzero(&BootId, (sizeof (PROG_ID)) * MAX_BOOTID); 4241fcf3ce44SJohn Forte 4242fcf3ce44SJohn Forte /* Read wakeup paramters */ 4243fcf3ce44SJohn Forte if (emlxs_read_wakeup_parms(hba, AbsWakeUpParms, 0) == 4244fcf3ce44SJohn Forte CFG_DATA_NO_REGION) { 4245fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4246fcf3ce44SJohn Forte "Unable to get DWC parameters."); 4247fcf3ce44SJohn Forte return (FALSE); 4248fcf3ce44SJohn Forte } 4249291a2b48SSukumar Swaminathan 4250fcf3ce44SJohn Forte bcopy((caddr_t)AbsWakeUpParms, (caddr_t)&WakeUpParms, 4251fcf3ce44SJohn Forte sizeof (WAKE_UP_PARMS)); 4252fcf3ce44SJohn Forte 4253fcf3ce44SJohn Forte if (((BWCflag == ALL_WITHOUT_BWC) || (extType == DWCext)) && 4254fcf3ce44SJohn Forte (WakeUpParms.u0.boot_bios_wd[0])) { 4255fcf3ce44SJohn Forte *numBootImage = 0; 4256fcf3ce44SJohn Forte } 4257291a2b48SSukumar Swaminathan 4258fcf3ce44SJohn Forte /* incoming buffer is without aif header */ 4259fcf3ce44SJohn Forte NextImage = 0x84 - sizeof (AIF_HDR); 4260fcf3ce44SJohn Forte BufferSize -= (sizeof (AIF_HDR) + sizeof (uint32_t)); 4261fcf3ce44SJohn Forte 4262fcf3ce44SJohn Forte while (BufferSize > NextImage) { 4263fcf3ce44SJohn Forte Sptr = &Buffer[NextImage]; 4264fcf3ce44SJohn Forte Dptr = (caddr_t)&ImageHdr; 4265fcf3ce44SJohn Forte for (i = 0; i < sizeof (IMAGE_HDR); i++) { 4266fcf3ce44SJohn Forte Dptr[i] = Sptr[i]; 4267fcf3ce44SJohn Forte } 4268fcf3ce44SJohn Forte 4269fcf3ce44SJohn Forte if (ImageHdr.BlockSize == 0xffffffff) { 4270fcf3ce44SJohn Forte break; 4271fcf3ce44SJohn Forte } 4272291a2b48SSukumar Swaminathan 4273fcf3ce44SJohn Forte switch (ImageHdr.Id.Type) { 4274fcf3ce44SJohn Forte case TEST_PROGRAM: 4275fcf3ce44SJohn Forte break; 4276fcf3ce44SJohn Forte 4277fcf3ce44SJohn Forte case FUNC_FIRMWARE: 4278fcf3ce44SJohn Forte AbsWakeUpParms->prog_id = ImageHdr.Id; 4279fcf3ce44SJohn Forte ChangeParams = TRUE; 4280fcf3ce44SJohn Forte break; 4281fcf3ce44SJohn Forte 4282fcf3ce44SJohn Forte case BOOT_BIOS: 4283fcf3ce44SJohn Forte if (!WakeUpParms.u0.boot_bios_wd[0]) { 4284fcf3ce44SJohn Forte if (extType == DWCext) { 4285fcf3ce44SJohn Forte break; 4286fcf3ce44SJohn Forte } else if (BWCflag == ALL_WITHOUT_BWC) { 4287291a2b48SSukumar Swaminathan /* for possible future changes */ 4288fcf3ce44SJohn Forte break; 4289fcf3ce44SJohn Forte } 4290fcf3ce44SJohn Forte } 4291fcf3ce44SJohn Forte ChangeParams = TRUE; 4292fcf3ce44SJohn Forte 4293fcf3ce44SJohn Forte if (*numBootImage < MAX_BOOTID) { 4294fcf3ce44SJohn Forte BootId[*numBootImage] = ImageHdr.Id; 4295fcf3ce44SJohn Forte (*numBootImage)++; 4296fcf3ce44SJohn Forte } 4297fcf3ce44SJohn Forte break; 4298fcf3ce44SJohn Forte 4299fcf3ce44SJohn Forte case SLI1_OVERLAY: 4300fcf3ce44SJohn Forte AbsWakeUpParms->sli1_prog_id = ImageHdr.Id; 4301fcf3ce44SJohn Forte ChangeParams = TRUE; 4302fcf3ce44SJohn Forte break; 4303fcf3ce44SJohn Forte 4304fcf3ce44SJohn Forte case SLI2_OVERLAY: 4305fcf3ce44SJohn Forte AbsWakeUpParms->sli2_prog_id = ImageHdr.Id; 4306fcf3ce44SJohn Forte ChangeParams = TRUE; 4307fcf3ce44SJohn Forte break; 4308fcf3ce44SJohn Forte 4309fcf3ce44SJohn Forte case SLI3_OVERLAY: 4310fcf3ce44SJohn Forte AbsWakeUpParms->sli3_prog_id = ImageHdr.Id; 4311fcf3ce44SJohn Forte ChangeParams = TRUE; 4312fcf3ce44SJohn Forte break; 4313fcf3ce44SJohn Forte 4314fcf3ce44SJohn Forte case SLI4_OVERLAY: 4315fcf3ce44SJohn Forte AbsWakeUpParms->sli4_prog_id = ImageHdr.Id; 4316fcf3ce44SJohn Forte ChangeParams = TRUE; 4317fcf3ce44SJohn Forte break; 4318fcf3ce44SJohn Forte } 4319fcf3ce44SJohn Forte 4320fcf3ce44SJohn Forte NextImage += ImageHdr.BlockSize; 4321fcf3ce44SJohn Forte } 4322fcf3ce44SJohn Forte 4323fcf3ce44SJohn Forte if ((ChangeParams) && ((BWCflag == ALL_WITHOUT_BWC) || 4324fcf3ce44SJohn Forte (extType == DWCext))) { 4325fcf3ce44SJohn Forte 4326fcf3ce44SJohn Forte if (*numBootImage > 1) { 4327fcf3ce44SJohn Forte for (i = 0; i < *numBootImage; i++) { 4328291a2b48SSukumar Swaminathan ptr1 = 4329291a2b48SSukumar Swaminathan (uint32_t *)&WakeUpParms.u0. 4330291a2b48SSukumar Swaminathan boot_bios_id; 4331fcf3ce44SJohn Forte ptr2 = (uint32_t *)&BootId[i]; 4332fcf3ce44SJohn Forte 4333fcf3ce44SJohn Forte if (ptr1[0] == ptr2[0]) { 4334fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_id = 4335fcf3ce44SJohn Forte BootId[i]; 4336fcf3ce44SJohn Forte (void) emlxs_update_exp_rom(hba, 4337fcf3ce44SJohn Forte AbsWakeUpParms); 4338fcf3ce44SJohn Forte break; 4339fcf3ce44SJohn Forte } 4340fcf3ce44SJohn Forte } 4341fcf3ce44SJohn Forte } else { 4342fcf3ce44SJohn Forte if (*numBootImage == 1) { 4343fcf3ce44SJohn Forte ptr2 = (uint32_t *)&BootId[0]; 4344fcf3ce44SJohn Forte 4345fcf3ce44SJohn Forte if (WakeUpParms.u0.boot_bios_wd[0] == ptr2[0]) { 4346fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_id = 4347fcf3ce44SJohn Forte BootId[0]; 4348fcf3ce44SJohn Forte (void) emlxs_update_exp_rom(hba, 4349fcf3ce44SJohn Forte AbsWakeUpParms); 4350fcf3ce44SJohn Forte } 4351fcf3ce44SJohn Forte } 4352fcf3ce44SJohn Forte } 4353fcf3ce44SJohn Forte } 4354291a2b48SSukumar Swaminathan 4355fcf3ce44SJohn Forte return (ChangeParams); 4356fcf3ce44SJohn Forte 4357fcf3ce44SJohn Forte 4358*82527734SSukumar Swaminathan } /* emlxs_build_parms_2mb_dwc() */ 4359fcf3ce44SJohn Forte 4360fcf3ce44SJohn Forte 4361fcf3ce44SJohn Forte extern uint32_t 4362fcf3ce44SJohn Forte emlxs_get_max_sram(emlxs_hba_t *hba, uint32_t *MaxRbusSize, 4363fcf3ce44SJohn Forte uint32_t *MaxIbusSize) 4364fcf3ce44SJohn Forte { 4365fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 4366fcf3ce44SJohn Forte MAILBOXQ *mbox; 4367fcf3ce44SJohn Forte MAILBOX *mb; 4368fcf3ce44SJohn Forte uint32_t *Uptr; 4369fcf3ce44SJohn Forte uint32_t rval = 0; 4370fcf3ce44SJohn Forte 4371291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 4372291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 4373fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4374fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 4375fcf3ce44SJohn Forte 4376fcf3ce44SJohn Forte return (1); 4377fcf3ce44SJohn Forte } 4378291a2b48SSukumar Swaminathan 4379fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 4380fcf3ce44SJohn Forte 4381*82527734SSukumar Swaminathan emlxs_format_dump(hba, mbox, DMP_MEM_REG, 0, 2, MAX_RBUS_SRAM_SIZE_ADR); 4382fcf3ce44SJohn Forte 4383*82527734SSukumar Swaminathan if ((rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0)) != 4384291a2b48SSukumar Swaminathan MBX_SUCCESS) { 4385fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 4386fcf3ce44SJohn Forte "Unable to get SRAM size: Mailbox cmd=%x status=%x", 4387fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 4388fcf3ce44SJohn Forte 4389fcf3ce44SJohn Forte rval = 1; 4390fcf3ce44SJohn Forte 4391fcf3ce44SJohn Forte goto Exit_Function; 4392fcf3ce44SJohn Forte } 4393291a2b48SSukumar Swaminathan 4394*82527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 4395*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle, 0, 4396*82527734SSukumar Swaminathan hba->sli.sli4.dump_region.size, DDI_DMA_SYNC_FORKERNEL); 4397*82527734SSukumar Swaminathan Uptr = (uint32_t *)hba->sli.sli4.dump_region.virt; 4398*82527734SSukumar Swaminathan } else { 4399*82527734SSukumar Swaminathan Uptr = (uint32_t *)&mb->un.varDmp.resp_offset; 4400*82527734SSukumar Swaminathan } 4401fcf3ce44SJohn Forte 4402fcf3ce44SJohn Forte *MaxRbusSize = Uptr[0]; 4403fcf3ce44SJohn Forte *MaxIbusSize = Uptr[1]; 4404fcf3ce44SJohn Forte 4405fcf3ce44SJohn Forte Exit_Function: 4406fcf3ce44SJohn Forte 4407fcf3ce44SJohn Forte if (mbox) { 4408fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 4409fcf3ce44SJohn Forte } 4410291a2b48SSukumar Swaminathan 4411fcf3ce44SJohn Forte return (rval); 4412fcf3ce44SJohn Forte 4413*82527734SSukumar Swaminathan } /* emlxs_get_max_sram() */ 4414fcf3ce44SJohn Forte 4415fcf3ce44SJohn Forte 4416fcf3ce44SJohn Forte static uint32_t 4417fcf3ce44SJohn Forte emlxs_kern_check(emlxs_hba_t *hba, uint32_t version) 4418fcf3ce44SJohn Forte { 4419fcf3ce44SJohn Forte uint8_t *ptr; 4420fcf3ce44SJohn Forte uint8_t ver; 4421fcf3ce44SJohn Forte 4422fcf3ce44SJohn Forte ver = version & 0xff; 4423fcf3ce44SJohn Forte ptr = hba->model_info.pt_FF; 4424fcf3ce44SJohn Forte 4425fcf3ce44SJohn Forte while (*ptr) { 4426fcf3ce44SJohn Forte if (*ptr++ == ver) { 4427fcf3ce44SJohn Forte return (1); 4428fcf3ce44SJohn Forte } 4429fcf3ce44SJohn Forte } 4430fcf3ce44SJohn Forte 4431fcf3ce44SJohn Forte return (0); 4432fcf3ce44SJohn Forte 4433*82527734SSukumar Swaminathan } /* emlxs_kern_check() */ 4434fcf3ce44SJohn Forte 4435fcf3ce44SJohn Forte static uint32_t 4436fcf3ce44SJohn Forte emlxs_stub_check(emlxs_hba_t *hba, uint32_t version) 4437fcf3ce44SJohn Forte { 4438fcf3ce44SJohn Forte uint8_t *ptr; 4439fcf3ce44SJohn Forte uint8_t ver; 4440fcf3ce44SJohn Forte 4441fcf3ce44SJohn Forte ver = version & 0xff; 4442fcf3ce44SJohn Forte ptr = hba->model_info.pt_2; 4443fcf3ce44SJohn Forte 4444fcf3ce44SJohn Forte while (*ptr) { 4445fcf3ce44SJohn Forte if (*ptr++ == ver) { 4446fcf3ce44SJohn Forte return (1); 4447fcf3ce44SJohn Forte } 4448fcf3ce44SJohn Forte } 4449fcf3ce44SJohn Forte 4450fcf3ce44SJohn Forte return (0); 4451fcf3ce44SJohn Forte 4452*82527734SSukumar Swaminathan } /* emlxs_stub_check() */ 4453fcf3ce44SJohn Forte 4454fcf3ce44SJohn Forte static uint32_t 4455fcf3ce44SJohn Forte emlxs_bios_check(emlxs_hba_t *hba, uint32_t version) 4456fcf3ce44SJohn Forte { 4457fcf3ce44SJohn Forte uint8_t *ptr; 4458fcf3ce44SJohn Forte uint8_t ver; 4459fcf3ce44SJohn Forte 4460fcf3ce44SJohn Forte ver = version & 0xff; 4461fcf3ce44SJohn Forte ptr = hba->model_info.pt_3; 4462fcf3ce44SJohn Forte 4463fcf3ce44SJohn Forte while (*ptr) { 4464fcf3ce44SJohn Forte if (*ptr++ == ver) { 4465fcf3ce44SJohn Forte return (1); 4466fcf3ce44SJohn Forte } 4467fcf3ce44SJohn Forte } 4468fcf3ce44SJohn Forte 4469fcf3ce44SJohn Forte return (0); 4470fcf3ce44SJohn Forte 4471*82527734SSukumar Swaminathan } /* emlxs_bios_check() */ 4472fcf3ce44SJohn Forte 4473fcf3ce44SJohn Forte static uint32_t 4474fcf3ce44SJohn Forte emlxs_sli1_check(emlxs_hba_t *hba, uint32_t version) 4475fcf3ce44SJohn Forte { 4476fcf3ce44SJohn Forte uint8_t *ptr; 4477fcf3ce44SJohn Forte uint8_t ver; 4478fcf3ce44SJohn Forte 4479fcf3ce44SJohn Forte ver = version & 0xff; 4480fcf3ce44SJohn Forte ptr = hba->model_info.pt_6; 4481fcf3ce44SJohn Forte 4482fcf3ce44SJohn Forte while (*ptr) { 4483fcf3ce44SJohn Forte if (*ptr++ == ver) { 4484fcf3ce44SJohn Forte return (1); 4485fcf3ce44SJohn Forte } 4486fcf3ce44SJohn Forte } 4487fcf3ce44SJohn Forte 4488fcf3ce44SJohn Forte return (0); 4489fcf3ce44SJohn Forte 4490*82527734SSukumar Swaminathan } /* emlxs_sli1_check() */ 4491fcf3ce44SJohn Forte 4492fcf3ce44SJohn Forte static uint32_t 4493fcf3ce44SJohn Forte emlxs_sli2_check(emlxs_hba_t *hba, uint32_t version) 4494fcf3ce44SJohn Forte { 4495fcf3ce44SJohn Forte uint8_t *ptr; 4496fcf3ce44SJohn Forte uint8_t ver; 4497fcf3ce44SJohn Forte 4498fcf3ce44SJohn Forte ver = version & 0xff; 4499fcf3ce44SJohn Forte ptr = hba->model_info.pt_7; 4500fcf3ce44SJohn Forte 4501fcf3ce44SJohn Forte while (*ptr) { 4502fcf3ce44SJohn Forte if (*ptr++ == ver) { 4503fcf3ce44SJohn Forte return (1); 4504fcf3ce44SJohn Forte } 4505fcf3ce44SJohn Forte } 4506fcf3ce44SJohn Forte 4507fcf3ce44SJohn Forte return (0); 4508fcf3ce44SJohn Forte 4509*82527734SSukumar Swaminathan } /* emlxs_sli2_check() */ 4510fcf3ce44SJohn Forte 4511fcf3ce44SJohn Forte static uint32_t 4512fcf3ce44SJohn Forte emlxs_sli3_check(emlxs_hba_t *hba, uint32_t version) 4513fcf3ce44SJohn Forte { 4514fcf3ce44SJohn Forte uint8_t *ptr; 4515fcf3ce44SJohn Forte uint8_t ver; 4516fcf3ce44SJohn Forte 4517fcf3ce44SJohn Forte ver = version & 0xff; 4518fcf3ce44SJohn Forte ptr = hba->model_info.pt_B; 4519fcf3ce44SJohn Forte 4520fcf3ce44SJohn Forte while (*ptr) { 4521fcf3ce44SJohn Forte if (*ptr++ == ver) { 4522fcf3ce44SJohn Forte return (1); 4523fcf3ce44SJohn Forte } 4524fcf3ce44SJohn Forte } 4525fcf3ce44SJohn Forte 4526fcf3ce44SJohn Forte return (0); 4527fcf3ce44SJohn Forte 4528*82527734SSukumar Swaminathan } /* emlxs_sli3_check() */ 4529fcf3ce44SJohn Forte 4530fcf3ce44SJohn Forte 4531fcf3ce44SJohn Forte static uint32_t 4532fcf3ce44SJohn Forte emlxs_sli4_check(emlxs_hba_t *hba, uint32_t version) 4533fcf3ce44SJohn Forte { 4534fcf3ce44SJohn Forte uint8_t *ptr; 4535fcf3ce44SJohn Forte uint8_t ver; 4536fcf3ce44SJohn Forte 4537fcf3ce44SJohn Forte ver = version & 0xff; 4538fcf3ce44SJohn Forte ptr = hba->model_info.pt_E; 4539fcf3ce44SJohn Forte 4540fcf3ce44SJohn Forte while (*ptr) { 4541fcf3ce44SJohn Forte if (*ptr++ == ver) { 4542fcf3ce44SJohn Forte return (1); 4543fcf3ce44SJohn Forte } 4544fcf3ce44SJohn Forte } 4545fcf3ce44SJohn Forte 4546fcf3ce44SJohn Forte return (0); 4547fcf3ce44SJohn Forte 4548*82527734SSukumar Swaminathan } /* emlxs_sli4_check() */ 4549fcf3ce44SJohn Forte 4550fcf3ce44SJohn Forte 4551fcf3ce44SJohn Forte static uint32_t 4552fcf3ce44SJohn Forte emlxs_sbus_fcode_check(emlxs_hba_t *hba, uint32_t version) 4553fcf3ce44SJohn Forte { 4554fcf3ce44SJohn Forte uint8_t *ptr; 4555fcf3ce44SJohn Forte uint8_t ver; 4556fcf3ce44SJohn Forte 4557fcf3ce44SJohn Forte ver = version & 0xff; 4558fcf3ce44SJohn Forte ptr = hba->model_info.pt_A; 4559fcf3ce44SJohn Forte 4560fcf3ce44SJohn Forte while (*ptr) { 4561fcf3ce44SJohn Forte if (*ptr++ == ver) { 4562fcf3ce44SJohn Forte return (1); 4563fcf3ce44SJohn Forte } 4564fcf3ce44SJohn Forte } 4565fcf3ce44SJohn Forte 4566fcf3ce44SJohn Forte return (0); 4567fcf3ce44SJohn Forte 4568*82527734SSukumar Swaminathan } /* emlxs_sbus_fcode_check() */ 4569fcf3ce44SJohn Forte 4570fcf3ce44SJohn Forte static uint32_t 4571fcf3ce44SJohn Forte emlxs_type_check(uint32_t type) 4572fcf3ce44SJohn Forte { 4573fcf3ce44SJohn Forte if (type == 0xff) { 4574fcf3ce44SJohn Forte return (KERNEL_CODE); 4575fcf3ce44SJohn Forte } 4576291a2b48SSukumar Swaminathan 4577fcf3ce44SJohn Forte if (type >= MAX_PROG_TYPES) { 4578fcf3ce44SJohn Forte return (RESERVED_D); 4579fcf3ce44SJohn Forte } 4580291a2b48SSukumar Swaminathan 4581fcf3ce44SJohn Forte return (type); 4582fcf3ce44SJohn Forte 4583*82527734SSukumar Swaminathan } /* emlxs_type_check() */ 4584fcf3ce44SJohn Forte 4585fcf3ce44SJohn Forte 4586fcf3ce44SJohn Forte 4587291a2b48SSukumar Swaminathan extern int32_t 4588fcf3ce44SJohn Forte emlxs_boot_code_disable(emlxs_hba_t *hba) 4589fcf3ce44SJohn Forte { 4590fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 4591fcf3ce44SJohn Forte PROG_ID Id; 4592fcf3ce44SJohn Forte emlxs_vpd_t *vpd; 4593fcf3ce44SJohn Forte 4594fcf3ce44SJohn Forte vpd = &VPD; 4595fcf3ce44SJohn Forte 4596fcf3ce44SJohn Forte if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 0)) { 4597fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, 4598fcf3ce44SJohn Forte "emlxs_boot_code_disable: Unable to read wake up parms."); 4599fcf3ce44SJohn Forte 4600291a2b48SSukumar Swaminathan return (FC_FAILURE); 4601fcf3ce44SJohn Forte } 4602291a2b48SSukumar Swaminathan 4603fcf3ce44SJohn Forte /* Check if boot code is already disabled */ 4604fcf3ce44SJohn Forte if (hba->wakeup_parms.u0.boot_bios_wd[0] == 0) { 4605fcf3ce44SJohn Forte return (FC_SUCCESS); 4606fcf3ce44SJohn Forte } 4607291a2b48SSukumar Swaminathan 4608fcf3ce44SJohn Forte /* Make sure EROM entry has copy of boot bios entry */ 4609fcf3ce44SJohn Forte if (!(hba->model_info.chip & 4610fcf3ce44SJohn Forte (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP)) && 4611fcf3ce44SJohn Forte (hba->wakeup_parms.u0.boot_bios_wd[0] != 4612fcf3ce44SJohn Forte hba->wakeup_parms.u1.EROM_prog_wd[0]) && 4613fcf3ce44SJohn Forte (hba->wakeup_parms.u0.boot_bios_wd[1] != 4614fcf3ce44SJohn Forte hba->wakeup_parms.u1.EROM_prog_wd[1])) { 4615fcf3ce44SJohn Forte (void) emlxs_update_boot_wakeup_parms(hba, &hba->wakeup_parms, 4616fcf3ce44SJohn Forte &hba->wakeup_parms.u0.boot_bios_id, 1); 4617fcf3ce44SJohn Forte } 4618291a2b48SSukumar Swaminathan 4619fcf3ce44SJohn Forte /* Update the bios id with a zero id */ 4620fcf3ce44SJohn Forte /* Don't load the EROM this time */ 4621fcf3ce44SJohn Forte bzero(&Id, sizeof (PROG_ID)); 4622fcf3ce44SJohn Forte (void) emlxs_update_boot_wakeup_parms(hba, &hba->wakeup_parms, &Id, 0); 4623fcf3ce44SJohn Forte 4624fcf3ce44SJohn Forte /* Now read the parms again to verify */ 4625fcf3ce44SJohn Forte (void) emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1); 4626fcf3ce44SJohn Forte emlxs_decode_version(hba->wakeup_parms.u0.boot_bios_wd[0], 4627fcf3ce44SJohn Forte vpd->boot_version); 4628fcf3ce44SJohn Forte /* (void) strcpy(vpd->fcode_version, vpd->boot_version); */ 4629fcf3ce44SJohn Forte 4630fcf3ce44SJohn Forte /* Return the result */ 4631291a2b48SSukumar Swaminathan return ((hba->wakeup_parms.u0.boot_bios_wd[0] == 0) ? 4632291a2b48SSukumar Swaminathan FC_SUCCESS : FC_FAILURE); 4633fcf3ce44SJohn Forte 4634*82527734SSukumar Swaminathan } /* emlxs_boot_code_disable() */ 4635fcf3ce44SJohn Forte 4636fcf3ce44SJohn Forte 4637291a2b48SSukumar Swaminathan extern int32_t 4638fcf3ce44SJohn Forte emlxs_boot_code_enable(emlxs_hba_t *hba) 4639fcf3ce44SJohn Forte { 4640fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 4641fcf3ce44SJohn Forte emlxs_vpd_t *vpd; 4642fcf3ce44SJohn Forte PROG_ID load_list[MAX_LOAD_ENTRY]; 4643fcf3ce44SJohn Forte uint32_t i; 4644fcf3ce44SJohn Forte 4645fcf3ce44SJohn Forte vpd = &VPD; 4646fcf3ce44SJohn Forte 4647fcf3ce44SJohn Forte /* Read the wakeup parms */ 4648fcf3ce44SJohn Forte if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 0)) { 4649fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, 4650fcf3ce44SJohn Forte "emlxs_boot_code_enable: Unable to read wake up parms."); 4651fcf3ce44SJohn Forte 4652291a2b48SSukumar Swaminathan return (FC_FAILURE); 4653fcf3ce44SJohn Forte } 4654291a2b48SSukumar Swaminathan 4655fcf3ce44SJohn Forte /* Check if boot code is already enabled */ 4656fcf3ce44SJohn Forte if (hba->wakeup_parms.u0.boot_bios_id.Type == BOOT_BIOS) { 4657fcf3ce44SJohn Forte return (FC_SUCCESS); 4658fcf3ce44SJohn Forte } 4659291a2b48SSukumar Swaminathan 4660fcf3ce44SJohn Forte if (!(hba->model_info.chip & 4661fcf3ce44SJohn Forte (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 4662fcf3ce44SJohn Forte if (hba->wakeup_parms.u1.EROM_prog_id.Type != BOOT_BIOS) { 4663fcf3ce44SJohn Forte return (EMLXS_NO_BOOT_CODE); 4664fcf3ce44SJohn Forte } 4665291a2b48SSukumar Swaminathan 4666fcf3ce44SJohn Forte /* Update the parms with the boot image id */ 4667fcf3ce44SJohn Forte /* Don't load the EROM this time */ 4668fcf3ce44SJohn Forte (void) emlxs_update_boot_wakeup_parms(hba, &hba->wakeup_parms, 4669fcf3ce44SJohn Forte &hba->wakeup_parms.u1.EROM_prog_id, 0); 4670fcf3ce44SJohn Forte } else { /* (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP) */ 4671291a2b48SSukumar Swaminathan 4672fcf3ce44SJohn Forte if (emlxs_get_load_list(hba, load_list)) { 4673291a2b48SSukumar Swaminathan return (FC_FAILURE); 4674fcf3ce44SJohn Forte } 4675291a2b48SSukumar Swaminathan 4676fcf3ce44SJohn Forte /* Scan load list for a boot image */ 4677fcf3ce44SJohn Forte for (i = 0; i < MAX_LOAD_ENTRY; i++) { 4678fcf3ce44SJohn Forte if (load_list[i].Type == BOOT_BIOS) { 4679fcf3ce44SJohn Forte /* Update the parms with the boot image id */ 4680fcf3ce44SJohn Forte /* Don't load the EROM this time */ 4681fcf3ce44SJohn Forte (void) emlxs_update_boot_wakeup_parms(hba, 4682fcf3ce44SJohn Forte &hba->wakeup_parms, &load_list[i], 0); 4683fcf3ce44SJohn Forte 4684fcf3ce44SJohn Forte break; 4685fcf3ce44SJohn Forte } 4686fcf3ce44SJohn Forte } 4687fcf3ce44SJohn Forte 4688fcf3ce44SJohn Forte if (i == MAX_LOAD_ENTRY) { 4689fcf3ce44SJohn Forte return (EMLXS_NO_BOOT_CODE); 4690fcf3ce44SJohn Forte } 4691fcf3ce44SJohn Forte } 4692fcf3ce44SJohn Forte 4693fcf3ce44SJohn Forte /* Now read the parms again to verify */ 4694fcf3ce44SJohn Forte (void) emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1); 4695fcf3ce44SJohn Forte emlxs_decode_version(hba->wakeup_parms.u0.boot_bios_wd[0], 4696fcf3ce44SJohn Forte vpd->boot_version); 4697291a2b48SSukumar Swaminathan /* (void) strcpy(vpd->fcode_version, vpd->boot_version); */ 4698fcf3ce44SJohn Forte 4699fcf3ce44SJohn Forte /* return the result */ 4700291a2b48SSukumar Swaminathan return ((hba->wakeup_parms.u0.boot_bios_wd[0] != 0) ? 4701291a2b48SSukumar Swaminathan FC_SUCCESS : FC_FAILURE); 4702fcf3ce44SJohn Forte 4703*82527734SSukumar Swaminathan } /* emlxs_boot_code_enable() */ 4704fcf3ce44SJohn Forte 4705fcf3ce44SJohn Forte 4706fcf3ce44SJohn Forte 4707291a2b48SSukumar Swaminathan extern int32_t 4708fcf3ce44SJohn Forte emlxs_boot_code_state(emlxs_hba_t *hba) 4709fcf3ce44SJohn Forte { 4710fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 4711fcf3ce44SJohn Forte 4712fcf3ce44SJohn Forte /* Read the wakeup parms */ 4713fcf3ce44SJohn Forte if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1)) { 4714fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, 4715fcf3ce44SJohn Forte "emlxs_boot_code_state: Unable to read wake up parms."); 4716fcf3ce44SJohn Forte 4717291a2b48SSukumar Swaminathan return (FC_FAILURE); 4718fcf3ce44SJohn Forte } 4719291a2b48SSukumar Swaminathan 4720fcf3ce44SJohn Forte /* return the result */ 4721291a2b48SSukumar Swaminathan return ((hba->wakeup_parms.u0.boot_bios_wd[0] != 0) ? 4722291a2b48SSukumar Swaminathan FC_SUCCESS : FC_FAILURE); 4723fcf3ce44SJohn Forte 4724*82527734SSukumar Swaminathan } /* emlxs_boot_code_state() */ 4725