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 /* 23*291a2b48SSukumar Swaminathan * Copyright 2009 Emulex. All rights reserved. 24fcf3ce44SJohn Forte * Use is subject to License terms. 25fcf3ce44SJohn Forte */ 26fcf3ce44SJohn Forte 27*291a2b48SSukumar Swaminathan #include <emlxs.h> 28fcf3ce44SJohn Forte 29fcf3ce44SJohn Forte /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 30fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_DOWNLOAD_C); 31fcf3ce44SJohn Forte 32fcf3ce44SJohn Forte #define MAX_BOOTID 10 33fcf3ce44SJohn Forte 34fcf3ce44SJohn Forte #define DATA32_SWAP(x) ((((x) & 0xFF)<<24) | (((x) & 0xFF00)<<8) | \ 35*291a2b48SSukumar Swaminathan (((x) & 0xFF0000)>>8) | \ 36*291a2b48SSukumar Swaminathan (((x) & 0xFF000000)>>24)) 37fcf3ce44SJohn Forte 38*291a2b48SSukumar Swaminathan static uint32_t emlxs_erase_fcode_flash(emlxs_hba_t *hba); 39*291a2b48SSukumar Swaminathan static uint32_t emlxs_write_fcode_flash(emlxs_hba_t *hba, 40*291a2b48SSukumar Swaminathan PIMAGE_HDR ImageHdr, caddr_t Buffer); 41fcf3ce44SJohn Forte 42*291a2b48SSukumar Swaminathan static int32_t emlxs_build_parms(caddr_t Buffer, PWAKE_UP_PARMS AbsWakeUpParms, 43*291a2b48SSukumar Swaminathan uint32_t BufferSize, PAIF_HDR AifHeader, 44*291a2b48SSukumar Swaminathan int32_t DwcFile); 45fcf3ce44SJohn Forte 46*291a2b48SSukumar Swaminathan static uint32_t emlxs_validate_image(emlxs_hba_t *hba, caddr_t Buffer, 47*291a2b48SSukumar Swaminathan uint32_t Size, emlxs_fw_image_t *fw_image); 48fcf3ce44SJohn Forte 49*291a2b48SSukumar Swaminathan static void emlxs_format_dump(MAILBOX *mb, uint32_t Type, uint32_t RegionId, 50*291a2b48SSukumar Swaminathan uint32_t WordCount, uint32_t BaseAddr); 51fcf3ce44SJohn Forte 52*291a2b48SSukumar Swaminathan static uint32_t emlxs_start_abs_download(emlxs_hba_t *hba, PAIF_HDR AifHdr, 53*291a2b48SSukumar Swaminathan caddr_t Buffer, PWAKE_UP_PARMS WakeUpParms, 54*291a2b48SSukumar Swaminathan uint32_t MaxRbusSramSize, uint32_t MaxIbusSramSize, 55*291a2b48SSukumar Swaminathan PWAKE_UP_PARMS AbsWakeUpParms, int32_t DwcFile); 56fcf3ce44SJohn Forte 57*291a2b48SSukumar Swaminathan static uint32_t emlxs_start_abs_download_2mb(emlxs_hba_t *hba, caddr_t buffer, 58*291a2b48SSukumar Swaminathan uint32_t len, uint32_t offline, 59*291a2b48SSukumar Swaminathan emlxs_fw_image_t *fw_image); 60fcf3ce44SJohn Forte 61*291a2b48SSukumar Swaminathan static uint32_t emlxs_proc_abs_2mb(emlxs_hba_t *hba, PAIF_HDR AifHdr, 62*291a2b48SSukumar Swaminathan caddr_t EntireBuffer, uint32_t FileType, 63*291a2b48SSukumar Swaminathan uint32_t BWCflag, uint32_t extType); 64fcf3ce44SJohn Forte 65*291a2b48SSukumar Swaminathan static void emlxs_format_load_area_cmd(MAILBOX *mb, uint32_t Base, 66*291a2b48SSukumar Swaminathan uint32_t DlByteCount, uint32_t Function, 67*291a2b48SSukumar Swaminathan uint32_t Complete, uint32_t DataOffset, uint32_t AreaId, 68*291a2b48SSukumar Swaminathan uint8_t MbxCmd, uint32_t StepCmd); 69fcf3ce44SJohn Forte 70*291a2b48SSukumar Swaminathan static uint32_t emlxs_build_parms_2mb_bwc(emlxs_hba_t *hba, PAIF_HDR AifHdr, 71*291a2b48SSukumar Swaminathan uint32_t extType, PWAKE_UP_PARMS AbsWakeUpParms); 72fcf3ce44SJohn Forte 73*291a2b48SSukumar Swaminathan static uint32_t emlxs_build_parms_2mb_dwc(emlxs_hba_t *hba, caddr_t Buffer, 74*291a2b48SSukumar Swaminathan uint32_t BufferSize, PAIF_HDR AifHeader, 75*291a2b48SSukumar Swaminathan PWAKE_UP_PARMS AbsWakeUpParms, uint32_t BWCflag, 76*291a2b48SSukumar Swaminathan uint32_t extType, uint32_t *numBootImage); 77fcf3ce44SJohn Forte 78*291a2b48SSukumar Swaminathan static uint32_t emlxs_update_exp_rom(emlxs_hba_t *hba, 79*291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms); 80fcf3ce44SJohn Forte 81*291a2b48SSukumar Swaminathan extern uint32_t emlxs_get_max_sram(emlxs_hba_t *hba, uint32_t *MaxRbusSize, 82*291a2b48SSukumar Swaminathan uint32_t *MaxIbusSize); 83fcf3ce44SJohn Forte 84*291a2b48SSukumar Swaminathan static void emlxs_format_prog_flash(MAILBOX *mb, uint32_t Base, 85*291a2b48SSukumar Swaminathan uint32_t DlByteCount, uint32_t Function, 86*291a2b48SSukumar Swaminathan uint32_t Complete, uint32_t BdeAddress, 87*291a2b48SSukumar Swaminathan uint32_t BdeSize, PROG_ID *ProgId); 88fcf3ce44SJohn Forte 89*291a2b48SSukumar Swaminathan static void emlxs_format_update_parms(MAILBOX *mb, 90*291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms); 91fcf3ce44SJohn Forte 92*291a2b48SSukumar Swaminathan static void emlxs_format_update_pci_cfg(emlxs_hba_t *hba, MAILBOX *mb, 93*291a2b48SSukumar Swaminathan uint32_t region_id, uint32_t size); 94fcf3ce44SJohn Forte 95*291a2b48SSukumar Swaminathan static uint32_t emlxs_update_wakeup_parms(emlxs_hba_t *hba, 96*291a2b48SSukumar Swaminathan PWAKE_UP_PARMS AbsWakeUpParms, 97*291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms); 98fcf3ce44SJohn Forte 99*291a2b48SSukumar Swaminathan static uint32_t emlxs_update_boot_wakeup_parms(emlxs_hba_t *hba, 100*291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, PROG_ID *id, 101*291a2b48SSukumar Swaminathan uint32_t proc_erom); 102fcf3ce44SJohn Forte 103*291a2b48SSukumar Swaminathan static uint32_t emlxs_update_ff_wakeup_parms(emlxs_hba_t *hba, 104*291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 105fcf3ce44SJohn Forte 106*291a2b48SSukumar Swaminathan static uint32_t emlxs_update_sli1_wakeup_parms(emlxs_hba_t *hba, 107*291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 108fcf3ce44SJohn Forte 109*291a2b48SSukumar Swaminathan static uint32_t emlxs_update_sli2_wakeup_parms(emlxs_hba_t *hba, 110*291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 111fcf3ce44SJohn Forte 112*291a2b48SSukumar Swaminathan static uint32_t emlxs_update_sli3_wakeup_parms(emlxs_hba_t *hba, 113*291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 114fcf3ce44SJohn Forte 115*291a2b48SSukumar Swaminathan static uint32_t emlxs_update_sli4_wakeup_parms(emlxs_hba_t *hba, 116*291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, PROG_ID *id); 117fcf3ce44SJohn Forte 118fcf3ce44SJohn Forte 119*291a2b48SSukumar Swaminathan static uint32_t emlxs_start_rel_download(emlxs_hba_t *hba, PIMAGE_HDR ImageHdr, 120*291a2b48SSukumar Swaminathan caddr_t Buffer, PWAKE_UP_PARMS WakeUpParms, 121*291a2b48SSukumar Swaminathan uint32_t MaxRbusSramSize, uint32_t MaxIbusSramSize); 122fcf3ce44SJohn Forte 123*291a2b48SSukumar Swaminathan static uint32_t emlxs_read_load_list(emlxs_hba_t *hba, LOAD_LIST *LoadList); 124fcf3ce44SJohn Forte 125*291a2b48SSukumar Swaminathan static uint32_t emlxs_valid_cksum(uint32_t *StartAddr, uint32_t *EndAddr); 126*291a2b48SSukumar Swaminathan static void emlxs_disp_aif_header(emlxs_hba_t *hba, PAIF_HDR AifHdr); 127*291a2b48SSukumar Swaminathan static void emlxs_dump_image_header(emlxs_hba_t *hba, PIMAGE_HDR image); 128*291a2b48SSukumar Swaminathan static uint32_t emlxs_get_abs_image_type(caddr_t Buffer, uint32_t BufferSize); 129fcf3ce44SJohn Forte 130*291a2b48SSukumar Swaminathan static uint32_t emlxs_get_dwc_image_type(emlxs_hba_t *hba, caddr_t Buffer, 131*291a2b48SSukumar Swaminathan uint32_t BufferSize, PAIF_HDR AifHeader); 132fcf3ce44SJohn Forte 133*291a2b48SSukumar Swaminathan static uint32_t emlxs_type_check(uint32_t type); 134*291a2b48SSukumar Swaminathan static uint32_t emlxs_kern_check(emlxs_hba_t *hba, uint32_t version); 135*291a2b48SSukumar Swaminathan static uint32_t emlxs_stub_check(emlxs_hba_t *hba, uint32_t version); 136*291a2b48SSukumar Swaminathan static uint32_t emlxs_sli1_check(emlxs_hba_t *hba, uint32_t version); 137*291a2b48SSukumar Swaminathan static uint32_t emlxs_sli2_check(emlxs_hba_t *hba, uint32_t version); 138*291a2b48SSukumar Swaminathan static uint32_t emlxs_sli3_check(emlxs_hba_t *hba, uint32_t version); 139*291a2b48SSukumar Swaminathan static uint32_t emlxs_sli4_check(emlxs_hba_t *hba, uint32_t version); 140*291a2b48SSukumar Swaminathan static uint32_t emlxs_bios_check(emlxs_hba_t *hba, uint32_t version); 141*291a2b48SSukumar Swaminathan static uint32_t emlxs_sbus_fcode_check(emlxs_hba_t *hba, uint32_t version); 142*291a2b48SSukumar Swaminathan static uint32_t emlxs_validate_version(emlxs_hba_t *hba, 143*291a2b48SSukumar Swaminathan emlxs_fw_file_t *file, uint32_t id, uint32_t type, 144*291a2b48SSukumar Swaminathan char *file_type); 145fcf3ce44SJohn Forte 146*291a2b48SSukumar Swaminathan /* ************************************************************************* */ 147fcf3ce44SJohn Forte 148fcf3ce44SJohn Forte 149fcf3ce44SJohn Forte extern int32_t 150fcf3ce44SJohn Forte emlxs_fw_download(emlxs_hba_t *hba, caddr_t buffer, uint32_t len, 151fcf3ce44SJohn Forte uint32_t offline) 152fcf3ce44SJohn Forte { 153fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 154fcf3ce44SJohn Forte uint32_t *Uptr; 155fcf3ce44SJohn Forte IMAGE_HDR ImageHdr; 156fcf3ce44SJohn Forte AIF_HDR AifHdr; 157fcf3ce44SJohn Forte uint32_t ImageType; 158fcf3ce44SJohn Forte WAKE_UP_PARMS WakeUpParms; 159fcf3ce44SJohn Forte WAKE_UP_PARMS AbsWakeUpParms; 160fcf3ce44SJohn Forte uint32_t MaxRbusSramSize; 161fcf3ce44SJohn Forte uint32_t MaxIbusSramSize; 162fcf3ce44SJohn Forte int32_t AbsChangeParams = 0; 163fcf3ce44SJohn Forte int32_t DwcFile = FALSE; 164fcf3ce44SJohn Forte uint32_t rval = 0; 165fcf3ce44SJohn Forte emlxs_fw_image_t fw_image; 166fcf3ce44SJohn Forte uint32_t i; 167fcf3ce44SJohn Forte 168fcf3ce44SJohn Forte #ifdef EMLXS_I386 169fcf3ce44SJohn Forte caddr_t local_buffer; 170fcf3ce44SJohn Forte uint32_t *bptr1; 171fcf3ce44SJohn Forte uint32_t *bptr2; 172*291a2b48SSukumar Swaminathan #endif /* EMLXS_I386 */ 173fcf3ce44SJohn Forte 174fcf3ce44SJohn Forte if (buffer == NULL || len == 0) { 175fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 176fcf3ce44SJohn Forte } 177fcf3ce44SJohn Forte #ifdef EMLXS_I386 178fcf3ce44SJohn Forte /* We need to swap the image buffer before we start */ 179fcf3ce44SJohn Forte 180fcf3ce44SJohn Forte /* 181fcf3ce44SJohn Forte * Use KM_SLEEP to allocate a temporary buffer 182fcf3ce44SJohn Forte */ 183fcf3ce44SJohn Forte local_buffer = (caddr_t)kmem_zalloc(len, KM_SLEEP); 184fcf3ce44SJohn Forte 185fcf3ce44SJohn Forte if (local_buffer == NULL) { 186fcf3ce44SJohn Forte return (FC_NOMEM); 187fcf3ce44SJohn Forte } 188*291a2b48SSukumar Swaminathan 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++) { 193fcf3ce44SJohn Forte *bptr1 = SWAP_DATA32(*bptr2); 194fcf3ce44SJohn Forte bptr1++; 195fcf3ce44SJohn Forte bptr2++; 196fcf3ce44SJohn Forte } 197fcf3ce44SJohn Forte 198fcf3ce44SJohn Forte /* Replace the original buffer */ 199fcf3ce44SJohn Forte buffer = local_buffer; 200*291a2b48SSukumar Swaminathan #endif /* EMLXS_I386 */ 201*291a2b48SSukumar Swaminathan 202fcf3ce44SJohn Forte 203fcf3ce44SJohn Forte bzero(&fw_image, sizeof (emlxs_fw_image_t)); 204fcf3ce44SJohn Forte for (i = 0; i < MAX_PROG_TYPES; i++) { 205fcf3ce44SJohn Forte (void) strcpy(fw_image.prog[i].label, "none"); 206fcf3ce44SJohn Forte } 207fcf3ce44SJohn Forte 208fcf3ce44SJohn Forte /* Validate image */ 209fcf3ce44SJohn Forte if ((rval = emlxs_validate_image(hba, buffer, len, &fw_image))) { 210fcf3ce44SJohn Forte goto done; 211fcf3ce44SJohn Forte } 212*291a2b48SSukumar Swaminathan 213fcf3ce44SJohn Forte /* Get image type */ 214fcf3ce44SJohn Forte Uptr = (uint32_t *)buffer; 215fcf3ce44SJohn Forte ImageType = *Uptr; 216fcf3ce44SJohn Forte 217fcf3ce44SJohn Forte /* 218*291a2b48SSukumar Swaminathan * Pegasus and beyond FW download is done differently 219*291a2b48SSukumar Swaminathan * for absolute download. 220fcf3ce44SJohn Forte */ 221fcf3ce44SJohn Forte 222fcf3ce44SJohn Forte /* Check for absolute image */ 223fcf3ce44SJohn Forte if ((ImageType == NOP_IMAGE_TYPE) && 224fcf3ce44SJohn Forte !(hba->model_info.chip & 225fcf3ce44SJohn Forte (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 226fcf3ce44SJohn Forte /* 227fcf3ce44SJohn Forte * Because 2Mb flash download file format is different from 228fcf3ce44SJohn Forte * 512k, it needs to be handled differently 229fcf3ce44SJohn Forte */ 230fcf3ce44SJohn Forte if (rval = emlxs_start_abs_download_2mb(hba, buffer, len, 231fcf3ce44SJohn Forte offline, &fw_image)) { 232fcf3ce44SJohn Forte goto done; 233fcf3ce44SJohn Forte } 234*291a2b48SSukumar Swaminathan 235fcf3ce44SJohn Forte /* Offline already handled */ 236fcf3ce44SJohn Forte offline = 0; 237fcf3ce44SJohn Forte 238fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 239fcf3ce44SJohn Forte } 240*291a2b48SSukumar Swaminathan 241fcf3ce44SJohn Forte /* Pre-pegasus adapters only */ 242fcf3ce44SJohn Forte 243fcf3ce44SJohn Forte /* Check for absolute image */ 244fcf3ce44SJohn Forte else if (ImageType == NOP_IMAGE_TYPE) { 245fcf3ce44SJohn Forte bcopy(buffer, &AifHdr, sizeof (AIF_HDR)); 246fcf3ce44SJohn Forte bzero((void *)&ImageHdr, sizeof (IMAGE_HDR)); 247fcf3ce44SJohn Forte 248fcf3ce44SJohn Forte if (AifHdr.ImageBase && (AifHdr.ImageBase == 0x20000)) { 249fcf3ce44SJohn Forte DwcFile = TRUE; 250fcf3ce44SJohn Forte } 251*291a2b48SSukumar Swaminathan 252*291a2b48SSukumar Swaminathan AbsChangeParams = emlxs_build_parms(buffer, 253*291a2b48SSukumar Swaminathan &AbsWakeUpParms, len, &AifHdr, DwcFile); 254fcf3ce44SJohn Forte } else { /* (ImageType != NOP_IMAGE_TYPE) Relative image */ 255*291a2b48SSukumar Swaminathan 256fcf3ce44SJohn Forte bzero((void *)&AifHdr, sizeof (AIF_HDR)); 257fcf3ce44SJohn Forte bcopy(buffer, &ImageHdr, sizeof (IMAGE_HDR)); 258fcf3ce44SJohn Forte } 259fcf3ce44SJohn Forte 260fcf3ce44SJohn Forte /* 261fcf3ce44SJohn Forte * Everything checks out, now to just do it 262fcf3ce44SJohn Forte */ 263fcf3ce44SJohn Forte 264fcf3ce44SJohn Forte if (offline) { 265fcf3ce44SJohn Forte if (emlxs_offline(hba) != FC_SUCCESS) { 266fcf3ce44SJohn Forte offline = 0; 267fcf3ce44SJohn Forte 268fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 269fcf3ce44SJohn Forte "Unable to take adapter offline."); 270fcf3ce44SJohn Forte 271fcf3ce44SJohn Forte rval = EMLXS_OFFLINE_FAILED; 272fcf3ce44SJohn Forte 273fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 274fcf3ce44SJohn Forte } 275*291a2b48SSukumar Swaminathan 276*291a2b48SSukumar Swaminathan if (emlxs_sli_hba_reset(hba, 1, 1) != FC_SUCCESS) { 277fcf3ce44SJohn Forte offline = 0; 278fcf3ce44SJohn Forte 279fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 280fcf3ce44SJohn Forte "Unable to restart adapter."); 281fcf3ce44SJohn Forte 282fcf3ce44SJohn Forte rval = EMLXS_OFFLINE_FAILED; 283fcf3ce44SJohn Forte 284fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 285fcf3ce44SJohn Forte } 286fcf3ce44SJohn Forte } 287*291a2b48SSukumar Swaminathan 288fcf3ce44SJohn Forte if (ImageHdr.Id.Type == SBUS_FCODE) { 289fcf3ce44SJohn Forte /* Erase Flash */ 290fcf3ce44SJohn Forte if (emlxs_erase_fcode_flash(hba)) { 291fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 292fcf3ce44SJohn Forte "Unable to erase flash."); 293fcf3ce44SJohn Forte 294fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 295fcf3ce44SJohn Forte 296fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 297fcf3ce44SJohn Forte } 298*291a2b48SSukumar Swaminathan 299fcf3ce44SJohn Forte /* Write FCODE */ 300fcf3ce44SJohn Forte if (emlxs_write_fcode_flash(hba, &ImageHdr, buffer)) { 301fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 302fcf3ce44SJohn Forte "Unable to write flash."); 303fcf3ce44SJohn Forte 304fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 305fcf3ce44SJohn Forte 306fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 307fcf3ce44SJohn Forte } 308*291a2b48SSukumar Swaminathan 309fcf3ce44SJohn Forte } else { /* !SBUS_FCODE */ 310fcf3ce44SJohn Forte 311*291a2b48SSukumar Swaminathan 312fcf3ce44SJohn Forte if (emlxs_read_wakeup_parms(hba, &WakeUpParms, 1)) { 313fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 314fcf3ce44SJohn Forte "Unable to get parameters."); 315fcf3ce44SJohn Forte 316fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 317fcf3ce44SJohn Forte 318fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 319fcf3ce44SJohn Forte } 320*291a2b48SSukumar Swaminathan 321fcf3ce44SJohn Forte if (emlxs_get_max_sram(hba, &MaxRbusSramSize, 322fcf3ce44SJohn Forte &MaxIbusSramSize)) { 323fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 324fcf3ce44SJohn Forte "Unable to get RAM size."); 325fcf3ce44SJohn Forte 326fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 327fcf3ce44SJohn Forte 328fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 329fcf3ce44SJohn Forte } 330*291a2b48SSukumar Swaminathan 331fcf3ce44SJohn Forte if (ImageType == NOP_IMAGE_TYPE) { 332fcf3ce44SJohn Forte if (emlxs_start_abs_download(hba, &AifHdr, buffer, 333fcf3ce44SJohn Forte &WakeUpParms, MaxRbusSramSize, MaxIbusSramSize, 334fcf3ce44SJohn Forte (AbsChangeParams) ? &AbsWakeUpParms : NULL, 335fcf3ce44SJohn Forte DwcFile)) { 336fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 337fcf3ce44SJohn Forte &emlxs_download_failed_msg, 338fcf3ce44SJohn Forte "Failed to program flash."); 339fcf3ce44SJohn Forte 340fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 341fcf3ce44SJohn Forte 342fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 343fcf3ce44SJohn Forte } 344*291a2b48SSukumar Swaminathan 345fcf3ce44SJohn Forte } else { 346fcf3ce44SJohn Forte 347fcf3ce44SJohn Forte if (emlxs_start_rel_download(hba, &ImageHdr, buffer, 348fcf3ce44SJohn Forte &WakeUpParms, MaxRbusSramSize, MaxIbusSramSize)) { 349fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 350fcf3ce44SJohn Forte &emlxs_download_failed_msg, 351fcf3ce44SJohn Forte "Failed to program flash."); 352fcf3ce44SJohn Forte 353fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 354fcf3ce44SJohn Forte 355fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 356fcf3ce44SJohn Forte } 357fcf3ce44SJohn Forte } 358fcf3ce44SJohn Forte 359fcf3ce44SJohn Forte } /* !SBUS_FCODE */ 360fcf3ce44SJohn Forte 361fcf3ce44SJohn Forte 362fcf3ce44SJohn Forte SLI_DOWNLOAD_EXIT: 363fcf3ce44SJohn Forte 364fcf3ce44SJohn Forte if (offline) { 365fcf3ce44SJohn Forte (void) emlxs_online(hba); 366fcf3ce44SJohn Forte } 367*291a2b48SSukumar Swaminathan 368fcf3ce44SJohn Forte if (rval == 0) { 369fcf3ce44SJohn Forte 370fcf3ce44SJohn Forte 371fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_complete_msg, 372fcf3ce44SJohn Forte "Status good."); 373fcf3ce44SJohn Forte } 374*291a2b48SSukumar Swaminathan 375fcf3ce44SJohn Forte done: 376fcf3ce44SJohn Forte 377fcf3ce44SJohn Forte #ifdef EMLXS_I386 378fcf3ce44SJohn Forte /* Free the local buffer */ 379fcf3ce44SJohn Forte kmem_free(local_buffer, len); 380*291a2b48SSukumar Swaminathan #endif /* EMLXS_I386 */ 381fcf3ce44SJohn Forte 382fcf3ce44SJohn Forte return (rval); 383fcf3ce44SJohn Forte 384*291a2b48SSukumar Swaminathan } /* emlxs_fw_download */ 385fcf3ce44SJohn Forte 386fcf3ce44SJohn Forte 387fcf3ce44SJohn Forte 388fcf3ce44SJohn Forte extern int32_t 389fcf3ce44SJohn Forte emlxs_cfl_download(emlxs_hba_t *hba, uint32_t region, caddr_t buffer, 390fcf3ce44SJohn Forte uint32_t len) 391fcf3ce44SJohn Forte { 392fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 393fcf3ce44SJohn Forte MAILBOXQ *mbox = NULL; 394fcf3ce44SJohn Forte MAILBOX *mb; 395fcf3ce44SJohn Forte uint32_t rval = 0; 396fcf3ce44SJohn Forte uint32_t region_id; 397fcf3ce44SJohn Forte uint32_t id; 398fcf3ce44SJohn Forte 399fcf3ce44SJohn Forte #ifndef EMLXS_I386 400fcf3ce44SJohn Forte caddr_t local_buffer; 401fcf3ce44SJohn Forte uint32_t *bptr1; 402fcf3ce44SJohn Forte uint32_t *bptr2; 403fcf3ce44SJohn Forte uint32_t i; 404*291a2b48SSukumar Swaminathan #endif /* !EMLXS_I386 */ 405fcf3ce44SJohn Forte 406fcf3ce44SJohn Forte if (buffer == NULL || len == 0) { 407fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 408fcf3ce44SJohn Forte } 409fcf3ce44SJohn Forte #ifndef EMLXS_I386 410fcf3ce44SJohn Forte /* We need to swap the image buffer before we start */ 411fcf3ce44SJohn Forte 412fcf3ce44SJohn Forte /* 413fcf3ce44SJohn Forte * Use KM_SLEEP to allocate a temporary buffer 414fcf3ce44SJohn Forte */ 415fcf3ce44SJohn Forte local_buffer = (caddr_t)kmem_zalloc(len, KM_SLEEP); 416fcf3ce44SJohn Forte 417fcf3ce44SJohn Forte if (local_buffer == NULL) { 418fcf3ce44SJohn Forte return (FC_NOMEM); 419fcf3ce44SJohn Forte } 420*291a2b48SSukumar Swaminathan 421fcf3ce44SJohn Forte /* Perform a 32 bit swap of the image */ 422fcf3ce44SJohn Forte bptr1 = (uint32_t *)local_buffer; 423fcf3ce44SJohn Forte bptr2 = (uint32_t *)buffer; 424fcf3ce44SJohn Forte 425fcf3ce44SJohn Forte for (i = 0; i < (len / 4); i++) { 426fcf3ce44SJohn Forte *bptr1 = DATA32_SWAP(*bptr2); 427fcf3ce44SJohn Forte bptr1++; 428fcf3ce44SJohn Forte bptr2++; 429fcf3ce44SJohn Forte } 430fcf3ce44SJohn Forte 431fcf3ce44SJohn Forte /* Replace the original buffer */ 432fcf3ce44SJohn Forte buffer = local_buffer; 433fcf3ce44SJohn Forte 434*291a2b48SSukumar Swaminathan #endif /* !EMLXS_I386 */ 435fcf3ce44SJohn Forte 436fcf3ce44SJohn Forte if (len > 128) { 437fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 438*291a2b48SSukumar Swaminathan "Invalid image length: 0x%x > 128", len); 439fcf3ce44SJohn Forte 440fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 441fcf3ce44SJohn Forte } 442*291a2b48SSukumar Swaminathan 443fcf3ce44SJohn Forte /* Check the region number */ 444fcf3ce44SJohn Forte if ((region > 2) && (region != 0xff)) { 445fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 446*291a2b48SSukumar Swaminathan "Invalid region id: 0x%x", region); 447fcf3ce44SJohn Forte 448fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 449fcf3ce44SJohn Forte 450fcf3ce44SJohn Forte } 451*291a2b48SSukumar Swaminathan 452fcf3ce44SJohn Forte /* Check the image vendor id */ 453fcf3ce44SJohn Forte id = *(int32_t *)buffer; 454fcf3ce44SJohn Forte if ((id & 0xffff) != 0x10df) { 455fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 456*291a2b48SSukumar Swaminathan "Invalid image id: 0x%x", id); 457fcf3ce44SJohn Forte 458fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 459fcf3ce44SJohn Forte } 460*291a2b48SSukumar Swaminathan 461*291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 462*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 463fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 464fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 465fcf3ce44SJohn Forte 466fcf3ce44SJohn Forte rval = 1; 467fcf3ce44SJohn Forte 468fcf3ce44SJohn Forte goto done; 469fcf3ce44SJohn Forte } 470*291a2b48SSukumar Swaminathan 471fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 472fcf3ce44SJohn Forte 473fcf3ce44SJohn Forte /* 474fcf3ce44SJohn Forte * Everything checks out, now to just do it 475fcf3ce44SJohn Forte */ 476fcf3ce44SJohn Forte if (emlxs_offline(hba) != FC_SUCCESS) { 477fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 478fcf3ce44SJohn Forte "Unable to take HBA offline."); 479fcf3ce44SJohn Forte 480fcf3ce44SJohn Forte rval = EMLXS_OFFLINE_FAILED; 481fcf3ce44SJohn Forte 482fcf3ce44SJohn Forte goto done; 483fcf3ce44SJohn Forte } 484*291a2b48SSukumar Swaminathan 485*291a2b48SSukumar Swaminathan if (emlxs_sli_hba_reset(hba, 1, 1) != FC_SUCCESS) { 486fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 487fcf3ce44SJohn Forte "Unable to restart adapter."); 488fcf3ce44SJohn Forte 489fcf3ce44SJohn Forte rval = EMLXS_OFFLINE_FAILED; 490fcf3ce44SJohn Forte 491fcf3ce44SJohn Forte goto done; 492fcf3ce44SJohn Forte } 493*291a2b48SSukumar Swaminathan 494fcf3ce44SJohn Forte /* Check if default region is requested */ 495fcf3ce44SJohn Forte if (region == 0xff) { 496fcf3ce44SJohn Forte /* 497*291a2b48SSukumar Swaminathan * Sun-branded Helios and Zypher have different 498*291a2b48SSukumar Swaminathan * default PCI region 499fcf3ce44SJohn Forte */ 500fcf3ce44SJohn Forte if ((hba->model_info.flags & EMLXS_SUN_BRANDED) && 501fcf3ce44SJohn Forte (hba->model_info.chip & 502fcf3ce44SJohn Forte (EMLXS_HELIOS_CHIP | EMLXS_ZEPHYR_CHIP))) { 503fcf3ce44SJohn Forte region = 2; 504fcf3ce44SJohn Forte } else { 505fcf3ce44SJohn Forte region = 0; 506fcf3ce44SJohn Forte } 507fcf3ce44SJohn Forte } 508*291a2b48SSukumar Swaminathan 509fcf3ce44SJohn Forte /* Set region id based on PCI region requested */ 510fcf3ce44SJohn Forte region_id = DEF_PCI_CFG_REGION_ID + region; 511fcf3ce44SJohn Forte 512fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 513*291a2b48SSukumar Swaminathan "PCI configuration: PCI%d region=%d id=0x%x size=%d", region, 514*291a2b48SSukumar Swaminathan region_id, id, len); 515fcf3ce44SJohn Forte 516fcf3ce44SJohn Forte /* Copy the data buffer to SLIM */ 517fcf3ce44SJohn Forte WRITE_SLIM_COPY(hba, (uint32_t *)buffer, 518*291a2b48SSukumar Swaminathan (volatile uint32_t *)((volatile char *)hba->slim_addr + 519*291a2b48SSukumar Swaminathan sizeof (MAILBOX)), (len / sizeof (uint32_t))); 520fcf3ce44SJohn Forte 521fcf3ce44SJohn Forte emlxs_format_update_pci_cfg(hba, mb, region_id, len); 522fcf3ce44SJohn Forte 523*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 524fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 525*291a2b48SSukumar Swaminathan "Unable to update PCI configuration: Mailbox cmd=%x " 526*291a2b48SSukumar Swaminathan "status=%x info=%d", mb->mbxCommand, mb->mbxStatus, 527fcf3ce44SJohn Forte mb->un.varUpdateCfg.rsp_info); 528fcf3ce44SJohn Forte 529fcf3ce44SJohn Forte rval = 1; 530fcf3ce44SJohn Forte } 531*291a2b48SSukumar Swaminathan 532fcf3ce44SJohn Forte (void) emlxs_online(hba); 533fcf3ce44SJohn Forte 534fcf3ce44SJohn Forte if (rval == 0) { 535fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_complete_msg, 536fcf3ce44SJohn Forte "Status good."); 537fcf3ce44SJohn Forte } 538*291a2b48SSukumar Swaminathan 539fcf3ce44SJohn Forte done: 540fcf3ce44SJohn Forte 541fcf3ce44SJohn Forte if (mbox) { 542fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 543fcf3ce44SJohn Forte } 544fcf3ce44SJohn Forte #ifndef EMLXS_I386 545fcf3ce44SJohn Forte /* Free the local buffer */ 546fcf3ce44SJohn Forte kmem_free(local_buffer, len); 547*291a2b48SSukumar Swaminathan #endif /* !EMLXS_I386 */ 548fcf3ce44SJohn Forte 549fcf3ce44SJohn Forte return (rval); 550fcf3ce44SJohn Forte 551*291a2b48SSukumar Swaminathan } /* emlxs_cfl_download */ 552fcf3ce44SJohn Forte 553fcf3ce44SJohn Forte 554fcf3ce44SJohn Forte 555fcf3ce44SJohn Forte static uint32_t 556fcf3ce44SJohn Forte emlxs_valid_cksum(uint32_t *StartAddr, uint32_t *EndAddr) 557fcf3ce44SJohn Forte { 558fcf3ce44SJohn Forte uint32_t Temp; 559fcf3ce44SJohn Forte uint32_t CkSum; 560fcf3ce44SJohn Forte 561fcf3ce44SJohn Forte EndAddr++; 562fcf3ce44SJohn Forte CkSum = SLI_CKSUM_SEED; 563fcf3ce44SJohn Forte 564fcf3ce44SJohn Forte CkSum = (CkSum >> 1) | (CkSum << 31); 565fcf3ce44SJohn Forte while (StartAddr != EndAddr) { 566fcf3ce44SJohn Forte CkSum = (CkSum << 1) | (CkSum >> 31); 567fcf3ce44SJohn Forte Temp = *StartAddr; 568fcf3ce44SJohn Forte 569fcf3ce44SJohn Forte CkSum ^= Temp; 570fcf3ce44SJohn Forte StartAddr++; 571fcf3ce44SJohn Forte } 572fcf3ce44SJohn Forte 573fcf3ce44SJohn Forte return (CkSum << 1) | (CkSum >> 31); 574fcf3ce44SJohn Forte 575*291a2b48SSukumar Swaminathan } /* emlxs_valid_cksum() */ 576fcf3ce44SJohn Forte 577fcf3ce44SJohn Forte 578fcf3ce44SJohn Forte static void 579fcf3ce44SJohn Forte emlxs_disp_aif_header(emlxs_hba_t *hba, PAIF_HDR AifHdr) 580fcf3ce44SJohn Forte { 581fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 582fcf3ce44SJohn Forte 583*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "AIF Header: "); 584fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 585fcf3ce44SJohn Forte "AIF Header: compress_br = 0x%x", AifHdr->CompressBr); 586fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 587fcf3ce44SJohn Forte "AIF Header: reloc_br = 0x%x", AifHdr->RelocBr); 588fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 589fcf3ce44SJohn Forte "AIF Header: zinit_br = 0x%x", AifHdr->ZinitBr); 590fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 591fcf3ce44SJohn Forte "AIF Header: entry_br = 0x%x", AifHdr->EntryBr); 592fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 593fcf3ce44SJohn Forte "AIF Header: area_id = 0x%x", AifHdr->Area_ID); 594fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 595fcf3ce44SJohn Forte "AIF Header: rosize = 0x%x", AifHdr->RoSize); 596fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 597fcf3ce44SJohn Forte "AIF Header: dbgsize = 0x%x", AifHdr->DbgSize); 598fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 599fcf3ce44SJohn Forte "AIF Header: zinitsize = 0x%x", AifHdr->ZinitSize); 600fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 601fcf3ce44SJohn Forte "AIF Header: dbgtype = 0x%x", AifHdr->DbgType); 602fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 603fcf3ce44SJohn Forte "AIF Header: imagebase = 0x%x", AifHdr->ImageBase); 604fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 605fcf3ce44SJohn Forte "AIF Header: area_size = 0x%x", AifHdr->Area_Size); 606fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 607fcf3ce44SJohn Forte "AIF Header: address_mode = 0x%x", AifHdr->AddressMode); 608fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 609fcf3ce44SJohn Forte "AIF Header: database = 0x%x", AifHdr->DataBase); 610fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 611fcf3ce44SJohn Forte "AIF Header: aversion = 0x%x", AifHdr->AVersion); 612fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 613fcf3ce44SJohn Forte "AIF Header: spare2 = 0x%x", AifHdr->Spare2); 614fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 615fcf3ce44SJohn Forte "AIF Header: debug_swi = 0x%x", AifHdr->DebugSwi); 616fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 617fcf3ce44SJohn Forte "AIF Header: zinitcode[0] = 0x%x", AifHdr->ZinitCode[0]); 618fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 619fcf3ce44SJohn Forte "AIF Header: zinitcode[1] = 0x%x", AifHdr->ZinitCode[1]); 620fcf3ce44SJohn Forte 621*291a2b48SSukumar Swaminathan } /* emlxs_disp_aif_header() */ 622fcf3ce44SJohn Forte 623fcf3ce44SJohn Forte 624fcf3ce44SJohn Forte 625fcf3ce44SJohn Forte static void 626fcf3ce44SJohn Forte emlxs_dump_image_header(emlxs_hba_t *hba, PIMAGE_HDR image) 627fcf3ce44SJohn Forte { 628fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 629fcf3ce44SJohn Forte 630*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "Img Header: "); 631fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 632fcf3ce44SJohn Forte "Img Header: BlockSize = 0x%x", image->BlockSize); 633fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 634fcf3ce44SJohn Forte "Img Header: PROG_ID Type = 0x%x", image->Id.Type); 635fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 636fcf3ce44SJohn Forte "Img Header: PROG_ID Id = 0x%x", image->Id.Id); 637fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 638fcf3ce44SJohn Forte "Img Header: PROG_ID Ver = 0x%x", image->Id.Ver); 639fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 640fcf3ce44SJohn Forte "Img Header: PROG_ID Rev = 0x%x", image->Id.Rev); 641fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 642fcf3ce44SJohn Forte "Img Header: PROG_ID revcomp = 0x%x", image->Id.un.revcomp); 643fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 644fcf3ce44SJohn Forte "Img Header: Flags = 0x%x", image->Flags); 645fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 646fcf3ce44SJohn Forte "Img Header: EntryAdr = 0x%x", image->EntryAdr); 647fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 648fcf3ce44SJohn Forte "Img Header: InitAdr = 0x%x", image->InitAdr); 649fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 650fcf3ce44SJohn Forte "Img Header: ExitAdr = 0x%x", image->ExitAdr); 651fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 652fcf3ce44SJohn Forte "Img Header: ImageBase = 0x%x", image->ImageBase); 653fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 654fcf3ce44SJohn Forte "Img Header: ImageSize = 0x%x", image->ImageSize); 655fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 656fcf3ce44SJohn Forte "Img Header: ZinitSize = 0x%x", image->ZinitSize); 657fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 658fcf3ce44SJohn Forte "Img Header: RelocSize = 0x%x", image->RelocSize); 659fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, 660fcf3ce44SJohn Forte "Img Header: HdrCks = 0x%x", image->HdrCks); 661fcf3ce44SJohn Forte 662*291a2b48SSukumar Swaminathan } /* emlxs_dump_image_header() */ 663fcf3ce44SJohn Forte 664fcf3ce44SJohn Forte 665fcf3ce44SJohn Forte static void 666fcf3ce44SJohn Forte emlxs_format_dump(MAILBOX *mb, uint32_t Type, uint32_t RegionId, 667fcf3ce44SJohn Forte uint32_t WordCount, uint32_t BaseAddr) 668fcf3ce44SJohn Forte { 669fcf3ce44SJohn Forte bzero((void *)mb, MAILBOX_CMD_BSIZE); 670fcf3ce44SJohn Forte 671fcf3ce44SJohn Forte mb->mbxCommand = MBX_DUMP_MEMORY; 672fcf3ce44SJohn Forte mb->un.varDmp.type = Type; 673fcf3ce44SJohn Forte mb->un.varDmp.region_id = RegionId; 674fcf3ce44SJohn Forte mb->un.varDmp.word_cnt = WordCount; 675fcf3ce44SJohn Forte mb->un.varDmp.base_adr = BaseAddr; 676fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 677fcf3ce44SJohn Forte 678fcf3ce44SJohn Forte return; 679fcf3ce44SJohn Forte 680*291a2b48SSukumar Swaminathan } /* emlxs_format_dump() */ 681fcf3ce44SJohn Forte 682fcf3ce44SJohn Forte 683fcf3ce44SJohn Forte /* ARGSUSED */ 684fcf3ce44SJohn Forte static uint32_t 685*291a2b48SSukumar Swaminathan emlxs_start_abs_download(emlxs_hba_t *hba, 686*291a2b48SSukumar Swaminathan PAIF_HDR AifHdr, 687*291a2b48SSukumar Swaminathan caddr_t Buffer, 688*291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, 689*291a2b48SSukumar Swaminathan uint32_t MaxRbusSramSize, 690fcf3ce44SJohn Forte uint32_t MaxIbusSramSize, PWAKE_UP_PARMS AbsWakeUpParms, int32_t DwcFile) 691fcf3ce44SJohn Forte { 692fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 693fcf3ce44SJohn Forte uint32_t DlByteCount = AifHdr->RoSize + AifHdr->RwSize; 694fcf3ce44SJohn Forte IMAGE_HDR ImageHdr; 695fcf3ce44SJohn Forte uint32_t *Src; 696fcf3ce44SJohn Forte uint32_t *Dst; 697fcf3ce44SJohn Forte caddr_t DataBuffer = NULL; 698fcf3ce44SJohn Forte MAILBOXQ *mbox; 699fcf3ce44SJohn Forte MAILBOX *mb; 700fcf3ce44SJohn Forte uint32_t rval = 1; 701fcf3ce44SJohn Forte uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT; 702fcf3ce44SJohn Forte uint32_t DlToAddr = AifHdr->ImageBase; 703fcf3ce44SJohn Forte uint32_t DlCount; 704fcf3ce44SJohn Forte uint32_t i; 705fcf3ce44SJohn Forte 706fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 707fcf3ce44SJohn Forte "Performing absolute download..."); 708fcf3ce44SJohn Forte 709*291a2b48SSukumar Swaminathan if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT, 710*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 711fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 712fcf3ce44SJohn Forte "Unable to allocate data buffer."); 713fcf3ce44SJohn Forte 714fcf3ce44SJohn Forte return (rval); 715fcf3ce44SJohn Forte } 716*291a2b48SSukumar Swaminathan 717*291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 718*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 719fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 720fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 721fcf3ce44SJohn Forte 722fcf3ce44SJohn Forte kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 723fcf3ce44SJohn Forte 724fcf3ce44SJohn Forte return (rval); 725fcf3ce44SJohn Forte } 726*291a2b48SSukumar Swaminathan 727fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 728fcf3ce44SJohn Forte 729fcf3ce44SJohn Forte Buffer += sizeof (AIF_HDR); 730fcf3ce44SJohn Forte 731*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, "Erasing flash..."); 732fcf3ce44SJohn Forte 733fcf3ce44SJohn Forte if (DwcFile) { 734*291a2b48SSukumar Swaminathan emlxs_format_prog_flash(mb, 0x20000, 0x50000, ERASE_FLASH, 0, 735*291a2b48SSukumar Swaminathan 0, 0, NULL); 736fcf3ce44SJohn Forte } else { 737*291a2b48SSukumar Swaminathan emlxs_format_prog_flash(mb, DlToAddr, DlByteCount, 738*291a2b48SSukumar Swaminathan ERASE_FLASH, 0, 0, 0, NULL); 739fcf3ce44SJohn Forte } 740fcf3ce44SJohn Forte 741*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 742fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 743fcf3ce44SJohn Forte "Unable to erase Flash: Mailbox cmd=%x status=%x", 744fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 745fcf3ce44SJohn Forte 746fcf3ce44SJohn Forte rval = 1; 747fcf3ce44SJohn Forte 748fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 749fcf3ce44SJohn Forte } 750*291a2b48SSukumar Swaminathan 751*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 752*291a2b48SSukumar Swaminathan "Programming flash..."); 753fcf3ce44SJohn Forte 754fcf3ce44SJohn Forte while (DlByteCount) { 755fcf3ce44SJohn Forte 756fcf3ce44SJohn Forte if (DlByteCount > SegSize) { 757fcf3ce44SJohn Forte DlCount = SegSize; 758fcf3ce44SJohn Forte } else { 759fcf3ce44SJohn Forte DlCount = DlByteCount; 760fcf3ce44SJohn Forte } 761fcf3ce44SJohn Forte DlByteCount -= DlCount; 762fcf3ce44SJohn Forte 763fcf3ce44SJohn Forte Dst = (uint32_t *)DataBuffer; 764fcf3ce44SJohn Forte Src = (uint32_t *)Buffer; 765fcf3ce44SJohn Forte 766fcf3ce44SJohn Forte for (i = 0; i < (DlCount / 4); i++) { 767fcf3ce44SJohn Forte *Dst = *Src; 768fcf3ce44SJohn Forte Dst++; 769fcf3ce44SJohn Forte Src++; 770fcf3ce44SJohn Forte } 771fcf3ce44SJohn Forte 772fcf3ce44SJohn Forte WRITE_SLIM_COPY(hba, (uint32_t *)DataBuffer, 773*291a2b48SSukumar Swaminathan (volatile uint32_t *)((volatile char *)hba->slim_addr + 774*291a2b48SSukumar Swaminathan sizeof (MAILBOX)), (DlCount / sizeof (uint32_t))); 775fcf3ce44SJohn Forte 776*291a2b48SSukumar Swaminathan emlxs_format_prog_flash(mb, DlToAddr, DlCount, 777*291a2b48SSukumar Swaminathan PROGRAM_FLASH, (DlByteCount) ? 0 : 1, 0, DlCount, NULL); 778fcf3ce44SJohn Forte 779*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 780*291a2b48SSukumar Swaminathan MBX_SUCCESS) { 781fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 782fcf3ce44SJohn Forte "Unable to program Flash: Mailbox cmd=%x status=%x", 783fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 784fcf3ce44SJohn Forte 785fcf3ce44SJohn Forte rval = 1; 786fcf3ce44SJohn Forte 787fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 788fcf3ce44SJohn Forte } 789*291a2b48SSukumar Swaminathan 790fcf3ce44SJohn Forte Buffer += DlCount; 791fcf3ce44SJohn Forte DlToAddr += DlCount; 792fcf3ce44SJohn Forte } 793fcf3ce44SJohn Forte 794fcf3ce44SJohn Forte bzero((caddr_t)&ImageHdr, sizeof (IMAGE_HDR)); 795fcf3ce44SJohn Forte ImageHdr.Id.Type = FUNC_FIRMWARE; 796fcf3ce44SJohn Forte 797fcf3ce44SJohn Forte switch (MaxRbusSramSize) { 798fcf3ce44SJohn Forte case REDUCED_RBUS_SRAM_CFG: 799fcf3ce44SJohn Forte ImageHdr.Id.Id = REDUCED_SRAM_CFG_PROG_ID; 800fcf3ce44SJohn Forte break; 801fcf3ce44SJohn Forte case FULL_RBUS_SRAM_CFG: 802fcf3ce44SJohn Forte ImageHdr.Id.Id = FULL_SRAM_CFG_PROG_ID; 803fcf3ce44SJohn Forte break; 804fcf3ce44SJohn Forte default: 805fcf3ce44SJohn Forte ImageHdr.Id.Id = OTHER_SRAM_CFG_PROG_ID; 806fcf3ce44SJohn Forte break; 807fcf3ce44SJohn Forte } 808fcf3ce44SJohn Forte 809fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, "Updating params..."); 810fcf3ce44SJohn Forte 811fcf3ce44SJohn Forte if (AbsWakeUpParms) { 812*291a2b48SSukumar Swaminathan rval = 813*291a2b48SSukumar Swaminathan emlxs_update_wakeup_parms(hba, AbsWakeUpParms, 814fcf3ce44SJohn Forte WakeUpParms); 815fcf3ce44SJohn Forte } else { 816*291a2b48SSukumar Swaminathan rval = 817*291a2b48SSukumar Swaminathan emlxs_update_boot_wakeup_parms(hba, WakeUpParms, 818fcf3ce44SJohn Forte &ImageHdr.Id, 1); 819fcf3ce44SJohn Forte } 820fcf3ce44SJohn Forte 821fcf3ce44SJohn Forte EXIT_ABS_DOWNLOAD: 822fcf3ce44SJohn Forte if (DataBuffer) { 823fcf3ce44SJohn Forte kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 824fcf3ce44SJohn Forte } 825*291a2b48SSukumar Swaminathan 826fcf3ce44SJohn Forte if (mbox) { 827fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 828fcf3ce44SJohn Forte } 829*291a2b48SSukumar Swaminathan 830fcf3ce44SJohn Forte return (rval); 831fcf3ce44SJohn Forte 832*291a2b48SSukumar Swaminathan } /* emlxs_start_abs_download() */ 833fcf3ce44SJohn Forte 834fcf3ce44SJohn Forte 835fcf3ce44SJohn Forte /* ARGSUSED */ 836fcf3ce44SJohn Forte static void 837*291a2b48SSukumar Swaminathan emlxs_format_prog_flash(MAILBOX *mb, 838*291a2b48SSukumar Swaminathan uint32_t Base, 839*291a2b48SSukumar Swaminathan uint32_t DlByteCount, 840*291a2b48SSukumar Swaminathan uint32_t Function, 841*291a2b48SSukumar Swaminathan uint32_t Complete, 842*291a2b48SSukumar Swaminathan uint32_t BdeAddress, uint32_t BdeSize, PROG_ID *ProgId) 843fcf3ce44SJohn Forte { 844*291a2b48SSukumar Swaminathan bzero((void *)mb, MAILBOX_CMD_BSIZE); 845fcf3ce44SJohn Forte 846fcf3ce44SJohn Forte if (ProgId) 847fcf3ce44SJohn Forte mb->mbxCommand = MBX_DOWN_LOAD; 848fcf3ce44SJohn Forte else 849fcf3ce44SJohn Forte mb->mbxCommand = MBX_LOAD_SM; 850fcf3ce44SJohn Forte 851fcf3ce44SJohn Forte mb->un.varLdSM.load_cmplt = Complete; 852fcf3ce44SJohn Forte mb->un.varLdSM.method = DL_FROM_SLIM; 853fcf3ce44SJohn Forte mb->un.varLdSM.update_flash = 1; 854fcf3ce44SJohn Forte mb->un.varLdSM.erase_or_prog = Function; 855fcf3ce44SJohn Forte mb->un.varLdSM.dl_to_adr = Base; 856fcf3ce44SJohn Forte mb->un.varLdSM.dl_len = DlByteCount; 857fcf3ce44SJohn Forte 858fcf3ce44SJohn Forte if (BdeSize) { 859fcf3ce44SJohn Forte mb->un.varLdSM.un.dl_from_slim_offset = DL_FROM_SLIM_OFFSET; 860fcf3ce44SJohn Forte } else if (ProgId) { 861fcf3ce44SJohn Forte mb->un.varLdSM.un.prog_id = *ProgId; 862fcf3ce44SJohn Forte } else { 863fcf3ce44SJohn Forte mb->un.varLdSM.un.dl_from_slim_offset = 0; 864fcf3ce44SJohn Forte } 865fcf3ce44SJohn Forte 866fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 867fcf3ce44SJohn Forte 868*291a2b48SSukumar Swaminathan } /* emlxs_format_prog_flash() */ 869fcf3ce44SJohn Forte 870fcf3ce44SJohn Forte 871fcf3ce44SJohn Forte static void 872fcf3ce44SJohn Forte emlxs_format_update_parms(MAILBOX *mb, PWAKE_UP_PARMS WakeUpParms) 873fcf3ce44SJohn Forte { 874fcf3ce44SJohn Forte bzero((void *)mb, MAILBOX_CMD_BSIZE); 875fcf3ce44SJohn Forte 876fcf3ce44SJohn Forte mb->mbxCommand = MBX_UPDATE_CFG; 877fcf3ce44SJohn Forte mb->un.varUpdateCfg.req_type = UPDATE_DATA; 878fcf3ce44SJohn Forte mb->un.varUpdateCfg.region_id = WAKE_UP_PARMS_REGION_ID; 879fcf3ce44SJohn Forte mb->un.varUpdateCfg.entry_len = sizeof (WAKE_UP_PARMS); 880fcf3ce44SJohn Forte mb->un.varUpdateCfg.byte_len = sizeof (WAKE_UP_PARMS); 881fcf3ce44SJohn Forte 882*291a2b48SSukumar Swaminathan bcopy((caddr_t)WakeUpParms, 883*291a2b48SSukumar Swaminathan (caddr_t)&(mb->un.varUpdateCfg.cfg_data), 884fcf3ce44SJohn Forte sizeof (WAKE_UP_PARMS)); 885fcf3ce44SJohn Forte 886*291a2b48SSukumar Swaminathan } /* emlxs_format_update_parms () */ 887fcf3ce44SJohn Forte 888fcf3ce44SJohn Forte 889fcf3ce44SJohn Forte /* ARGSUSED */ 890fcf3ce44SJohn Forte static void 891fcf3ce44SJohn Forte emlxs_format_update_pci_cfg(emlxs_hba_t *hba, MAILBOX *mb, 892fcf3ce44SJohn Forte uint32_t region_id, uint32_t size) 893fcf3ce44SJohn Forte { 894fcf3ce44SJohn Forte bzero((void *)mb, MAILBOX_CMD_BSIZE); 895fcf3ce44SJohn Forte 896fcf3ce44SJohn Forte mb->mbxCommand = MBX_UPDATE_CFG; 897fcf3ce44SJohn Forte mb->un.varUpdateCfg.Vbit = 1; 898fcf3ce44SJohn Forte mb->un.varUpdateCfg.Obit = 1; 899fcf3ce44SJohn Forte mb->un.varUpdateCfg.cfg_data = DL_FROM_SLIM_OFFSET; 900fcf3ce44SJohn Forte mb->un.varUpdateCfg.req_type = UPDATE_DATA; 901fcf3ce44SJohn Forte mb->un.varUpdateCfg.region_id = region_id; 902fcf3ce44SJohn Forte mb->un.varUpdateCfg.entry_len = size; 903fcf3ce44SJohn Forte mb->un.varUpdateCfg.byte_len = size; 904fcf3ce44SJohn Forte 905fcf3ce44SJohn Forte 906*291a2b48SSukumar Swaminathan } /* emlxs_format_update_pci_cfg() */ 907fcf3ce44SJohn Forte 908fcf3ce44SJohn Forte 909fcf3ce44SJohn Forte 910fcf3ce44SJohn Forte static uint32_t 911fcf3ce44SJohn Forte emlxs_update_boot_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 912fcf3ce44SJohn Forte PROG_ID * prog_id, uint32_t proc_erom) 913fcf3ce44SJohn Forte { 914fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 915fcf3ce44SJohn Forte MAILBOX *mb; 916fcf3ce44SJohn Forte MAILBOXQ *mbox; 917fcf3ce44SJohn Forte uint32_t rval = 0; 918fcf3ce44SJohn Forte 919*291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 920*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 921fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 922fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 923fcf3ce44SJohn Forte 924fcf3ce44SJohn Forte return (1); 925fcf3ce44SJohn Forte } 926fcf3ce44SJohn Forte 927*291a2b48SSukumar Swaminathan mb = (MAILBOX *)mbox; 928*291a2b48SSukumar Swaminathan 929*291a2b48SSukumar Swaminathan if (proc_erom && !(hba->model_info.chip & 930fcf3ce44SJohn Forte (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 931fcf3ce44SJohn Forte WakeUpParms->u1.EROM_prog_id = *prog_id; 932fcf3ce44SJohn Forte (void) emlxs_update_exp_rom(hba, WakeUpParms); 933fcf3ce44SJohn Forte } 934*291a2b48SSukumar Swaminathan 935fcf3ce44SJohn Forte WakeUpParms->u0.boot_bios_id = *prog_id; 936fcf3ce44SJohn Forte 937fcf3ce44SJohn Forte emlxs_format_update_parms(mb, WakeUpParms); 938fcf3ce44SJohn Forte 939*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 940fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 941*291a2b48SSukumar Swaminathan "Unable to update boot wakeup parms: Mailbox cmd=%x " 942*291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 943fcf3ce44SJohn Forte 944fcf3ce44SJohn Forte rval = 1; 945fcf3ce44SJohn Forte } 946*291a2b48SSukumar Swaminathan 947fcf3ce44SJohn Forte if (mbox) { 948fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 949fcf3ce44SJohn Forte } 950*291a2b48SSukumar Swaminathan 951fcf3ce44SJohn Forte return (rval); 952fcf3ce44SJohn Forte 953*291a2b48SSukumar Swaminathan } /* emlxs_update_boot_wakeup_parms() */ 954fcf3ce44SJohn Forte 955fcf3ce44SJohn Forte 956fcf3ce44SJohn Forte 957fcf3ce44SJohn Forte static uint32_t 958fcf3ce44SJohn Forte emlxs_update_ff_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 959fcf3ce44SJohn Forte PROG_ID *prog_id) 960fcf3ce44SJohn Forte { 961fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 962fcf3ce44SJohn Forte uint32_t rval = 0; 963fcf3ce44SJohn Forte MAILBOXQ *mbox; 964fcf3ce44SJohn Forte MAILBOX *mb; 965fcf3ce44SJohn Forte 966*291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 967*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 968fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 969fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 970fcf3ce44SJohn Forte 971fcf3ce44SJohn Forte return (1); 972fcf3ce44SJohn Forte } 973*291a2b48SSukumar Swaminathan 974fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 975fcf3ce44SJohn Forte 976fcf3ce44SJohn Forte WakeUpParms->prog_id = *prog_id; 977fcf3ce44SJohn Forte 978fcf3ce44SJohn Forte emlxs_format_update_parms(mb, WakeUpParms); 979fcf3ce44SJohn Forte 980*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 981fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 982*291a2b48SSukumar Swaminathan "Unable to update wakeup parameters: Mailbox cmd=%x " 983*291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 984fcf3ce44SJohn Forte 985fcf3ce44SJohn Forte rval = 1; 986fcf3ce44SJohn Forte } 987*291a2b48SSukumar Swaminathan 988fcf3ce44SJohn Forte if (mbox) { 989fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 990fcf3ce44SJohn Forte } 991*291a2b48SSukumar Swaminathan 992fcf3ce44SJohn Forte return (rval); 993fcf3ce44SJohn Forte 994*291a2b48SSukumar Swaminathan } /* emlxs_update_ff_wakeup_parms() */ 995fcf3ce44SJohn Forte 996fcf3ce44SJohn Forte 997fcf3ce44SJohn Forte static uint32_t 998fcf3ce44SJohn Forte emlxs_update_sli1_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 999*291a2b48SSukumar Swaminathan PROG_ID * prog_id) 1000fcf3ce44SJohn Forte { 1001fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1002fcf3ce44SJohn Forte uint32_t rval = 0; 1003fcf3ce44SJohn Forte MAILBOXQ *mbox; 1004fcf3ce44SJohn Forte MAILBOX *mb; 1005fcf3ce44SJohn Forte 1006*291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1007*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 1008fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1009fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 1010fcf3ce44SJohn Forte 1011fcf3ce44SJohn Forte return (1); 1012fcf3ce44SJohn Forte } 1013*291a2b48SSukumar Swaminathan 1014fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 1015fcf3ce44SJohn Forte 1016fcf3ce44SJohn Forte WakeUpParms->sli1_prog_id = *prog_id; 1017fcf3ce44SJohn Forte 1018fcf3ce44SJohn Forte emlxs_format_update_parms(mb, WakeUpParms); 1019fcf3ce44SJohn Forte 1020*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 1021fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1022*291a2b48SSukumar Swaminathan "Unable to update wakeup parameters. Mailbox cmd=%x " 1023*291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 1024fcf3ce44SJohn Forte 1025fcf3ce44SJohn Forte rval = 1; 1026fcf3ce44SJohn Forte } 1027*291a2b48SSukumar Swaminathan 1028fcf3ce44SJohn Forte if (mbox) { 1029fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 1030fcf3ce44SJohn Forte } 1031*291a2b48SSukumar Swaminathan 1032fcf3ce44SJohn Forte return (rval); 1033fcf3ce44SJohn Forte 1034*291a2b48SSukumar Swaminathan } /* emlxs_update_sli1_wakeup_parms() */ 1035fcf3ce44SJohn Forte 1036fcf3ce44SJohn Forte 1037fcf3ce44SJohn Forte static uint32_t 1038fcf3ce44SJohn Forte emlxs_update_sli2_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 1039*291a2b48SSukumar Swaminathan PROG_ID * prog_id) 1040fcf3ce44SJohn Forte { 1041fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1042fcf3ce44SJohn Forte uint32_t rval = 0; 1043fcf3ce44SJohn Forte MAILBOXQ *mbox; 1044fcf3ce44SJohn Forte MAILBOX *mb; 1045fcf3ce44SJohn Forte 1046*291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1047*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 1048fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1049fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 1050fcf3ce44SJohn Forte 1051fcf3ce44SJohn Forte return (1); 1052fcf3ce44SJohn Forte } 1053*291a2b48SSukumar Swaminathan 1054fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 1055fcf3ce44SJohn Forte 1056fcf3ce44SJohn Forte WakeUpParms->sli2_prog_id = *prog_id; 1057fcf3ce44SJohn Forte 1058fcf3ce44SJohn Forte emlxs_format_update_parms(mb, WakeUpParms); 1059fcf3ce44SJohn Forte 1060*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 1061fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1062*291a2b48SSukumar Swaminathan "Unable to update wakeup parameters. Mailbox cmd=%x " 1063*291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 1064fcf3ce44SJohn Forte 1065fcf3ce44SJohn Forte rval = 1; 1066fcf3ce44SJohn Forte } 1067*291a2b48SSukumar Swaminathan 1068fcf3ce44SJohn Forte if (mbox) { 1069fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 1070fcf3ce44SJohn Forte } 1071*291a2b48SSukumar Swaminathan 1072fcf3ce44SJohn Forte return (rval); 1073fcf3ce44SJohn Forte 1074*291a2b48SSukumar Swaminathan } /* emlxs_update_sli2_wakeup_parms() */ 1075fcf3ce44SJohn Forte 1076fcf3ce44SJohn Forte 1077fcf3ce44SJohn Forte static uint32_t 1078fcf3ce44SJohn Forte emlxs_update_sli3_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 1079fcf3ce44SJohn Forte PROG_ID *prog_id) 1080fcf3ce44SJohn Forte { 1081fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1082fcf3ce44SJohn Forte uint32_t rval = 0; 1083fcf3ce44SJohn Forte MAILBOXQ *mbox; 1084fcf3ce44SJohn Forte MAILBOX *mb; 1085fcf3ce44SJohn Forte 1086*291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1087*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 1088fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1089fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 1090fcf3ce44SJohn Forte 1091fcf3ce44SJohn Forte return (1); 1092fcf3ce44SJohn Forte } 1093*291a2b48SSukumar Swaminathan 1094fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 1095fcf3ce44SJohn Forte 1096fcf3ce44SJohn Forte WakeUpParms->sli3_prog_id = *prog_id; 1097fcf3ce44SJohn Forte 1098fcf3ce44SJohn Forte emlxs_format_update_parms(mb, WakeUpParms); 1099fcf3ce44SJohn Forte 1100*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 1101fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1102*291a2b48SSukumar Swaminathan "Unable to update wakeup parameters. Mailbox cmd=%x " 1103*291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 1104fcf3ce44SJohn Forte 1105fcf3ce44SJohn Forte rval = 1; 1106fcf3ce44SJohn Forte } 1107*291a2b48SSukumar Swaminathan 1108fcf3ce44SJohn Forte if (mbox) { 1109fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 1110fcf3ce44SJohn Forte } 1111*291a2b48SSukumar Swaminathan 1112fcf3ce44SJohn Forte return (rval); 1113fcf3ce44SJohn Forte 1114*291a2b48SSukumar Swaminathan } /* emlxs_update_sli3_wakeup_parms() */ 1115fcf3ce44SJohn Forte 1116fcf3ce44SJohn Forte 1117fcf3ce44SJohn Forte static uint32_t 1118fcf3ce44SJohn Forte emlxs_update_sli4_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 1119fcf3ce44SJohn Forte PROG_ID *prog_id) 1120fcf3ce44SJohn Forte { 1121fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1122fcf3ce44SJohn Forte uint32_t rval = 0; 1123fcf3ce44SJohn Forte MAILBOXQ *mbox; 1124fcf3ce44SJohn Forte MAILBOX *mb; 1125fcf3ce44SJohn Forte 1126*291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1127*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 1128fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1129fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 1130fcf3ce44SJohn Forte 1131fcf3ce44SJohn Forte return (1); 1132fcf3ce44SJohn Forte } 1133*291a2b48SSukumar Swaminathan 1134fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 1135fcf3ce44SJohn Forte 1136fcf3ce44SJohn Forte WakeUpParms->sli4_prog_id = *prog_id; 1137fcf3ce44SJohn Forte 1138fcf3ce44SJohn Forte emlxs_format_update_parms(mb, WakeUpParms); 1139fcf3ce44SJohn Forte 1140*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 1141fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1142*291a2b48SSukumar Swaminathan "Unable to update wakeup parameters. Mailbox cmd=%x " 1143*291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 1144fcf3ce44SJohn Forte 1145fcf3ce44SJohn Forte rval = 1; 1146fcf3ce44SJohn Forte } 1147*291a2b48SSukumar Swaminathan 1148fcf3ce44SJohn Forte if (mbox) { 1149fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 1150fcf3ce44SJohn Forte } 1151*291a2b48SSukumar Swaminathan 1152fcf3ce44SJohn Forte return (rval); 1153fcf3ce44SJohn Forte 1154*291a2b48SSukumar Swaminathan } /* emlxs_update_sli4_wakeup_parms() */ 1155fcf3ce44SJohn Forte 1156fcf3ce44SJohn Forte 1157fcf3ce44SJohn Forte /* ARGSUSED */ 1158fcf3ce44SJohn Forte static uint32_t 1159*291a2b48SSukumar Swaminathan emlxs_start_rel_download(emlxs_hba_t *hba, 1160*291a2b48SSukumar Swaminathan PIMAGE_HDR ImageHdr, 1161*291a2b48SSukumar Swaminathan caddr_t Buffer, 1162*291a2b48SSukumar Swaminathan PWAKE_UP_PARMS WakeUpParms, 1163fcf3ce44SJohn Forte uint32_t MaxRbusSramSize, uint32_t MaxIbusSramSize) 1164fcf3ce44SJohn Forte { 1165fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1166fcf3ce44SJohn Forte MAILBOXQ *mbox; 1167fcf3ce44SJohn Forte MAILBOX *mb; 1168fcf3ce44SJohn Forte uint32_t *Src; 1169fcf3ce44SJohn Forte uint32_t *Dst; 1170fcf3ce44SJohn Forte caddr_t DataBuffer = NULL; 1171fcf3ce44SJohn Forte uint32_t rval = 1; 1172fcf3ce44SJohn Forte uint32_t DlByteCount = ImageHdr->BlockSize; 1173fcf3ce44SJohn Forte uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT; 1174fcf3ce44SJohn Forte uint32_t DlCount; 1175fcf3ce44SJohn Forte uint32_t i; 1176fcf3ce44SJohn Forte 1177fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1178fcf3ce44SJohn Forte "Performing relative download..."); 1179fcf3ce44SJohn Forte 1180*291a2b48SSukumar Swaminathan if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT, 1181*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 1182fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1183fcf3ce44SJohn Forte "Unable to allocate data buffer."); 1184fcf3ce44SJohn Forte 1185fcf3ce44SJohn Forte return (rval); 1186fcf3ce44SJohn Forte } 1187*291a2b48SSukumar Swaminathan 1188*291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1189*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 1190fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1191fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 1192fcf3ce44SJohn Forte 1193fcf3ce44SJohn Forte kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 1194fcf3ce44SJohn Forte 1195fcf3ce44SJohn Forte return (rval); 1196fcf3ce44SJohn Forte } 1197*291a2b48SSukumar Swaminathan 1198fcf3ce44SJohn Forte if (ImageHdr->Id.Type == FUNC_FIRMWARE) { 1199fcf3ce44SJohn Forte switch (MaxRbusSramSize) { 1200fcf3ce44SJohn Forte case REDUCED_RBUS_SRAM_CFG: 1201fcf3ce44SJohn Forte if (ImageHdr->Id.Id != REDUCED_SRAM_CFG_PROG_ID) { 1202*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 1203*291a2b48SSukumar Swaminathan &emlxs_image_bad_msg, 1204fcf3ce44SJohn Forte "Invalid header id."); 1205fcf3ce44SJohn Forte 1206fcf3ce44SJohn Forte return (1); 1207fcf3ce44SJohn Forte } 1208fcf3ce44SJohn Forte break; 1209fcf3ce44SJohn Forte case FULL_RBUS_SRAM_CFG: 1210fcf3ce44SJohn Forte if (ImageHdr->Id.Id != FULL_SRAM_CFG_PROG_ID) { 1211*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 1212*291a2b48SSukumar Swaminathan &emlxs_image_bad_msg, 1213fcf3ce44SJohn Forte "Invalid header id."); 1214fcf3ce44SJohn Forte 1215fcf3ce44SJohn Forte return (1); 1216fcf3ce44SJohn Forte } 1217fcf3ce44SJohn Forte break; 1218fcf3ce44SJohn Forte default: 1219fcf3ce44SJohn Forte if (ImageHdr->Id.Id != OTHER_SRAM_CFG_PROG_ID) { 1220*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 1221*291a2b48SSukumar Swaminathan &emlxs_image_bad_msg, 1222fcf3ce44SJohn Forte "Invalid header id."); 1223fcf3ce44SJohn Forte 1224fcf3ce44SJohn Forte return (1); 1225fcf3ce44SJohn Forte } 1226fcf3ce44SJohn Forte break; 1227fcf3ce44SJohn Forte } 1228fcf3ce44SJohn Forte } 1229*291a2b48SSukumar Swaminathan 1230fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 1231fcf3ce44SJohn Forte 1232*291a2b48SSukumar Swaminathan emlxs_format_prog_flash(mb, 0, DlByteCount, ERASE_FLASH, 0, 0, 0, 1233*291a2b48SSukumar Swaminathan &ImageHdr->Id); 1234fcf3ce44SJohn Forte 1235fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, "Erasing flash..."); 1236fcf3ce44SJohn Forte 1237*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 1238fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1239fcf3ce44SJohn Forte "Unable to erase flash. Mailbox cmd=%x status=%x", 1240fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 1241fcf3ce44SJohn Forte 1242fcf3ce44SJohn Forte rval = 1; 1243fcf3ce44SJohn Forte 1244fcf3ce44SJohn Forte goto EXIT_REL_DOWNLOAD; 1245fcf3ce44SJohn Forte } 1246*291a2b48SSukumar Swaminathan 1247*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1248*291a2b48SSukumar Swaminathan "Programming flash..."); 1249fcf3ce44SJohn Forte 1250fcf3ce44SJohn Forte while (DlByteCount) { 1251fcf3ce44SJohn Forte if (DlByteCount > SegSize) { 1252fcf3ce44SJohn Forte DlCount = SegSize; 1253fcf3ce44SJohn Forte } else { 1254fcf3ce44SJohn Forte DlCount = DlByteCount; 1255fcf3ce44SJohn Forte } 1256fcf3ce44SJohn Forte DlByteCount -= DlCount; 1257fcf3ce44SJohn Forte 1258fcf3ce44SJohn Forte Dst = (uint32_t *)DataBuffer; 1259fcf3ce44SJohn Forte Src = (uint32_t *)Buffer; 1260fcf3ce44SJohn Forte 1261fcf3ce44SJohn Forte for (i = 0; i < (DlCount / 4); i++) { 1262fcf3ce44SJohn Forte *Dst = *Src; 1263fcf3ce44SJohn Forte Dst++; 1264fcf3ce44SJohn Forte Src++; 1265fcf3ce44SJohn Forte } 1266fcf3ce44SJohn Forte 1267fcf3ce44SJohn Forte WRITE_SLIM_COPY(hba, (uint32_t *)DataBuffer, 1268*291a2b48SSukumar Swaminathan (volatile uint32_t *)((volatile char *)hba->slim_addr + 1269*291a2b48SSukumar Swaminathan sizeof (MAILBOX)), (DlCount / sizeof (uint32_t))); 1270fcf3ce44SJohn Forte 1271*291a2b48SSukumar Swaminathan emlxs_format_prog_flash(mb, 1272*291a2b48SSukumar Swaminathan 0, 1273*291a2b48SSukumar Swaminathan DlCount, 1274*291a2b48SSukumar Swaminathan PROGRAM_FLASH, 1275fcf3ce44SJohn Forte (DlByteCount) ? 0 : 1, 0, DlCount, &ImageHdr->Id); 1276fcf3ce44SJohn Forte 1277*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 1278*291a2b48SSukumar Swaminathan MBX_SUCCESS) { 1279fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1280fcf3ce44SJohn Forte "Unable to program flash. Mailbox cmd=%x status=%x", 1281fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 1282fcf3ce44SJohn Forte 1283fcf3ce44SJohn Forte rval = 1; 1284fcf3ce44SJohn Forte 1285fcf3ce44SJohn Forte goto EXIT_REL_DOWNLOAD; 1286fcf3ce44SJohn Forte } 1287*291a2b48SSukumar Swaminathan 1288fcf3ce44SJohn Forte Buffer += DlCount; 1289fcf3ce44SJohn Forte } 1290fcf3ce44SJohn Forte 1291fcf3ce44SJohn Forte switch (ImageHdr->Id.Type) { 1292fcf3ce44SJohn Forte case TEST_PROGRAM: 1293fcf3ce44SJohn Forte rval = 0; 1294fcf3ce44SJohn Forte break; 1295fcf3ce44SJohn Forte 1296fcf3ce44SJohn Forte case FUNC_FIRMWARE: 1297fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1298fcf3ce44SJohn Forte "FF: Updating parms..."); 1299*291a2b48SSukumar Swaminathan rval = 1300*291a2b48SSukumar Swaminathan emlxs_update_ff_wakeup_parms(hba, WakeUpParms, 1301fcf3ce44SJohn Forte &ImageHdr->Id); 1302fcf3ce44SJohn Forte break; 1303fcf3ce44SJohn Forte 1304fcf3ce44SJohn Forte case BOOT_BIOS: 1305fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1306fcf3ce44SJohn Forte "BOOT: Updating parms..."); 1307*291a2b48SSukumar Swaminathan rval = 1308*291a2b48SSukumar Swaminathan emlxs_update_boot_wakeup_parms(hba, WakeUpParms, 1309fcf3ce44SJohn Forte &ImageHdr->Id, 1); 1310fcf3ce44SJohn Forte break; 1311fcf3ce44SJohn Forte 1312fcf3ce44SJohn Forte case SLI1_OVERLAY: 1313fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1314fcf3ce44SJohn Forte "SLI1: Updating parms..."); 1315*291a2b48SSukumar Swaminathan rval = 1316*291a2b48SSukumar Swaminathan emlxs_update_sli1_wakeup_parms(hba, WakeUpParms, 1317fcf3ce44SJohn Forte &ImageHdr->Id); 1318fcf3ce44SJohn Forte break; 1319fcf3ce44SJohn Forte 1320fcf3ce44SJohn Forte case SLI2_OVERLAY: 1321fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1322fcf3ce44SJohn Forte "SLI2: Updating parms..."); 1323*291a2b48SSukumar Swaminathan rval = 1324*291a2b48SSukumar Swaminathan emlxs_update_sli2_wakeup_parms(hba, WakeUpParms, 1325fcf3ce44SJohn Forte &ImageHdr->Id); 1326fcf3ce44SJohn Forte break; 1327fcf3ce44SJohn Forte 1328fcf3ce44SJohn Forte case SLI3_OVERLAY: 1329fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1330fcf3ce44SJohn Forte "SLI3: Updating parms..."); 1331*291a2b48SSukumar Swaminathan rval = 1332*291a2b48SSukumar Swaminathan emlxs_update_sli3_wakeup_parms(hba, WakeUpParms, 1333fcf3ce44SJohn Forte &ImageHdr->Id); 1334fcf3ce44SJohn Forte break; 1335fcf3ce44SJohn Forte 1336fcf3ce44SJohn Forte case SLI4_OVERLAY: 1337fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 1338fcf3ce44SJohn Forte "SLI4: Updating parms..."); 1339*291a2b48SSukumar Swaminathan rval = 1340*291a2b48SSukumar Swaminathan emlxs_update_sli4_wakeup_parms(hba, WakeUpParms, 1341fcf3ce44SJohn Forte &ImageHdr->Id); 1342fcf3ce44SJohn Forte break; 1343fcf3ce44SJohn Forte 1344fcf3ce44SJohn Forte default: 1345fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 1346*291a2b48SSukumar Swaminathan "Image type not supported. Type=%x", ImageHdr->Id.Type); 1347fcf3ce44SJohn Forte 1348fcf3ce44SJohn Forte break; 1349fcf3ce44SJohn Forte } 1350fcf3ce44SJohn Forte 1351fcf3ce44SJohn Forte EXIT_REL_DOWNLOAD: 1352fcf3ce44SJohn Forte if (DataBuffer) { 1353fcf3ce44SJohn Forte kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 1354fcf3ce44SJohn Forte } 1355*291a2b48SSukumar Swaminathan 1356fcf3ce44SJohn Forte if (mbox) { 1357fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 1358fcf3ce44SJohn Forte } 1359*291a2b48SSukumar Swaminathan 1360fcf3ce44SJohn Forte return (rval); 1361fcf3ce44SJohn Forte 1362*291a2b48SSukumar Swaminathan } /* emlxs_start_rel_download() */ 1363fcf3ce44SJohn Forte 1364fcf3ce44SJohn Forte 1365fcf3ce44SJohn Forte #define FLASH_POLLING_BIT 0x80 1366fcf3ce44SJohn Forte #define FLASH_ERROR_BIT 0x20 1367fcf3ce44SJohn Forte 1368*291a2b48SSukumar Swaminathan typedef struct _flash_t 1369*291a2b48SSukumar Swaminathan { 1370*291a2b48SSukumar Swaminathan uint32_t offset; 1371*291a2b48SSukumar Swaminathan uint8_t val; 1372fcf3ce44SJohn Forte } flash_t; 1373fcf3ce44SJohn Forte 1374fcf3ce44SJohn Forte 1375fcf3ce44SJohn Forte 1376fcf3ce44SJohn Forte static uint32_t 1377*291a2b48SSukumar Swaminathan emlxs_write_fcode_flash(emlxs_hba_t *hba, 1378*291a2b48SSukumar Swaminathan PIMAGE_HDR ImageHdr, caddr_t Buffer) 1379fcf3ce44SJohn Forte { 1380fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1381fcf3ce44SJohn Forte uint8_t bb; 1382fcf3ce44SJohn Forte uint8_t cc; 1383fcf3ce44SJohn Forte uint8_t *src; 1384fcf3ce44SJohn Forte uint32_t DlByteCount = ImageHdr->BlockSize; 1385fcf3ce44SJohn Forte uint32_t i; 1386fcf3ce44SJohn Forte uint32_t j; 1387fcf3ce44SJohn Forte uint32_t k; 1388fcf3ce44SJohn Forte 1389*291a2b48SSukumar Swaminathan flash_t wr[3] = { 1390fcf3ce44SJohn Forte {0x555, 0xaa}, 1391fcf3ce44SJohn Forte {0x2aa, 0x55}, 1392fcf3ce44SJohn Forte {0x555, 0xa0} 1393fcf3ce44SJohn Forte }; 1394fcf3ce44SJohn Forte 1395fcf3ce44SJohn Forte /* Load Fcode */ 1396fcf3ce44SJohn Forte src = (uint8_t *)Buffer + sizeof (IMAGE_HDR); 1397fcf3ce44SJohn Forte for (i = 0; i < DlByteCount; i++) { 1398fcf3ce44SJohn Forte for (k = 0; k < 3; k++) { 1399fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, wr[k].offset, wr[k].val); 1400fcf3ce44SJohn Forte } 1401fcf3ce44SJohn Forte 1402fcf3ce44SJohn Forte /* Reverse Endian word alignment */ 1403fcf3ce44SJohn Forte j = (i & 3) ^ 3; 1404fcf3ce44SJohn Forte 1405fcf3ce44SJohn Forte bb = src[j]; 1406fcf3ce44SJohn Forte 1407fcf3ce44SJohn Forte if (j == 0) { 1408fcf3ce44SJohn Forte src += 4; 1409fcf3ce44SJohn Forte } 1410*291a2b48SSukumar Swaminathan 1411fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, i, bb); 1412fcf3ce44SJohn Forte 1413fcf3ce44SJohn Forte /* check for complete */ 1414fcf3ce44SJohn Forte for (;;) { 1415fcf3ce44SJohn Forte DELAYUS(20); 1416fcf3ce44SJohn Forte 1417fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, i); 1418fcf3ce44SJohn Forte 1419fcf3ce44SJohn Forte /* If data matches then continue */ 1420fcf3ce44SJohn Forte if (cc == bb) { 1421fcf3ce44SJohn Forte break; 1422fcf3ce44SJohn Forte } 1423*291a2b48SSukumar Swaminathan 1424*291a2b48SSukumar Swaminathan /* Polling bit will be inverse final value */ 1425*291a2b48SSukumar Swaminathan /* while active */ 1426fcf3ce44SJohn Forte if ((cc ^ bb) & FLASH_POLLING_BIT) { 1427fcf3ce44SJohn Forte /* Still busy */ 1428fcf3ce44SJohn Forte 1429fcf3ce44SJohn Forte /* Check for error bit */ 1430fcf3ce44SJohn Forte if (cc & FLASH_ERROR_BIT) { 1431fcf3ce44SJohn Forte /* Read data one more time */ 1432fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, i); 1433fcf3ce44SJohn Forte 1434fcf3ce44SJohn Forte /* Check if data matches */ 1435fcf3ce44SJohn Forte if (cc == bb) { 1436fcf3ce44SJohn Forte break; 1437fcf3ce44SJohn Forte } 1438*291a2b48SSukumar Swaminathan 1439fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 1440fcf3ce44SJohn Forte &emlxs_download_failed_msg, 1441fcf3ce44SJohn Forte "FCode write error: offset:%x " 1442*291a2b48SSukumar Swaminathan "wrote:%x read:%x\n", i, bb, cc); 1443fcf3ce44SJohn Forte 1444fcf3ce44SJohn Forte return (1); 1445fcf3ce44SJohn Forte } 1446fcf3ce44SJohn Forte } 1447fcf3ce44SJohn Forte } 1448fcf3ce44SJohn Forte } 1449fcf3ce44SJohn Forte 1450fcf3ce44SJohn Forte /* Load Header */ 1451fcf3ce44SJohn Forte src = (uint8_t *)ImageHdr; 1452fcf3ce44SJohn Forte 1453fcf3ce44SJohn Forte for (i = (0xFFFF - sizeof (IMAGE_HDR)); i < 0xFFFF; i++) { 1454fcf3ce44SJohn Forte for (k = 0; k < 3; k++) { 1455fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, wr[k].offset, wr[k].val); 1456fcf3ce44SJohn Forte } 1457fcf3ce44SJohn Forte 1458fcf3ce44SJohn Forte /* Reverse Endian word alignment */ 1459fcf3ce44SJohn Forte j = (i & 3) ^ 3; 1460fcf3ce44SJohn Forte 1461fcf3ce44SJohn Forte bb = src[j]; 1462fcf3ce44SJohn Forte 1463fcf3ce44SJohn Forte if (j == 0) { 1464fcf3ce44SJohn Forte src += 4; 1465fcf3ce44SJohn Forte } 1466*291a2b48SSukumar Swaminathan 1467fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, i, bb); 1468fcf3ce44SJohn Forte 1469fcf3ce44SJohn Forte /* check for complete */ 1470fcf3ce44SJohn Forte for (;;) { 1471fcf3ce44SJohn Forte DELAYUS(20); 1472fcf3ce44SJohn Forte 1473fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, i); 1474fcf3ce44SJohn Forte 1475fcf3ce44SJohn Forte /* If data matches then continue */ 1476fcf3ce44SJohn Forte if (cc == bb) { 1477fcf3ce44SJohn Forte break; 1478fcf3ce44SJohn Forte } 1479*291a2b48SSukumar Swaminathan 1480*291a2b48SSukumar Swaminathan /* Polling bit will be inverse final value */ 1481*291a2b48SSukumar Swaminathan /* while active */ 1482fcf3ce44SJohn Forte if ((cc ^ bb) & FLASH_POLLING_BIT) { 1483fcf3ce44SJohn Forte /* Still busy */ 1484fcf3ce44SJohn Forte 1485fcf3ce44SJohn Forte /* Check for error bit */ 1486fcf3ce44SJohn Forte if (cc & FLASH_ERROR_BIT) { 1487fcf3ce44SJohn Forte /* Read data one more time */ 1488fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, i); 1489fcf3ce44SJohn Forte 1490fcf3ce44SJohn Forte /* Check if data matches */ 1491fcf3ce44SJohn Forte if (cc == bb) { 1492fcf3ce44SJohn Forte break; 1493fcf3ce44SJohn Forte } 1494*291a2b48SSukumar Swaminathan 1495fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 1496fcf3ce44SJohn Forte &emlxs_download_failed_msg, 1497fcf3ce44SJohn Forte "FCode write error: offset:%x " 1498*291a2b48SSukumar Swaminathan "wrote:%x read:%x\n", i, bb, cc); 1499fcf3ce44SJohn Forte 1500fcf3ce44SJohn Forte return (1); 1501fcf3ce44SJohn Forte } 1502fcf3ce44SJohn Forte } 1503fcf3ce44SJohn Forte } 1504fcf3ce44SJohn Forte } 1505fcf3ce44SJohn Forte 1506*291a2b48SSukumar Swaminathan 1507fcf3ce44SJohn Forte return (0); 1508fcf3ce44SJohn Forte 1509*291a2b48SSukumar Swaminathan } /* emlxs_write_fcode_flash() */ 1510fcf3ce44SJohn Forte 1511fcf3ce44SJohn Forte 1512fcf3ce44SJohn Forte 1513fcf3ce44SJohn Forte static uint32_t 1514fcf3ce44SJohn Forte emlxs_erase_fcode_flash(emlxs_hba_t *hba) 1515fcf3ce44SJohn Forte { 1516fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1517fcf3ce44SJohn Forte int32_t i, j; 1518fcf3ce44SJohn Forte uint8_t cc; 1519fcf3ce44SJohn Forte uint32_t offset; 1520fcf3ce44SJohn Forte 1521*291a2b48SSukumar Swaminathan flash_t ef[6] = { 1522fcf3ce44SJohn Forte {0x555, 0xaa}, 1523fcf3ce44SJohn Forte {0x2aa, 0x55}, 1524fcf3ce44SJohn Forte {0x555, 0x80}, 1525fcf3ce44SJohn Forte {0x555, 0xaa}, 1526fcf3ce44SJohn Forte {0x2aa, 0x55}, 1527fcf3ce44SJohn Forte {0x555, 0x10} 1528fcf3ce44SJohn Forte }; 1529fcf3ce44SJohn Forte 1530fcf3ce44SJohn Forte /* Auto select */ 1531*291a2b48SSukumar Swaminathan flash_t as[3] = { 1532fcf3ce44SJohn Forte {0x555, 0xaa}, 1533fcf3ce44SJohn Forte {0x2aa, 0x55}, 1534fcf3ce44SJohn Forte {0x555, 0x90} 1535fcf3ce44SJohn Forte }; 1536fcf3ce44SJohn Forte 1537fcf3ce44SJohn Forte 1538fcf3ce44SJohn Forte /* Check Manufacturers Code */ 1539fcf3ce44SJohn Forte for (i = 0; i < 3; i++) { 1540fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, as[i].offset, as[i].val); 1541fcf3ce44SJohn Forte } 1542fcf3ce44SJohn Forte 1543fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, 0); 1544fcf3ce44SJohn Forte 1545fcf3ce44SJohn Forte /* Check Device Code */ 1546fcf3ce44SJohn Forte for (i = 0; i < 3; i++) { 1547fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, as[i].offset, as[i].val); 1548fcf3ce44SJohn Forte } 1549fcf3ce44SJohn Forte 1550fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, 1); 1551fcf3ce44SJohn Forte 1552fcf3ce44SJohn Forte 1553fcf3ce44SJohn Forte /* Check block protections (up to 4 16K blocks = 64K) */ 1554fcf3ce44SJohn Forte for (j = 0; j < 4; j++) { 1555fcf3ce44SJohn Forte for (i = 0; i < 3; i++) { 1556fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, as[i].offset, as[i].val); 1557fcf3ce44SJohn Forte } 1558fcf3ce44SJohn Forte 1559fcf3ce44SJohn Forte offset = (j << 14) | 0x2; 1560fcf3ce44SJohn Forte 1561fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, offset); 1562fcf3ce44SJohn Forte 1563fcf3ce44SJohn Forte if (cc == 0x01) { 1564fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1565fcf3ce44SJohn Forte "Block %d is protected and can't be erased.", j); 1566fcf3ce44SJohn Forte } 1567fcf3ce44SJohn Forte } 1568fcf3ce44SJohn Forte 1569fcf3ce44SJohn Forte /* Write erase flash sequence */ 1570fcf3ce44SJohn Forte for (i = 0; i < 6; i++) { 1571fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, ef[i].offset, ef[i].val); 1572fcf3ce44SJohn Forte } 1573fcf3ce44SJohn Forte 1574fcf3ce44SJohn Forte /* check for complete */ 1575fcf3ce44SJohn Forte for (;;) { 1576fcf3ce44SJohn Forte /* Delay 3 seconds */ 1577fcf3ce44SJohn Forte DELAYMS(3000); 1578fcf3ce44SJohn Forte 1579fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, 0); 1580fcf3ce44SJohn Forte 1581fcf3ce44SJohn Forte 1582fcf3ce44SJohn Forte /* If data matches then continue; */ 1583fcf3ce44SJohn Forte if (cc == 0xff) { 1584fcf3ce44SJohn Forte break; 1585fcf3ce44SJohn Forte } 1586*291a2b48SSukumar Swaminathan 1587fcf3ce44SJohn Forte /* Polling bit will be inverse final value while active */ 1588fcf3ce44SJohn Forte if ((cc ^ 0xff) & FLASH_POLLING_BIT) { 1589fcf3ce44SJohn Forte /* Still busy */ 1590fcf3ce44SJohn Forte 1591fcf3ce44SJohn Forte /* Check for error bit */ 1592fcf3ce44SJohn Forte if (cc & FLASH_ERROR_BIT) { 1593fcf3ce44SJohn Forte /* Read data one more time */ 1594fcf3ce44SJohn Forte cc = SBUS_READ_FLASH_COPY(hba, 0); 1595fcf3ce44SJohn Forte 1596fcf3ce44SJohn Forte /* Check if data matches */ 1597fcf3ce44SJohn Forte if (cc == 0xff) { 1598fcf3ce44SJohn Forte break; 1599fcf3ce44SJohn Forte } 1600*291a2b48SSukumar Swaminathan 1601fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 1602fcf3ce44SJohn Forte &emlxs_download_failed_msg, 1603*291a2b48SSukumar Swaminathan "FCode write error: offset:%x wrote:%x " 1604*291a2b48SSukumar Swaminathan "read:%x\n", i, 0xff, cc); 1605fcf3ce44SJohn Forte 1606fcf3ce44SJohn Forte return (1); 1607fcf3ce44SJohn Forte } 1608fcf3ce44SJohn Forte } 1609fcf3ce44SJohn Forte } 1610fcf3ce44SJohn Forte 1611fcf3ce44SJohn Forte return (0); 1612fcf3ce44SJohn Forte 1613*291a2b48SSukumar Swaminathan } /* emlxs_erase_fcode_flash() */ 1614fcf3ce44SJohn Forte 1615fcf3ce44SJohn Forte 1616fcf3ce44SJohn Forte extern uint32_t 1617fcf3ce44SJohn Forte emlxs_get_load_list(emlxs_hba_t *hba, PROG_ID *load_list) 1618fcf3ce44SJohn Forte { 1619fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1620fcf3ce44SJohn Forte LOAD_ENTRY *LoadEntry; 1621fcf3ce44SJohn Forte LOAD_LIST *LoadList = NULL; 1622fcf3ce44SJohn Forte uint32_t i; 1623fcf3ce44SJohn Forte uint32_t rval = 0; 1624fcf3ce44SJohn Forte 1625fcf3ce44SJohn Forte bzero(load_list, (sizeof (PROG_ID) * MAX_LOAD_ENTRY)); 1626fcf3ce44SJohn Forte 1627*291a2b48SSukumar Swaminathan if ((LoadList = (LOAD_LIST *)kmem_zalloc(sizeof (LOAD_LIST), 1628*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 1629fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1630fcf3ce44SJohn Forte "Unable to allocate LOADLIST buffer."); 1631fcf3ce44SJohn Forte 1632fcf3ce44SJohn Forte rval = 1; 1633fcf3ce44SJohn Forte goto done; 1634fcf3ce44SJohn Forte } 1635*291a2b48SSukumar Swaminathan 1636fcf3ce44SJohn Forte if (emlxs_read_load_list(hba, LoadList)) { 1637fcf3ce44SJohn Forte rval = 1; 1638fcf3ce44SJohn Forte goto done; 1639fcf3ce44SJohn Forte } 1640*291a2b48SSukumar Swaminathan 1641fcf3ce44SJohn Forte for (i = 0; i < LoadList->entry_cnt; i++) { 1642fcf3ce44SJohn Forte LoadEntry = &LoadList->load_entry[i]; 1643fcf3ce44SJohn Forte if ((LoadEntry->un.wd[0] != 0) && 1644fcf3ce44SJohn Forte (LoadEntry->un.wd[0] != 0xffffffff)) { 1645fcf3ce44SJohn Forte load_list[i] = LoadEntry->un.id; 1646fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1647*291a2b48SSukumar Swaminathan "Load List[%d]: %08x %08x", i, 1648*291a2b48SSukumar Swaminathan LoadEntry->un.wd[0], LoadEntry->un.wd[1]); 1649fcf3ce44SJohn Forte } 1650fcf3ce44SJohn Forte } 1651fcf3ce44SJohn Forte 1652fcf3ce44SJohn Forte done: 1653fcf3ce44SJohn Forte 1654fcf3ce44SJohn Forte if (LoadList) { 1655fcf3ce44SJohn Forte kmem_free(LoadList, sizeof (LOAD_LIST)); 1656fcf3ce44SJohn Forte } 1657*291a2b48SSukumar Swaminathan 1658fcf3ce44SJohn Forte return (rval); 1659fcf3ce44SJohn Forte 1660*291a2b48SSukumar Swaminathan } /* emlxs_get_load_list() */ 1661fcf3ce44SJohn Forte 1662fcf3ce44SJohn Forte 1663fcf3ce44SJohn Forte extern uint32_t 1664fcf3ce44SJohn Forte emlxs_read_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms, 1665fcf3ce44SJohn Forte uint32_t verbose) 1666fcf3ce44SJohn Forte { 1667fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1668fcf3ce44SJohn Forte MAILBOXQ *mbox; 1669fcf3ce44SJohn Forte MAILBOX *mb; 1670fcf3ce44SJohn Forte uint32_t rval = 0; 1671fcf3ce44SJohn Forte uint32_t *wd; 1672fcf3ce44SJohn Forte 1673fcf3ce44SJohn Forte bzero(WakeUpParms, sizeof (WAKE_UP_PARMS)); 1674fcf3ce44SJohn Forte 1675*291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1676*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 1677fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1678fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 1679fcf3ce44SJohn Forte 1680fcf3ce44SJohn Forte return (1); 1681fcf3ce44SJohn Forte } 1682*291a2b48SSukumar Swaminathan 1683fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 1684fcf3ce44SJohn Forte 1685*291a2b48SSukumar Swaminathan emlxs_format_dump(mb, 1686*291a2b48SSukumar Swaminathan DMP_NV_PARAMS, 1687*291a2b48SSukumar Swaminathan WAKE_UP_PARMS_REGION_ID, 1688fcf3ce44SJohn Forte sizeof (WAKE_UP_PARMS) / sizeof (uint32_t), 0); 1689fcf3ce44SJohn Forte 1690*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 1691fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1692fcf3ce44SJohn Forte "Unable to get parameters: Mailbox cmd=%x status=%x", 1693fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 1694fcf3ce44SJohn Forte 1695fcf3ce44SJohn Forte if (mb->un.varDmp.word_cnt == (uint32_t)CFG_DATA_NO_REGION) { 1696fcf3ce44SJohn Forte rval = (uint32_t)CFG_DATA_NO_REGION; 1697fcf3ce44SJohn Forte } else { 1698fcf3ce44SJohn Forte rval = 1; 1699fcf3ce44SJohn Forte } 1700fcf3ce44SJohn Forte } else { 1701fcf3ce44SJohn Forte bcopy((caddr_t)&mb->un.varDmp.resp_offset, 1702fcf3ce44SJohn Forte (caddr_t)WakeUpParms, sizeof (WAKE_UP_PARMS)); 1703fcf3ce44SJohn Forte 1704fcf3ce44SJohn Forte if (verbose) { 1705fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->prog_id; 1706fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1707*291a2b48SSukumar Swaminathan "Wakeup: prog_id=%08x %08x", wd[0], wd[1]); 1708fcf3ce44SJohn Forte 1709fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->u0.boot_bios_id; 1710fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1711*291a2b48SSukumar Swaminathan "Wakeup: boot_bios_id=%08x %08x", wd[0], wd[1]); 1712fcf3ce44SJohn Forte 1713fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->sli1_prog_id; 1714fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1715*291a2b48SSukumar Swaminathan "Wakeup: sli1_prog_id=%08x %08x", wd[0], wd[1]); 1716fcf3ce44SJohn Forte 1717fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->sli2_prog_id; 1718fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1719*291a2b48SSukumar Swaminathan "Wakeup: sli2_prog_id=%08x %08x", wd[0], wd[1]); 1720fcf3ce44SJohn Forte 1721fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->sli3_prog_id; 1722fcf3ce44SJohn Forte if (wd[0] || wd[1]) { 1723*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 1724*291a2b48SSukumar Swaminathan &emlxs_init_debug_msg, 1725*291a2b48SSukumar Swaminathan "Wakeup: sli3_prog_id=%08x %08x", wd[0], 1726*291a2b48SSukumar Swaminathan wd[1]); 1727fcf3ce44SJohn Forte } 1728*291a2b48SSukumar Swaminathan 1729fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->sli4_prog_id; 1730fcf3ce44SJohn Forte if (wd[0] || wd[1]) { 1731*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 1732*291a2b48SSukumar Swaminathan &emlxs_init_debug_msg, 1733*291a2b48SSukumar Swaminathan "Wakeup: sli4_prog_id=%08x %08x", wd[0], 1734*291a2b48SSukumar Swaminathan wd[1]); 1735fcf3ce44SJohn Forte } 1736*291a2b48SSukumar Swaminathan 1737fcf3ce44SJohn Forte wd = (uint32_t *)&WakeUpParms->u1.EROM_prog_id; 1738fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1739*291a2b48SSukumar Swaminathan "Wakeup: EROM_prog_id=%08x %08x", wd[0], wd[1]); 1740fcf3ce44SJohn Forte 1741fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1742fcf3ce44SJohn Forte "Wakeup: pci_cfg_rsvd=%x", 1743fcf3ce44SJohn Forte WakeUpParms->pci_cfg_rsvd); 1744fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1745fcf3ce44SJohn Forte "Wakeup: use_hdw_def=%x", 1746fcf3ce44SJohn Forte WakeUpParms->use_hdw_def); 1747fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1748fcf3ce44SJohn Forte "Wakeup: pci_cfg_sel=%x", 1749fcf3ce44SJohn Forte WakeUpParms->pci_cfg_sel); 1750fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1751fcf3ce44SJohn Forte "Wakeup: cfg_lookup=%x", 1752fcf3ce44SJohn Forte WakeUpParms->pci_cfg_lookup_sel); 1753fcf3ce44SJohn Forte } 1754fcf3ce44SJohn Forte } 1755fcf3ce44SJohn Forte 1756fcf3ce44SJohn Forte done: 1757fcf3ce44SJohn Forte 1758fcf3ce44SJohn Forte if (mbox) { 1759fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 1760fcf3ce44SJohn Forte } 1761*291a2b48SSukumar Swaminathan 1762fcf3ce44SJohn Forte return (rval); 1763fcf3ce44SJohn Forte 1764*291a2b48SSukumar Swaminathan } /* emlxs_read_wakeup_parms() */ 1765fcf3ce44SJohn Forte 1766fcf3ce44SJohn Forte 1767fcf3ce44SJohn Forte static uint32_t 1768*291a2b48SSukumar Swaminathan emlxs_read_load_list(emlxs_hba_t *hba, LOAD_LIST *LoadList) 1769fcf3ce44SJohn Forte { 1770fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1771fcf3ce44SJohn Forte LOAD_ENTRY *LoadEntry; 1772fcf3ce44SJohn Forte uint32_t *Uptr; 1773fcf3ce44SJohn Forte uint32_t CurEntryAddr; 1774fcf3ce44SJohn Forte MAILBOXQ *mbox = NULL; 1775fcf3ce44SJohn Forte MAILBOX *mb; 1776fcf3ce44SJohn Forte 1777fcf3ce44SJohn Forte bzero((caddr_t)LoadList, sizeof (LOAD_LIST)); 1778fcf3ce44SJohn Forte 1779*291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1780*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 1781fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1782fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 1783fcf3ce44SJohn Forte 1784fcf3ce44SJohn Forte return (1); 1785fcf3ce44SJohn Forte } 1786*291a2b48SSukumar Swaminathan 1787fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 1788fcf3ce44SJohn Forte 1789fcf3ce44SJohn Forte emlxs_format_dump(mb, DMP_MEM_REG, 0, 2, FLASH_LOAD_LIST_ADR); 1790fcf3ce44SJohn Forte 1791*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 1792fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1793fcf3ce44SJohn Forte "Unable to get load list: Mailbox cmd=%x status=%x", 1794fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 1795fcf3ce44SJohn Forte 1796fcf3ce44SJohn Forte goto done; 1797fcf3ce44SJohn Forte } 1798*291a2b48SSukumar Swaminathan 1799fcf3ce44SJohn Forte Uptr = (uint32_t *)&mb->un.varDmp.resp_offset; 1800fcf3ce44SJohn Forte 1801fcf3ce44SJohn Forte LoadList->head = Uptr[0]; 1802fcf3ce44SJohn Forte LoadList->tail = Uptr[1]; 1803fcf3ce44SJohn Forte 1804fcf3ce44SJohn Forte CurEntryAddr = LoadList->head; 1805fcf3ce44SJohn Forte 1806fcf3ce44SJohn Forte while ((CurEntryAddr != FLASH_LOAD_LIST_ADR) && 1807fcf3ce44SJohn Forte (LoadList->entry_cnt < MAX_LOAD_ENTRY)) { 1808fcf3ce44SJohn Forte LoadEntry = &LoadList->load_entry[LoadList->entry_cnt]; 1809fcf3ce44SJohn Forte LoadList->entry_cnt++; 1810fcf3ce44SJohn Forte 1811*291a2b48SSukumar Swaminathan emlxs_format_dump(mb, 1812*291a2b48SSukumar Swaminathan DMP_MEM_REG, 0, FLASH_LOAD_ENTRY_SIZE, CurEntryAddr); 1813fcf3ce44SJohn Forte 1814*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 1815*291a2b48SSukumar Swaminathan MBX_SUCCESS) { 1816fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 1817*291a2b48SSukumar Swaminathan "Unable to get load list (%d): Mailbox cmd=%x " 1818*291a2b48SSukumar Swaminathan "status=%x", LoadList->entry_cnt, mb->mbxCommand, 1819*291a2b48SSukumar Swaminathan mb->mbxStatus); 1820fcf3ce44SJohn Forte 1821fcf3ce44SJohn Forte goto done; 1822fcf3ce44SJohn Forte } 1823*291a2b48SSukumar Swaminathan 1824fcf3ce44SJohn Forte Uptr = (uint32_t *)&(mb->un.varDmp.resp_offset); 1825fcf3ce44SJohn Forte 1826fcf3ce44SJohn Forte LoadEntry->next = Uptr[0]; 1827fcf3ce44SJohn Forte LoadEntry->prev = Uptr[1]; 1828fcf3ce44SJohn Forte LoadEntry->start_adr = Uptr[2]; 1829fcf3ce44SJohn Forte LoadEntry->len = Uptr[3]; 1830fcf3ce44SJohn Forte LoadEntry->un.wd[0] = Uptr[4]; 1831fcf3ce44SJohn Forte LoadEntry->un.wd[1] = Uptr[5]; 1832fcf3ce44SJohn Forte 1833fcf3ce44SJohn Forte /* update next current load entry address */ 1834fcf3ce44SJohn Forte CurEntryAddr = LoadEntry->next; 1835fcf3ce44SJohn Forte 1836fcf3ce44SJohn Forte } /* end of while (not end of list) */ 1837fcf3ce44SJohn Forte 1838fcf3ce44SJohn Forte done: 1839fcf3ce44SJohn Forte 1840fcf3ce44SJohn Forte if (mbox) { 1841fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 1842fcf3ce44SJohn Forte } 1843*291a2b48SSukumar Swaminathan 1844fcf3ce44SJohn Forte return (0); 1845fcf3ce44SJohn Forte 1846*291a2b48SSukumar Swaminathan } /* emlxs_read_load_list() */ 1847fcf3ce44SJohn Forte 1848fcf3ce44SJohn Forte 1849fcf3ce44SJohn Forte 1850fcf3ce44SJohn Forte 1851fcf3ce44SJohn Forte static uint32_t 1852fcf3ce44SJohn Forte emlxs_get_abs_image_type(caddr_t Buffer, uint32_t BufferSize) 1853fcf3ce44SJohn Forte { 1854fcf3ce44SJohn Forte uint32_t Version; 1855fcf3ce44SJohn Forte 1856fcf3ce44SJohn Forte if (BufferSize < (SLI_VERSION_LOC + 4)) 1857fcf3ce44SJohn Forte return (0xffffffff); 1858fcf3ce44SJohn Forte 1859fcf3ce44SJohn Forte Buffer += SLI_VERSION_LOC; 1860fcf3ce44SJohn Forte Version = *((uint32_t *)Buffer); 1861fcf3ce44SJohn Forte 1862fcf3ce44SJohn Forte return (Version); 1863fcf3ce44SJohn Forte 1864*291a2b48SSukumar Swaminathan } /* emlxs_get_abs_image_type() */ 1865fcf3ce44SJohn Forte 1866fcf3ce44SJohn Forte 1867fcf3ce44SJohn Forte static uint32_t 1868fcf3ce44SJohn Forte emlxs_get_dwc_image_type(emlxs_hba_t *hba, caddr_t Buffer, 1869fcf3ce44SJohn Forte uint32_t BufferSize, PAIF_HDR AifHeader) 1870fcf3ce44SJohn Forte { 1871fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1872fcf3ce44SJohn Forte IMAGE_HDR ImageHdr; 1873fcf3ce44SJohn Forte uint32_t NextImage; 1874fcf3ce44SJohn Forte uint32_t i; 1875fcf3ce44SJohn Forte uint8_t *Sptr; 1876fcf3ce44SJohn Forte uint8_t *Dptr; 1877fcf3ce44SJohn Forte uint32_t HwId = 0xffffffff; 1878fcf3ce44SJohn Forte 1879fcf3ce44SJohn Forte NextImage = SLI_IMAGE_START - AifHeader->ImageBase; 1880fcf3ce44SJohn Forte 1881fcf3ce44SJohn Forte while (BufferSize > NextImage) { 1882fcf3ce44SJohn Forte Sptr = (uint8_t *)&Buffer[NextImage]; 1883fcf3ce44SJohn Forte Dptr = (uint8_t *)&ImageHdr; 1884fcf3ce44SJohn Forte for (i = 0; i < sizeof (IMAGE_HDR); i++) { 1885fcf3ce44SJohn Forte Dptr[i] = Sptr[i]; 1886fcf3ce44SJohn Forte } 1887fcf3ce44SJohn Forte 1888fcf3ce44SJohn Forte if (ImageHdr.BlockSize == 0xffffffff) 1889fcf3ce44SJohn Forte break; 1890fcf3ce44SJohn Forte 1891fcf3ce44SJohn Forte switch (ImageHdr.Id.Type) { 1892fcf3ce44SJohn Forte case 6: 1893fcf3ce44SJohn Forte case 7: 1894fcf3ce44SJohn Forte if (HwId == 0xffffffff) { 1895fcf3ce44SJohn Forte HwId = ImageHdr.Id.Id; 1896fcf3ce44SJohn Forte } 1897*291a2b48SSukumar Swaminathan 1898fcf3ce44SJohn Forte if (HwId != ImageHdr.Id.Id) { 1899*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 1900*291a2b48SSukumar Swaminathan &emlxs_image_bad_msg, 1901*291a2b48SSukumar Swaminathan "Invalid hardware id. %x %x", HwId, 1902*291a2b48SSukumar Swaminathan ImageHdr.Id.Id); 1903fcf3ce44SJohn Forte } 1904fcf3ce44SJohn Forte break; 1905fcf3ce44SJohn Forte } 1906fcf3ce44SJohn Forte 1907fcf3ce44SJohn Forte NextImage += ImageHdr.BlockSize; 1908fcf3ce44SJohn Forte } 1909fcf3ce44SJohn Forte 1910fcf3ce44SJohn Forte return (HwId); 1911fcf3ce44SJohn Forte 1912*291a2b48SSukumar Swaminathan } /* emlxs_get_dwc_image_type() */ 1913fcf3ce44SJohn Forte 1914fcf3ce44SJohn Forte 1915fcf3ce44SJohn Forte static int 1916*291a2b48SSukumar Swaminathan emlxs_build_parms(caddr_t Buffer, 1917*291a2b48SSukumar Swaminathan PWAKE_UP_PARMS AbsWakeUpParms, 1918fcf3ce44SJohn Forte uint32_t BufferSize, PAIF_HDR AifHeader, int32_t DwcFile) 1919fcf3ce44SJohn Forte { 1920fcf3ce44SJohn Forte IMAGE_HDR ImageHdr; 1921fcf3ce44SJohn Forte uint32_t NextImage; 1922fcf3ce44SJohn Forte uint32_t i; 1923fcf3ce44SJohn Forte int32_t ChangeParams = FALSE; 1924fcf3ce44SJohn Forte caddr_t Sptr; 1925fcf3ce44SJohn Forte caddr_t Dptr; 1926fcf3ce44SJohn Forte 1927fcf3ce44SJohn Forte bzero((caddr_t)AbsWakeUpParms, sizeof (WAKE_UP_PARMS)); 1928fcf3ce44SJohn Forte 1929fcf3ce44SJohn Forte if (!DwcFile && ((AifHeader->RoSize + AifHeader->RwSize) <= 0x20000)) { 1930fcf3ce44SJohn Forte return (FALSE); 1931fcf3ce44SJohn Forte } 1932*291a2b48SSukumar Swaminathan 1933fcf3ce44SJohn Forte NextImage = SLI_IMAGE_START - AifHeader->ImageBase; 1934fcf3ce44SJohn Forte 1935fcf3ce44SJohn Forte while (BufferSize > NextImage) { 1936fcf3ce44SJohn Forte Sptr = &Buffer[NextImage]; 1937fcf3ce44SJohn Forte Dptr = (caddr_t)&ImageHdr; 1938fcf3ce44SJohn Forte for (i = 0; i < sizeof (IMAGE_HDR); i++) { 1939fcf3ce44SJohn Forte Dptr[i] = Sptr[i]; 1940fcf3ce44SJohn Forte } 1941fcf3ce44SJohn Forte 1942fcf3ce44SJohn Forte if (ImageHdr.BlockSize == 0xffffffff) 1943fcf3ce44SJohn Forte break; 1944fcf3ce44SJohn Forte 1945fcf3ce44SJohn Forte switch (ImageHdr.Id.Type) { 1946fcf3ce44SJohn Forte case TEST_PROGRAM: 1947fcf3ce44SJohn Forte break; 1948fcf3ce44SJohn Forte case FUNC_FIRMWARE: 1949fcf3ce44SJohn Forte AbsWakeUpParms->prog_id = ImageHdr.Id; 1950fcf3ce44SJohn Forte ChangeParams = TRUE; 1951fcf3ce44SJohn Forte break; 1952fcf3ce44SJohn Forte case BOOT_BIOS: 1953fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_id = ImageHdr.Id; 1954fcf3ce44SJohn Forte ChangeParams = TRUE; 1955fcf3ce44SJohn Forte break; 1956fcf3ce44SJohn Forte case SLI1_OVERLAY: 1957fcf3ce44SJohn Forte AbsWakeUpParms->sli1_prog_id = ImageHdr.Id; 1958fcf3ce44SJohn Forte ChangeParams = TRUE; 1959fcf3ce44SJohn Forte break; 1960fcf3ce44SJohn Forte case SLI2_OVERLAY: 1961fcf3ce44SJohn Forte AbsWakeUpParms->sli2_prog_id = ImageHdr.Id; 1962fcf3ce44SJohn Forte ChangeParams = TRUE; 1963fcf3ce44SJohn Forte break; 1964fcf3ce44SJohn Forte case SLI3_OVERLAY: 1965fcf3ce44SJohn Forte AbsWakeUpParms->sli3_prog_id = ImageHdr.Id; 1966fcf3ce44SJohn Forte ChangeParams = TRUE; 1967fcf3ce44SJohn Forte break; 1968fcf3ce44SJohn Forte case SLI4_OVERLAY: 1969fcf3ce44SJohn Forte AbsWakeUpParms->sli4_prog_id = ImageHdr.Id; 1970fcf3ce44SJohn Forte ChangeParams = TRUE; 1971fcf3ce44SJohn Forte break; 1972fcf3ce44SJohn Forte default: 1973fcf3ce44SJohn Forte break; 1974fcf3ce44SJohn Forte } 1975fcf3ce44SJohn Forte 1976fcf3ce44SJohn Forte NextImage += ImageHdr.BlockSize; 1977fcf3ce44SJohn Forte } 1978fcf3ce44SJohn Forte 1979fcf3ce44SJohn Forte return (ChangeParams); 1980fcf3ce44SJohn Forte 1981*291a2b48SSukumar Swaminathan } /* emlxs_build_parms() */ 1982fcf3ce44SJohn Forte 1983fcf3ce44SJohn Forte 1984fcf3ce44SJohn Forte static uint32_t 1985fcf3ce44SJohn Forte emlxs_update_wakeup_parms(emlxs_hba_t *hba, 1986fcf3ce44SJohn Forte PWAKE_UP_PARMS AbsWakeUpParms, PWAKE_UP_PARMS WakeUpParms) 1987fcf3ce44SJohn Forte { 1988fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1989fcf3ce44SJohn Forte MAILBOX *mb; 1990fcf3ce44SJohn Forte MAILBOXQ *mbox; 1991fcf3ce44SJohn Forte uint32_t rval = 0; 1992fcf3ce44SJohn Forte 1993*291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 1994*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 1995fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 1996fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 1997fcf3ce44SJohn Forte 1998fcf3ce44SJohn Forte return (1); 1999fcf3ce44SJohn Forte } 2000*291a2b48SSukumar Swaminathan 2001fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 2002fcf3ce44SJohn Forte 2003fcf3ce44SJohn Forte WakeUpParms->prog_id = AbsWakeUpParms->prog_id; 2004fcf3ce44SJohn Forte WakeUpParms->u0.boot_bios_id = AbsWakeUpParms->u0.boot_bios_id; 2005fcf3ce44SJohn Forte WakeUpParms->sli1_prog_id = AbsWakeUpParms->sli1_prog_id; 2006fcf3ce44SJohn Forte WakeUpParms->sli2_prog_id = AbsWakeUpParms->sli2_prog_id; 2007fcf3ce44SJohn Forte WakeUpParms->sli3_prog_id = AbsWakeUpParms->sli3_prog_id; 2008fcf3ce44SJohn Forte WakeUpParms->sli4_prog_id = AbsWakeUpParms->sli4_prog_id; 2009fcf3ce44SJohn Forte 2010fcf3ce44SJohn Forte emlxs_format_update_parms(mb, WakeUpParms); 2011fcf3ce44SJohn Forte 2012*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 2013fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2014*291a2b48SSukumar Swaminathan "Unable to update wakeup parameters: Mailbox cmd=%x " 2015*291a2b48SSukumar Swaminathan "status=%x", mb->mbxCommand, mb->mbxStatus); 2016fcf3ce44SJohn Forte 2017fcf3ce44SJohn Forte rval = 1; 2018fcf3ce44SJohn Forte } 2019*291a2b48SSukumar Swaminathan 2020fcf3ce44SJohn Forte if (mbox) { 2021fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 2022fcf3ce44SJohn Forte } 2023*291a2b48SSukumar Swaminathan 2024fcf3ce44SJohn Forte return (rval); 2025fcf3ce44SJohn Forte 2026*291a2b48SSukumar Swaminathan } /* emlxs_update_wakeup_parms() */ 2027fcf3ce44SJohn Forte 2028fcf3ce44SJohn Forte 2029fcf3ce44SJohn Forte static uint32_t 2030*291a2b48SSukumar Swaminathan emlxs_validate_version(emlxs_hba_t *hba, emlxs_fw_file_t *file, uint32_t id, 2031*291a2b48SSukumar Swaminathan uint32_t type, char *file_type) 2032fcf3ce44SJohn Forte { 2033fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2034fcf3ce44SJohn Forte 2035fcf3ce44SJohn Forte /* Create the version label */ 2036fcf3ce44SJohn Forte emlxs_decode_version(file->version, file->label); 2037fcf3ce44SJohn Forte 2038fcf3ce44SJohn Forte /* Process the DWC type */ 2039fcf3ce44SJohn Forte switch (type) { 2040fcf3ce44SJohn Forte case TEST_PROGRAM: 2041fcf3ce44SJohn Forte 2042fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2043*291a2b48SSukumar Swaminathan "%s: TEST: offset=%08x version=%08x, %s", file_type, 2044*291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 2045fcf3ce44SJohn Forte 2046fcf3ce44SJohn Forte break; 2047fcf3ce44SJohn Forte 2048fcf3ce44SJohn Forte case BOOT_BIOS: 2049fcf3ce44SJohn Forte 2050fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2051*291a2b48SSukumar Swaminathan "%s: BOOT: offset=%08x version=%08x, %s", file_type, 2052*291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 2053fcf3ce44SJohn Forte 2054fcf3ce44SJohn Forte if (!emlxs_bios_check(hba, id)) { 2055fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2056fcf3ce44SJohn Forte "BOOT Check: Image not compatible with %s. id=%02x", 2057fcf3ce44SJohn Forte hba->model_info.model, id); 2058fcf3ce44SJohn Forte 2059fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 2060fcf3ce44SJohn Forte } 2061*291a2b48SSukumar Swaminathan 2062fcf3ce44SJohn Forte break; 2063fcf3ce44SJohn Forte 2064fcf3ce44SJohn Forte case FUNC_FIRMWARE: /* Stub */ 2065fcf3ce44SJohn Forte 2066fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2067*291a2b48SSukumar Swaminathan "%s: STUB: offset=%08x version=%08x, %s", file_type, 2068*291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 2069fcf3ce44SJohn Forte 2070fcf3ce44SJohn Forte if (!emlxs_stub_check(hba, id)) { 2071fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2072fcf3ce44SJohn Forte "STUB Check: Image not compatible with %s. id=%02x", 2073fcf3ce44SJohn Forte hba->model_info.model, id); 2074fcf3ce44SJohn Forte 2075fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 2076fcf3ce44SJohn Forte } 2077*291a2b48SSukumar Swaminathan 2078fcf3ce44SJohn Forte break; 2079fcf3ce44SJohn Forte 2080fcf3ce44SJohn Forte case SLI1_OVERLAY: 2081fcf3ce44SJohn Forte 2082fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2083*291a2b48SSukumar Swaminathan "%s: SLI1: offset=%08x version=%08x, %s", file_type, 2084*291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 2085fcf3ce44SJohn Forte 2086fcf3ce44SJohn Forte if (!emlxs_sli1_check(hba, id)) { 2087fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2088fcf3ce44SJohn Forte "SLI1 Check: Image not compatible with %s. id=%02x", 2089fcf3ce44SJohn Forte hba->model_info.model, id); 2090fcf3ce44SJohn Forte 2091fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 2092fcf3ce44SJohn Forte } 2093*291a2b48SSukumar Swaminathan 2094fcf3ce44SJohn Forte break; 2095fcf3ce44SJohn Forte 2096fcf3ce44SJohn Forte case SLI2_OVERLAY: 2097fcf3ce44SJohn Forte 2098fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2099*291a2b48SSukumar Swaminathan "%s: SLI2: offset=%08x version=%08x, %s", file_type, 2100*291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 2101fcf3ce44SJohn Forte 2102fcf3ce44SJohn Forte if (!emlxs_sli2_check(hba, id)) { 2103fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2104fcf3ce44SJohn Forte "SLI2 Check: Image not compatible with %s. id=%02x", 2105fcf3ce44SJohn Forte hba->model_info.model, id); 2106fcf3ce44SJohn Forte 2107fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 2108fcf3ce44SJohn Forte } 2109*291a2b48SSukumar Swaminathan 2110fcf3ce44SJohn Forte break; 2111fcf3ce44SJohn Forte 2112fcf3ce44SJohn Forte case SLI3_OVERLAY: 2113fcf3ce44SJohn Forte 2114fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2115*291a2b48SSukumar Swaminathan "%s: SLI3: offset=%08x version=%08x, %s", file_type, 2116*291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 2117fcf3ce44SJohn Forte 2118fcf3ce44SJohn Forte if (!emlxs_sli3_check(hba, id)) { 2119fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2120fcf3ce44SJohn Forte "SLI3 Check: Image not compatible with %s. id=%02x", 2121fcf3ce44SJohn Forte hba->model_info.model, id); 2122fcf3ce44SJohn Forte 2123fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 2124fcf3ce44SJohn Forte } 2125*291a2b48SSukumar Swaminathan 2126fcf3ce44SJohn Forte break; 2127fcf3ce44SJohn Forte 2128fcf3ce44SJohn Forte case SLI4_OVERLAY: 2129fcf3ce44SJohn Forte 2130fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2131*291a2b48SSukumar Swaminathan "%s: SLI4: offset=%08x version=%08x, %s", file_type, 2132*291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 2133fcf3ce44SJohn Forte 2134fcf3ce44SJohn Forte if (!emlxs_sli4_check(hba, id)) { 2135fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2136fcf3ce44SJohn Forte "SLI4 Check: Image not compatible with %s. id=%02x", 2137fcf3ce44SJohn Forte hba->model_info.model, id); 2138fcf3ce44SJohn Forte 2139fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 2140fcf3ce44SJohn Forte } 2141*291a2b48SSukumar Swaminathan 2142fcf3ce44SJohn Forte break; 2143fcf3ce44SJohn Forte 2144fcf3ce44SJohn Forte case SBUS_FCODE: 2145fcf3ce44SJohn Forte 2146fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2147fcf3ce44SJohn Forte "%s: SBUS FCODE: offset=%08x version=%08x, %s", 2148*291a2b48SSukumar Swaminathan file_type, file->offset, file->version, file->label); 2149fcf3ce44SJohn Forte 2150fcf3ce44SJohn Forte if (!emlxs_sbus_fcode_check(hba, id)) { 2151fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2152fcf3ce44SJohn Forte "SBUS FCODE Check: Image not compatible with %s. " 2153*291a2b48SSukumar Swaminathan "id=%02x", hba->model_info.model, id); 2154fcf3ce44SJohn Forte 2155fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 2156fcf3ce44SJohn Forte } 2157*291a2b48SSukumar Swaminathan 2158fcf3ce44SJohn Forte break; 2159fcf3ce44SJohn Forte 2160fcf3ce44SJohn Forte case KERNEL_CODE: 2161fcf3ce44SJohn Forte 2162fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg, 2163*291a2b48SSukumar Swaminathan "%s: KERN: offset=%08x version=%08x, %s", file_type, 2164*291a2b48SSukumar Swaminathan file->offset, file->version, file->label); 2165fcf3ce44SJohn Forte 2166fcf3ce44SJohn Forte if (!emlxs_kern_check(hba, id)) { 2167fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg, 2168fcf3ce44SJohn Forte "KERN Check: Image not compatible with %s. id=%02x", 2169fcf3ce44SJohn Forte hba->model_info.model, id); 2170fcf3ce44SJohn Forte 2171fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 2172fcf3ce44SJohn Forte } 2173*291a2b48SSukumar Swaminathan 2174fcf3ce44SJohn Forte break; 2175fcf3ce44SJohn Forte 2176fcf3ce44SJohn Forte default: 2177fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2178*291a2b48SSukumar Swaminathan "%s: Image type not supported. type=%x", file_type, type); 2179fcf3ce44SJohn Forte 2180fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 2181fcf3ce44SJohn Forte } 2182fcf3ce44SJohn Forte 2183fcf3ce44SJohn Forte return (0); 2184fcf3ce44SJohn Forte 2185*291a2b48SSukumar Swaminathan } /* emlxs_validate_version() */ 2186fcf3ce44SJohn Forte 2187fcf3ce44SJohn Forte 2188fcf3ce44SJohn Forte static uint32_t 2189fcf3ce44SJohn Forte emlxs_validate_image(emlxs_hba_t *hba, caddr_t Buffer, uint32_t Size, 2190fcf3ce44SJohn Forte emlxs_fw_image_t *image) 2191fcf3ce44SJohn Forte { 2192fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2193fcf3ce44SJohn Forte uint32_t ImageType; 2194fcf3ce44SJohn Forte AIF_HDR AifHdr; 2195fcf3ce44SJohn Forte IMAGE_HDR ImageHdr; 2196fcf3ce44SJohn Forte uint32_t NextImage; 2197fcf3ce44SJohn Forte uint32_t FileType; 2198fcf3ce44SJohn Forte uint32_t FileLen = 0; 2199fcf3ce44SJohn Forte uint32_t TotalLen = 0; 2200fcf3ce44SJohn Forte uint32_t *CkSumEnd; 2201fcf3ce44SJohn Forte uint32_t id; 2202fcf3ce44SJohn Forte uint32_t type; 2203fcf3ce44SJohn Forte uint32_t ver; 2204fcf3ce44SJohn Forte uint32_t ImageLength; 2205fcf3ce44SJohn Forte uint32_t BufferSize; 2206fcf3ce44SJohn Forte uint32_t rval = 0; 2207fcf3ce44SJohn Forte caddr_t bptr; 2208fcf3ce44SJohn Forte emlxs_vpd_t *vpd; 2209fcf3ce44SJohn Forte 2210fcf3ce44SJohn Forte vpd = &VPD; 2211fcf3ce44SJohn Forte 2212fcf3ce44SJohn Forte /* Get image type */ 2213fcf3ce44SJohn Forte ImageType = *((uint32_t *)Buffer); 2214fcf3ce44SJohn Forte 2215fcf3ce44SJohn Forte /* Pegasus and beyond adapters */ 2216fcf3ce44SJohn Forte if ((ImageType == NOP_IMAGE_TYPE) && 2217fcf3ce44SJohn Forte !(hba->model_info.chip & 2218fcf3ce44SJohn Forte (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 2219fcf3ce44SJohn Forte bptr = Buffer; 2220fcf3ce44SJohn Forte TotalLen = sizeof (uint32_t); 2221fcf3ce44SJohn Forte 2222fcf3ce44SJohn Forte while (TotalLen < Size) { 2223fcf3ce44SJohn Forte if (Size < sizeof (AIF_HDR)) { 2224*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 2225*291a2b48SSukumar Swaminathan &emlxs_image_bad_msg, 2226fcf3ce44SJohn Forte "Invalid image header length: 0x%x < 0x%x", 2227fcf3ce44SJohn Forte Size, sizeof (AIF_HDR)); 2228fcf3ce44SJohn Forte 2229fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 2230fcf3ce44SJohn Forte } 2231*291a2b48SSukumar Swaminathan 2232fcf3ce44SJohn Forte bcopy(bptr, &AifHdr, sizeof (AIF_HDR)); 2233fcf3ce44SJohn Forte emlxs_disp_aif_header(hba, &AifHdr); 2234fcf3ce44SJohn Forte 2235fcf3ce44SJohn Forte ImageLength = AifHdr.RoSize; 2236fcf3ce44SJohn Forte 2237fcf3ce44SJohn Forte /* Validate checksum */ 2238*291a2b48SSukumar Swaminathan CkSumEnd = 2239*291a2b48SSukumar Swaminathan (uint32_t *)(bptr + ImageLength + 2240*291a2b48SSukumar Swaminathan sizeof (AIF_HDR)); 2241fcf3ce44SJohn Forte if (emlxs_valid_cksum((uint32_t *)bptr, CkSumEnd)) { 2242*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 2243*291a2b48SSukumar Swaminathan &emlxs_image_bad_msg, 2244fcf3ce44SJohn Forte "Invalid checksum found."); 2245fcf3ce44SJohn Forte 2246fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 2247fcf3ce44SJohn Forte } 2248*291a2b48SSukumar Swaminathan 2249fcf3ce44SJohn Forte FileType = AifHdr.ZinitBr; 2250fcf3ce44SJohn Forte switch (FileType) { 2251fcf3ce44SJohn Forte case FILE_TYPE_AWC: 2252*291a2b48SSukumar Swaminathan image->awc.offset = 2253*291a2b48SSukumar Swaminathan (uint32_t)((uintptr_t)bptr - 2254*291a2b48SSukumar Swaminathan (uintptr_t)Buffer); 2255fcf3ce44SJohn Forte image->awc.version = AifHdr.AVersion; 2256fcf3ce44SJohn Forte image->awc.revcomp = 0; 2257fcf3ce44SJohn Forte 2258fcf3ce44SJohn Forte id = (AifHdr.AVersion & 0x00ff0000) >> 16; 2259fcf3ce44SJohn Forte type = emlxs_type_check( 2260fcf3ce44SJohn Forte (AifHdr.AVersion & 0xff000000) >> 24); 2261fcf3ce44SJohn Forte 2262fcf3ce44SJohn Forte /* Validate the file version */ 2263fcf3ce44SJohn Forte if ((rval = emlxs_validate_version(hba, 2264fcf3ce44SJohn Forte &image->awc, id, type, "AWC file"))) { 2265fcf3ce44SJohn Forte return (rval); 2266fcf3ce44SJohn Forte } 2267*291a2b48SSukumar Swaminathan 2268fcf3ce44SJohn Forte break; 2269fcf3ce44SJohn Forte 2270fcf3ce44SJohn Forte case FILE_TYPE_BWC: 2271*291a2b48SSukumar Swaminathan image->bwc.offset = 2272*291a2b48SSukumar Swaminathan (uint32_t)((uintptr_t)bptr - 2273*291a2b48SSukumar Swaminathan (uintptr_t)Buffer); 2274fcf3ce44SJohn Forte image->bwc.version = AifHdr.AVersion; 2275fcf3ce44SJohn Forte image->bwc.revcomp = 0; 2276fcf3ce44SJohn Forte 2277fcf3ce44SJohn Forte id = (AifHdr.AVersion & 0x00ff0000) >> 16; 2278fcf3ce44SJohn Forte type = emlxs_type_check( 2279fcf3ce44SJohn Forte (AifHdr.AVersion & 0xff000000) >> 24); 2280fcf3ce44SJohn Forte 2281fcf3ce44SJohn Forte /* Validate the file version */ 2282fcf3ce44SJohn Forte if ((rval = emlxs_validate_version(hba, 2283fcf3ce44SJohn Forte &image->bwc, id, type, "BWC file"))) { 2284fcf3ce44SJohn Forte return (rval); 2285fcf3ce44SJohn Forte } 2286*291a2b48SSukumar Swaminathan 2287fcf3ce44SJohn Forte break; 2288fcf3ce44SJohn Forte 2289fcf3ce44SJohn Forte case FILE_TYPE_DWC: 2290*291a2b48SSukumar Swaminathan image->dwc.offset = 2291*291a2b48SSukumar Swaminathan (uint32_t)((uintptr_t)bptr - 2292*291a2b48SSukumar Swaminathan (uintptr_t)Buffer); 2293fcf3ce44SJohn Forte image->dwc.version = AifHdr.AVersion; 2294fcf3ce44SJohn Forte image->dwc.revcomp = 0; 2295fcf3ce44SJohn Forte 2296fcf3ce44SJohn Forte id = (AifHdr.AVersion & 0x00ff0000) >> 16; 2297fcf3ce44SJohn Forte type = emlxs_type_check( 2298fcf3ce44SJohn Forte (AifHdr.AVersion & 0xff000000) >> 24); 2299fcf3ce44SJohn Forte 2300fcf3ce44SJohn Forte /* Validate the file version */ 2301fcf3ce44SJohn Forte if ((rval = emlxs_validate_version(hba, 2302fcf3ce44SJohn Forte &image->dwc, id, type, "DWC file"))) { 2303fcf3ce44SJohn Forte return (rval); 2304fcf3ce44SJohn Forte } 2305*291a2b48SSukumar Swaminathan 2306fcf3ce44SJohn Forte /* Scan for program types */ 2307fcf3ce44SJohn Forte NextImage = sizeof (AIF_HDR) + 4; 2308fcf3ce44SJohn Forte BufferSize = AifHdr.RoSize + AifHdr.RwSize; 2309fcf3ce44SJohn Forte 2310fcf3ce44SJohn Forte while (BufferSize > NextImage) { 2311fcf3ce44SJohn Forte bcopy(&bptr[NextImage], &ImageHdr, 2312fcf3ce44SJohn Forte sizeof (IMAGE_HDR)); 2313*291a2b48SSukumar Swaminathan emlxs_dump_image_header(hba, 2314*291a2b48SSukumar Swaminathan &ImageHdr); 2315fcf3ce44SJohn Forte 2316fcf3ce44SJohn Forte /* Validate block size */ 2317fcf3ce44SJohn Forte if (ImageHdr.BlockSize == 0xffffffff) { 2318fcf3ce44SJohn Forte break; 2319fcf3ce44SJohn Forte } 2320*291a2b48SSukumar Swaminathan 2321fcf3ce44SJohn Forte type = emlxs_type_check( 2322fcf3ce44SJohn Forte ImageHdr.Id.Type); 2323fcf3ce44SJohn Forte 2324fcf3ce44SJohn Forte /* Calculate the program offset */ 2325*291a2b48SSukumar Swaminathan image->prog[type].offset = 2326*291a2b48SSukumar Swaminathan (uint32_t)((uintptr_t) 2327*291a2b48SSukumar Swaminathan &bptr[NextImage] - 2328fcf3ce44SJohn Forte (uintptr_t)Buffer); 2329fcf3ce44SJohn Forte 2330fcf3ce44SJohn Forte /* Acquire the versions */ 2331fcf3ce44SJohn Forte image->prog[type].version = 2332fcf3ce44SJohn Forte (ImageHdr.Id.Type << 24) | 2333fcf3ce44SJohn Forte (ImageHdr.Id.Id << 16) | 2334fcf3ce44SJohn Forte (ImageHdr.Id.Ver << 8) | 2335fcf3ce44SJohn Forte ImageHdr.Id.Rev; 2336fcf3ce44SJohn Forte 2337fcf3ce44SJohn Forte image->prog[type].revcomp = 2338fcf3ce44SJohn Forte ImageHdr.Id.un.revcomp; 2339fcf3ce44SJohn Forte 2340fcf3ce44SJohn Forte /* Validate the file version */ 2341fcf3ce44SJohn Forte if ((rval = emlxs_validate_version(hba, 2342fcf3ce44SJohn Forte &image->prog[type], ImageHdr.Id.Id, 2343fcf3ce44SJohn Forte type, "DWC prog"))) { 2344fcf3ce44SJohn Forte return (rval); 2345fcf3ce44SJohn Forte } 2346*291a2b48SSukumar Swaminathan 2347fcf3ce44SJohn Forte NextImage += ImageHdr.BlockSize; 2348fcf3ce44SJohn Forte 2349fcf3ce44SJohn Forte } /* while() */ 2350fcf3ce44SJohn Forte 2351fcf3ce44SJohn Forte break; 2352fcf3ce44SJohn Forte } 2353fcf3ce44SJohn Forte 2354*291a2b48SSukumar Swaminathan FileLen = 2355*291a2b48SSukumar Swaminathan sizeof (AIF_HDR) + ImageLength + 2356fcf3ce44SJohn Forte sizeof (uint32_t); 2357fcf3ce44SJohn Forte TotalLen += FileLen; 2358fcf3ce44SJohn Forte bptr += FileLen; 2359fcf3ce44SJohn Forte } 2360fcf3ce44SJohn Forte } 2361*291a2b48SSukumar Swaminathan 2362fcf3ce44SJohn Forte /* Pre-pegasus adapters */ 2363fcf3ce44SJohn Forte 2364fcf3ce44SJohn Forte else if (ImageType == NOP_IMAGE_TYPE) { 2365fcf3ce44SJohn Forte if (Size < sizeof (AIF_HDR)) { 2366fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2367*291a2b48SSukumar Swaminathan "Invalid image header length: 0x%x < 0x%x", Size, 2368*291a2b48SSukumar Swaminathan sizeof (AIF_HDR)); 2369fcf3ce44SJohn Forte 2370fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 2371fcf3ce44SJohn Forte } 2372*291a2b48SSukumar Swaminathan 2373fcf3ce44SJohn Forte bcopy(Buffer, &AifHdr, sizeof (AIF_HDR)); 2374fcf3ce44SJohn Forte emlxs_disp_aif_header(hba, &AifHdr); 2375fcf3ce44SJohn Forte 2376fcf3ce44SJohn Forte ImageLength = AifHdr.RoSize + AifHdr.RwSize; 2377fcf3ce44SJohn Forte 2378fcf3ce44SJohn Forte if (Size != (sizeof (AIF_HDR) + ImageLength + sizeof (int))) { 2379fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2380*291a2b48SSukumar Swaminathan "Image length incorrect: 0x%x != 0x%x", Size, 2381*291a2b48SSukumar Swaminathan sizeof (AIF_HDR) + ImageLength + 2382*291a2b48SSukumar Swaminathan sizeof (uint32_t)); 2383fcf3ce44SJohn Forte 2384fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 2385fcf3ce44SJohn Forte } 2386*291a2b48SSukumar Swaminathan 2387fcf3ce44SJohn Forte if (AifHdr.ImageBase && AifHdr.ImageBase != 0x20000) { 2388fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2389fcf3ce44SJohn Forte "Invalid imageBase value %x != 0x20000", 2390fcf3ce44SJohn Forte AifHdr.ImageBase); 2391fcf3ce44SJohn Forte 2392fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 2393fcf3ce44SJohn Forte } 2394*291a2b48SSukumar Swaminathan 2395*291a2b48SSukumar Swaminathan CkSumEnd = 2396*291a2b48SSukumar Swaminathan (uint32_t *)(Buffer + ImageLength + sizeof (AIF_HDR)); 2397fcf3ce44SJohn Forte if (emlxs_valid_cksum((uint32_t *)Buffer, CkSumEnd)) { 2398fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2399fcf3ce44SJohn Forte "Invalid checksum found."); 2400fcf3ce44SJohn Forte 2401fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 2402fcf3ce44SJohn Forte } 2403*291a2b48SSukumar Swaminathan 2404fcf3ce44SJohn Forte image->dwc.offset = 0; 2405fcf3ce44SJohn Forte image->dwc.version = AifHdr.AVersion; 2406fcf3ce44SJohn Forte image->dwc.revcomp = 0; 2407fcf3ce44SJohn Forte 2408fcf3ce44SJohn Forte id = (AifHdr.AVersion & 0x00ff0000) >> 16; 2409fcf3ce44SJohn Forte type = emlxs_type_check((AifHdr.AVersion & 0xff000000) >> 24); 2410fcf3ce44SJohn Forte 2411fcf3ce44SJohn Forte /* Validate the file version */ 2412*291a2b48SSukumar Swaminathan if ((rval = emlxs_validate_version(hba, &image->dwc, id, type, 2413*291a2b48SSukumar Swaminathan "DWC file"))) { 2414fcf3ce44SJohn Forte return (rval); 2415fcf3ce44SJohn Forte } 2416*291a2b48SSukumar Swaminathan 2417fcf3ce44SJohn Forte NextImage = SLI_IMAGE_START - AifHdr.ImageBase; 2418fcf3ce44SJohn Forte while (Size > NextImage) { 2419fcf3ce44SJohn Forte bcopy(&Buffer[NextImage], &ImageHdr, 2420fcf3ce44SJohn Forte sizeof (IMAGE_HDR)); 2421fcf3ce44SJohn Forte emlxs_dump_image_header(hba, &ImageHdr); 2422fcf3ce44SJohn Forte 2423fcf3ce44SJohn Forte /* Validate block size */ 2424fcf3ce44SJohn Forte if (ImageHdr.BlockSize == 0xffffffff) { 2425fcf3ce44SJohn Forte break; 2426fcf3ce44SJohn Forte } 2427*291a2b48SSukumar Swaminathan 2428fcf3ce44SJohn Forte type = emlxs_type_check(ImageHdr.Id.Type); 2429fcf3ce44SJohn Forte 2430fcf3ce44SJohn Forte /* Calculate the program offset */ 2431fcf3ce44SJohn Forte image->prog[type].offset = NextImage; 2432fcf3ce44SJohn Forte 2433fcf3ce44SJohn Forte /* Acquire the versions */ 2434*291a2b48SSukumar Swaminathan image->prog[type].version = 2435*291a2b48SSukumar Swaminathan (ImageHdr.Id.Type << 24) | 2436*291a2b48SSukumar Swaminathan (ImageHdr.Id.Id << 16) | 2437*291a2b48SSukumar Swaminathan (ImageHdr.Id.Ver << 8) | 2438fcf3ce44SJohn Forte ImageHdr.Id.Rev; 2439fcf3ce44SJohn Forte 2440fcf3ce44SJohn Forte image->prog[type].revcomp = ImageHdr.Id.un.revcomp; 2441fcf3ce44SJohn Forte 2442fcf3ce44SJohn Forte /* Validate the file version */ 2443fcf3ce44SJohn Forte if ((rval = emlxs_validate_version(hba, 2444*291a2b48SSukumar Swaminathan &image->prog[type], ImageHdr.Id.Id, type, 2445*291a2b48SSukumar Swaminathan "DWC prog"))) { 2446fcf3ce44SJohn Forte return (rval); 2447fcf3ce44SJohn Forte } 2448*291a2b48SSukumar Swaminathan 2449fcf3ce44SJohn Forte NextImage += ImageHdr.BlockSize; 2450fcf3ce44SJohn Forte } 2451fcf3ce44SJohn Forte } else { 2452fcf3ce44SJohn Forte /* Precheck image size */ 2453fcf3ce44SJohn Forte if (Size < sizeof (IMAGE_HDR)) { 2454fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2455*291a2b48SSukumar Swaminathan "Invalid image header length: 0x%x < 0x%x", Size, 2456*291a2b48SSukumar Swaminathan sizeof (IMAGE_HDR)); 2457fcf3ce44SJohn Forte 2458fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 2459fcf3ce44SJohn Forte } 2460*291a2b48SSukumar Swaminathan 2461fcf3ce44SJohn Forte bcopy(Buffer, &ImageHdr, sizeof (IMAGE_HDR)); 2462fcf3ce44SJohn Forte emlxs_dump_image_header(hba, &ImageHdr); 2463fcf3ce44SJohn Forte 2464fcf3ce44SJohn Forte /* Validate block size */ 2465fcf3ce44SJohn Forte if (ImageHdr.BlockSize == 0xffffffff) { 2466fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2467fcf3ce44SJohn Forte "Invalid block size."); 2468fcf3ce44SJohn Forte 2469fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 2470fcf3ce44SJohn Forte } 2471*291a2b48SSukumar Swaminathan 2472fcf3ce44SJohn Forte ImageLength = ImageHdr.BlockSize; 2473fcf3ce44SJohn Forte 2474fcf3ce44SJohn Forte /* Validate image length */ 2475fcf3ce44SJohn Forte if (Size != ImageLength) { 2476fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2477*291a2b48SSukumar Swaminathan "Invalid image length: 0x%x != 0x%x", Size, 2478*291a2b48SSukumar Swaminathan ImageLength); 2479fcf3ce44SJohn Forte 2480fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 2481fcf3ce44SJohn Forte } 2482*291a2b48SSukumar Swaminathan 2483fcf3ce44SJohn Forte /* Validate Checksum */ 2484*291a2b48SSukumar Swaminathan CkSumEnd = 2485*291a2b48SSukumar Swaminathan (uint32_t *)Buffer + (ImageLength / sizeof (uint32_t)) - 2486*291a2b48SSukumar Swaminathan 1; 2487fcf3ce44SJohn Forte if (emlxs_valid_cksum((uint32_t *)Buffer, CkSumEnd)) { 2488fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2489fcf3ce44SJohn Forte "Invalid checksum found."); 2490fcf3ce44SJohn Forte 2491fcf3ce44SJohn Forte return (EMLXS_IMAGE_BAD); 2492fcf3ce44SJohn Forte } 2493*291a2b48SSukumar Swaminathan 2494fcf3ce44SJohn Forte type = emlxs_type_check(ImageHdr.Id.Type); 2495fcf3ce44SJohn Forte 2496fcf3ce44SJohn Forte /* Calculate the program offset */ 2497fcf3ce44SJohn Forte image->prog[type].offset = 0; 2498fcf3ce44SJohn Forte 2499fcf3ce44SJohn Forte /* Acquire the versions */ 2500*291a2b48SSukumar Swaminathan image->prog[type].version = 2501*291a2b48SSukumar Swaminathan (ImageHdr.Id.Type << 24) | (ImageHdr.Id. 2502*291a2b48SSukumar Swaminathan Id << 16) | (ImageHdr.Id.Ver << 8) | ImageHdr.Id.Rev; 2503fcf3ce44SJohn Forte 2504fcf3ce44SJohn Forte image->prog[type].revcomp = ImageHdr.Id.un.revcomp; 2505fcf3ce44SJohn Forte 2506fcf3ce44SJohn Forte /* Validate the file version */ 2507fcf3ce44SJohn Forte if ((rval = emlxs_validate_version(hba, &image->prog[type], 2508fcf3ce44SJohn Forte ImageHdr.Id.Id, type, "DWC file"))) { 2509fcf3ce44SJohn Forte return (rval); 2510fcf3ce44SJohn Forte } 2511fcf3ce44SJohn Forte } 2512fcf3ce44SJohn Forte 2513fcf3ce44SJohn Forte /* 2514*291a2b48SSukumar Swaminathan * This checks if a DragonFly (pre-V2 ASIC) SLI2 2515*291a2b48SSukumar Swaminathan * image file is greater than version 3.8 2516fcf3ce44SJohn Forte */ 2517fcf3ce44SJohn Forte if (FC_JEDEC_ID(vpd->biuRev) == DRAGONFLY_JEDEC_ID) { 2518fcf3ce44SJohn Forte if (image->prog[SLI2_OVERLAY].version != 0) { 2519fcf3ce44SJohn Forte ver = (image->prog[SLI2_OVERLAY].version & 2520fcf3ce44SJohn Forte 0x0000ff00) >> 8; 2521fcf3ce44SJohn Forte 2522fcf3ce44SJohn Forte if ((((ver & 0xf0) == 0x30) && 2523fcf3ce44SJohn Forte ((ver & 0x0f) >= 0x08)) || 2524fcf3ce44SJohn Forte ((ver & 0xf0) > 0x30)) { 2525fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 2526fcf3ce44SJohn Forte &emlxs_image_incompat_msg, 2527*291a2b48SSukumar Swaminathan "ASIC Check: Image requires DragonFly " 2528*291a2b48SSukumar Swaminathan "V2 ASIC"); 2529fcf3ce44SJohn Forte 2530fcf3ce44SJohn Forte return (EMLXS_IMAGE_INCOMPATIBLE); 2531fcf3ce44SJohn Forte } 2532fcf3ce44SJohn Forte } 2533fcf3ce44SJohn Forte } 2534*291a2b48SSukumar Swaminathan 2535fcf3ce44SJohn Forte return (0); 2536fcf3ce44SJohn Forte 2537*291a2b48SSukumar Swaminathan } /* emlxs_validate_image() */ 2538fcf3ce44SJohn Forte 2539fcf3ce44SJohn Forte 2540fcf3ce44SJohn Forte static uint32_t 2541fcf3ce44SJohn Forte emlxs_update_exp_rom(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms) 2542fcf3ce44SJohn Forte { 2543fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2544fcf3ce44SJohn Forte MAILBOXQ *mbox; 2545fcf3ce44SJohn Forte MAILBOX *mb; 2546fcf3ce44SJohn Forte uint32_t next_address; 2547fcf3ce44SJohn Forte uint32_t rval = 0; 2548fcf3ce44SJohn Forte 2549fcf3ce44SJohn Forte if (WakeUpParms->u1.EROM_prog_wd[0] == 0) { 2550fcf3ce44SJohn Forte return (1); 2551fcf3ce44SJohn Forte } 2552*291a2b48SSukumar Swaminathan 2553*291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2554*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2555fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2556fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 2557fcf3ce44SJohn Forte 2558fcf3ce44SJohn Forte return (1); 2559fcf3ce44SJohn Forte } 2560*291a2b48SSukumar Swaminathan 2561fcf3ce44SJohn Forte bzero(mbox, sizeof (MAILBOXQ)); 2562fcf3ce44SJohn Forte 2563fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 2564fcf3ce44SJohn Forte mb->mbxCommand = MBX_LOAD_EXP_ROM; 2565fcf3ce44SJohn Forte mb->un.varLdExpRom.step = EROM_CMD_FIND_IMAGE; 2566fcf3ce44SJohn Forte mb->un.varLdExpRom.progress = 0; 2567fcf3ce44SJohn Forte mb->un.varLdExpRom.un.prog_id = WakeUpParms->u1.EROM_prog_id; 2568fcf3ce44SJohn Forte 2569*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 2570fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2571fcf3ce44SJohn Forte "Unable to load exp ROM. Mailbox cmd=%x status=%x", 2572fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 2573fcf3ce44SJohn Forte 2574fcf3ce44SJohn Forte rval = 1; 2575fcf3ce44SJohn Forte 2576fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 2577fcf3ce44SJohn Forte } 2578*291a2b48SSukumar Swaminathan 2579fcf3ce44SJohn Forte if (mb->un.varLdExpRom.progress == EROM_RSP_COPY_DONE) { 2580fcf3ce44SJohn Forte (void) emlxs_update_wakeup_parms(hba, WakeUpParms, WakeUpParms); 2581fcf3ce44SJohn Forte 2582fcf3ce44SJohn Forte rval = 1; 2583fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 2584fcf3ce44SJohn Forte } 2585*291a2b48SSukumar Swaminathan 2586fcf3ce44SJohn Forte if (mb->un.varLdExpRom.progress != EROM_RSP_ERASE_STARTED) { 2587fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2588fcf3ce44SJohn Forte "Invalid exp ROM progress. progress=%x", 2589fcf3ce44SJohn Forte mb->un.varLdExpRom.progress); 2590fcf3ce44SJohn Forte 2591fcf3ce44SJohn Forte rval = 1; 2592fcf3ce44SJohn Forte 2593fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 2594fcf3ce44SJohn Forte } 2595*291a2b48SSukumar Swaminathan 2596fcf3ce44SJohn Forte /* 2597fcf3ce44SJohn Forte * continue Erase 2598fcf3ce44SJohn Forte */ 2599fcf3ce44SJohn Forte while (mb->un.varLdExpRom.progress != EROM_RSP_ERASE_COMPLETE) { 2600fcf3ce44SJohn Forte 2601fcf3ce44SJohn Forte next_address = mb->un.varLdExpRom.dl_to_adr; 2602fcf3ce44SJohn Forte 2603fcf3ce44SJohn Forte bzero((void *)mb, MAILBOX_CMD_BSIZE); 2604fcf3ce44SJohn Forte 2605fcf3ce44SJohn Forte mb->mbxCommand = MBX_LOAD_EXP_ROM; 2606fcf3ce44SJohn Forte mb->un.varLdExpRom.step = EROM_CMD_CONTINUE_ERASE; 2607fcf3ce44SJohn Forte mb->un.varLdExpRom.dl_to_adr = next_address; 2608fcf3ce44SJohn Forte mb->un.varLdExpRom.progress = 0; 2609fcf3ce44SJohn Forte mb->un.varLdExpRom.un.prog_id = WakeUpParms->u1.EROM_prog_id; 2610fcf3ce44SJohn Forte 2611*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 2612*291a2b48SSukumar Swaminathan MBX_SUCCESS) { 2613fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2614fcf3ce44SJohn Forte "Unable to load exp ROM. Mailbox cmd=%x status=%x", 2615fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 2616fcf3ce44SJohn Forte 2617fcf3ce44SJohn Forte rval = 1; 2618fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 2619fcf3ce44SJohn Forte } 2620*291a2b48SSukumar Swaminathan 2621fcf3ce44SJohn Forte } 2622fcf3ce44SJohn Forte 2623fcf3ce44SJohn Forte while (mb->un.varLdExpRom.progress != EROM_RSP_COPY_DONE) { 2624fcf3ce44SJohn Forte next_address = mb->un.varLdExpRom.dl_to_adr; 2625fcf3ce44SJohn Forte 2626fcf3ce44SJohn Forte bzero((void *)mb, MAILBOX_CMD_BSIZE); 2627fcf3ce44SJohn Forte 2628fcf3ce44SJohn Forte mb->mbxCommand = MBX_LOAD_EXP_ROM; 2629fcf3ce44SJohn Forte mb->un.varLdExpRom.step = EROM_CMD_COPY; 2630fcf3ce44SJohn Forte mb->un.varLdExpRom.dl_to_adr = next_address; 2631fcf3ce44SJohn Forte mb->un.varLdExpRom.progress = 0; 2632fcf3ce44SJohn Forte mb->un.varLdExpRom.un.prog_id = WakeUpParms->u1.EROM_prog_id; 2633fcf3ce44SJohn Forte 2634*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 2635*291a2b48SSukumar Swaminathan MBX_SUCCESS) { 2636fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2637fcf3ce44SJohn Forte "Unable to load exp ROM. Mailbox cmd=%x status=%x", 2638fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 2639fcf3ce44SJohn Forte 2640fcf3ce44SJohn Forte rval = 1; 2641fcf3ce44SJohn Forte 2642fcf3ce44SJohn Forte goto SLI_DOWNLOAD_EXIT; 2643fcf3ce44SJohn Forte } 2644fcf3ce44SJohn Forte } 2645fcf3ce44SJohn Forte 2646fcf3ce44SJohn Forte rval = emlxs_update_wakeup_parms(hba, WakeUpParms, WakeUpParms); 2647fcf3ce44SJohn Forte 2648fcf3ce44SJohn Forte SLI_DOWNLOAD_EXIT: 2649fcf3ce44SJohn Forte 2650fcf3ce44SJohn Forte if (mbox) { 2651fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 2652fcf3ce44SJohn Forte } 2653*291a2b48SSukumar Swaminathan 2654fcf3ce44SJohn Forte return (rval); 2655fcf3ce44SJohn Forte 2656*291a2b48SSukumar Swaminathan } /* emlxs_update_exp_rom() */ 2657fcf3ce44SJohn Forte 2658fcf3ce44SJohn Forte 2659fcf3ce44SJohn Forte /* 2660fcf3ce44SJohn Forte * 2661fcf3ce44SJohn Forte * FUNCTION NAME: emlxs_start_abs_download_2mb 2662fcf3ce44SJohn Forte * 2663fcf3ce44SJohn Forte * DESCRIPTION: Perform absolute download for 2 MB flash. A incoming 2664fcf3ce44SJohn Forte * buffer may consist of more than 1 file. This function 2665fcf3ce44SJohn Forte * will parse the buffer to find all the files. 2666fcf3ce44SJohn Forte * 2667fcf3ce44SJohn Forte * 2668fcf3ce44SJohn Forte * PARAMETERS: 2669fcf3ce44SJohn Forte * 2670fcf3ce44SJohn Forte * 2671fcf3ce44SJohn Forte * RETURNS: 2672fcf3ce44SJohn Forte * 2673fcf3ce44SJohn Forte */ 2674fcf3ce44SJohn Forte /* ARGSUSED */ 2675fcf3ce44SJohn Forte static uint32_t 2676fcf3ce44SJohn Forte emlxs_start_abs_download_2mb(emlxs_hba_t *hba, caddr_t buffer, uint32_t len, 2677fcf3ce44SJohn Forte uint32_t offline, emlxs_fw_image_t *fw_image) 2678fcf3ce44SJohn Forte { 2679fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2680fcf3ce44SJohn Forte caddr_t AwcBuffer = NULL; 2681fcf3ce44SJohn Forte caddr_t BwcBuffer = NULL; 2682fcf3ce44SJohn Forte caddr_t DwcBuffer = NULL; 2683fcf3ce44SJohn Forte AIF_HDR *AwcAifHdr; 2684fcf3ce44SJohn Forte AIF_HDR *BwcAifHdr; 2685fcf3ce44SJohn Forte AIF_HDR *DwcAifHdr; 2686fcf3ce44SJohn Forte uint32_t BWCflag; 2687fcf3ce44SJohn Forte emlxs_vpd_t *vpd; 2688fcf3ce44SJohn Forte uint32_t i; 2689fcf3ce44SJohn Forte uint32_t count; 2690fcf3ce44SJohn Forte uint32_t extType = 0; 2691fcf3ce44SJohn Forte uint32_t rval = 0; 2692fcf3ce44SJohn Forte 2693fcf3ce44SJohn Forte vpd = &VPD; 2694fcf3ce44SJohn Forte 2695fcf3ce44SJohn Forte /* Check for AWC file */ 2696fcf3ce44SJohn Forte if (fw_image->awc.version) { 2697fcf3ce44SJohn Forte AwcBuffer = buffer + fw_image->awc.offset; 2698*291a2b48SSukumar Swaminathan AwcAifHdr = (AIF_HDR *)AwcBuffer; 2699fcf3ce44SJohn Forte } 2700*291a2b48SSukumar Swaminathan 2701fcf3ce44SJohn Forte /* Check for BWC file */ 2702fcf3ce44SJohn Forte if (fw_image->bwc.version) { 2703fcf3ce44SJohn Forte extType = BWCext; 2704fcf3ce44SJohn Forte BwcBuffer = buffer + fw_image->bwc.offset; 2705*291a2b48SSukumar Swaminathan BwcAifHdr = (AIF_HDR *)BwcBuffer; 2706fcf3ce44SJohn Forte } 2707*291a2b48SSukumar Swaminathan 2708fcf3ce44SJohn Forte /* Check for DWC file */ 2709fcf3ce44SJohn Forte if (fw_image->dwc.version) { 2710fcf3ce44SJohn Forte extType = DWCext; 2711fcf3ce44SJohn Forte DwcBuffer = buffer + fw_image->dwc.offset; 2712*291a2b48SSukumar Swaminathan DwcAifHdr = (AIF_HDR *)DwcBuffer; 2713fcf3ce44SJohn Forte } 2714*291a2b48SSukumar Swaminathan 2715fcf3ce44SJohn Forte /* Check for program files */ 2716fcf3ce44SJohn Forte count = 0; 2717fcf3ce44SJohn Forte for (i = 0; i < MAX_PROG_TYPES; i++) { 2718fcf3ce44SJohn Forte if (fw_image->prog[i].version) { 2719fcf3ce44SJohn Forte count++; 2720fcf3ce44SJohn Forte } 2721fcf3ce44SJohn Forte } 2722fcf3ce44SJohn Forte 2723fcf3ce44SJohn Forte if (count > 1) { 2724fcf3ce44SJohn Forte extType = ALLext; 2725fcf3ce44SJohn Forte 2726fcf3ce44SJohn Forte if (fw_image->bwc.version) { 2727fcf3ce44SJohn Forte BWCflag = ALL_WITH_BWC; 2728fcf3ce44SJohn Forte } else { 2729fcf3ce44SJohn Forte BWCflag = ALL_WITHOUT_BWC; 2730fcf3ce44SJohn Forte } 2731fcf3ce44SJohn Forte } else { 2732fcf3ce44SJohn Forte BWCflag = NO_ALL; 2733fcf3ce44SJohn Forte } 2734fcf3ce44SJohn Forte 2735fcf3ce44SJohn Forte /* If nothing to download then quit now */ 2736fcf3ce44SJohn Forte if (!AwcBuffer && !DwcBuffer && !BwcBuffer) { 2737fcf3ce44SJohn Forte return (0); 2738fcf3ce44SJohn Forte } 2739*291a2b48SSukumar Swaminathan 2740fcf3ce44SJohn Forte /* 2741fcf3ce44SJohn Forte * Everything checks out, now to just do it 2742fcf3ce44SJohn Forte */ 2743fcf3ce44SJohn Forte if (offline) { 2744fcf3ce44SJohn Forte if (emlxs_offline(hba) != FC_SUCCESS) { 2745fcf3ce44SJohn Forte return (EMLXS_OFFLINE_FAILED); 2746fcf3ce44SJohn Forte } 2747*291a2b48SSukumar Swaminathan 2748*291a2b48SSukumar Swaminathan if (emlxs_sli_hba_reset(hba, 1, 1) != FC_SUCCESS) { 2749fcf3ce44SJohn Forte return (EMLXS_OFFLINE_FAILED); 2750fcf3ce44SJohn Forte } 2751fcf3ce44SJohn Forte } 2752*291a2b48SSukumar Swaminathan 2753fcf3ce44SJohn Forte if (AwcBuffer) { 2754fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2755*291a2b48SSukumar Swaminathan "AWC file: KERN: old=%s new=%s ", vpd->postKernName, 2756*291a2b48SSukumar Swaminathan fw_image->awc.label); 2757fcf3ce44SJohn Forte 2758*291a2b48SSukumar Swaminathan rval = emlxs_proc_abs_2mb(hba, 2759*291a2b48SSukumar Swaminathan AwcAifHdr, AwcBuffer, FILE_TYPE_AWC, BWCflag, extType); 2760fcf3ce44SJohn Forte 2761fcf3ce44SJohn Forte if (rval) { 2762fcf3ce44SJohn Forte goto SLI_DOWNLOAD_2MB_EXIT; 2763fcf3ce44SJohn Forte } 2764fcf3ce44SJohn Forte } 2765*291a2b48SSukumar Swaminathan 2766fcf3ce44SJohn Forte if (DwcBuffer) { 2767fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2768fcf3ce44SJohn Forte "DWC file: TEST: new=%s ", 2769fcf3ce44SJohn Forte fw_image->prog[TEST_PROGRAM].label); 2770fcf3ce44SJohn Forte 2771fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2772*291a2b48SSukumar Swaminathan "DWC file: STUB: old=%s new=%s ", vpd->opFwName, 2773*291a2b48SSukumar Swaminathan fw_image->prog[FUNC_FIRMWARE].label); 2774fcf3ce44SJohn Forte 2775fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2776*291a2b48SSukumar Swaminathan "DWC file: SLI1: old=%s new=%s ", vpd->sli1FwName, 2777*291a2b48SSukumar Swaminathan fw_image->prog[SLI1_OVERLAY].label); 2778fcf3ce44SJohn Forte 2779fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2780*291a2b48SSukumar Swaminathan "DWC file: SLI2: old=%s new=%s ", vpd->sli2FwName, 2781*291a2b48SSukumar Swaminathan fw_image->prog[SLI2_OVERLAY].label); 2782fcf3ce44SJohn Forte 2783fcf3ce44SJohn Forte if (vpd->sli3FwRev || fw_image->prog[SLI3_OVERLAY].version) { 2784fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2785fcf3ce44SJohn Forte "DWC file: SLI3: old=%s new=%s ", 2786fcf3ce44SJohn Forte vpd->sli3FwName, 2787fcf3ce44SJohn Forte fw_image->prog[SLI3_OVERLAY].label); 2788fcf3ce44SJohn Forte } 2789*291a2b48SSukumar Swaminathan 2790fcf3ce44SJohn Forte if (vpd->sli4FwRev || fw_image->prog[SLI4_OVERLAY].version) { 2791fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2792fcf3ce44SJohn Forte "DWC file: SLI4: old=%s new=%s ", 2793fcf3ce44SJohn Forte vpd->sli4FwName, 2794fcf3ce44SJohn Forte fw_image->prog[SLI4_OVERLAY].label); 2795fcf3ce44SJohn Forte } 2796*291a2b48SSukumar Swaminathan 2797*291a2b48SSukumar Swaminathan rval = emlxs_proc_abs_2mb(hba, 2798*291a2b48SSukumar Swaminathan DwcAifHdr, DwcBuffer, FILE_TYPE_DWC, BWCflag, extType); 2799fcf3ce44SJohn Forte 2800fcf3ce44SJohn Forte if (rval) { 2801fcf3ce44SJohn Forte goto SLI_DOWNLOAD_2MB_EXIT; 2802fcf3ce44SJohn Forte } 2803fcf3ce44SJohn Forte } 2804*291a2b48SSukumar Swaminathan 2805fcf3ce44SJohn Forte if (BwcBuffer) { 2806fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, 2807*291a2b48SSukumar Swaminathan "BWC file: BOOT: old=%s new=%s ", vpd->fcode_version, 2808*291a2b48SSukumar Swaminathan fw_image->bwc.label); 2809fcf3ce44SJohn Forte 2810*291a2b48SSukumar Swaminathan rval = emlxs_proc_abs_2mb(hba, 2811*291a2b48SSukumar Swaminathan BwcAifHdr, BwcBuffer, FILE_TYPE_BWC, BWCflag, extType); 2812fcf3ce44SJohn Forte } 2813*291a2b48SSukumar Swaminathan 2814fcf3ce44SJohn Forte SLI_DOWNLOAD_2MB_EXIT: 2815fcf3ce44SJohn Forte 2816fcf3ce44SJohn Forte if (offline) { 2817fcf3ce44SJohn Forte (void) emlxs_online(hba); 2818fcf3ce44SJohn Forte } 2819*291a2b48SSukumar Swaminathan 2820fcf3ce44SJohn Forte return (rval); 2821fcf3ce44SJohn Forte 2822*291a2b48SSukumar Swaminathan } /* emlxs_start_abs_download_2mb() */ 2823fcf3ce44SJohn Forte 2824fcf3ce44SJohn Forte 2825fcf3ce44SJohn Forte /* 2826fcf3ce44SJohn Forte * 2827fcf3ce44SJohn Forte * FUNCTION NAME: emlxs_proc_abs_2mb 2828fcf3ce44SJohn Forte * 2829fcf3ce44SJohn Forte * DESCRIPTION: Given one of the 3 file types(awc/bwc/dwc), it will reset 2830fcf3ce44SJohn Forte * the port and download the file with sliIssueMbCommand() 2831fcf3ce44SJohn Forte * 2832fcf3ce44SJohn Forte * 2833fcf3ce44SJohn Forte * PARAMETERS: 2834fcf3ce44SJohn Forte * 2835fcf3ce44SJohn Forte * 2836fcf3ce44SJohn Forte * RETURNS: 2837fcf3ce44SJohn Forte * 2838fcf3ce44SJohn Forte */ 2839fcf3ce44SJohn Forte static uint32_t 2840*291a2b48SSukumar Swaminathan emlxs_proc_abs_2mb(emlxs_hba_t *hba, 2841*291a2b48SSukumar Swaminathan PAIF_HDR AifHdr, 2842*291a2b48SSukumar Swaminathan caddr_t EntireBuffer, 2843fcf3ce44SJohn Forte uint32_t FileType, uint32_t BWCflag, uint32_t extType) 2844fcf3ce44SJohn Forte { 2845fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2846fcf3ce44SJohn Forte caddr_t Buffer = NULL; 2847fcf3ce44SJohn Forte caddr_t DataBuffer = NULL; 2848fcf3ce44SJohn Forte uint32_t *Src; 2849fcf3ce44SJohn Forte uint32_t *Dst; 2850fcf3ce44SJohn Forte MAILBOXQ *mbox; 2851fcf3ce44SJohn Forte MAILBOX *mb; 2852fcf3ce44SJohn Forte uint32_t DlByteCount = AifHdr->RoSize + AifHdr->RwSize; 2853fcf3ce44SJohn Forte uint32_t rval = 0; 2854fcf3ce44SJohn Forte uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT; 2855fcf3ce44SJohn Forte uint32_t DlToAddr = AifHdr->ImageBase; 2856fcf3ce44SJohn Forte uint32_t DlCount; 2857fcf3ce44SJohn Forte WAKE_UP_PARMS AbsWakeUpParms; 2858fcf3ce44SJohn Forte uint32_t i; 2859fcf3ce44SJohn Forte uint32_t NextAddr; 2860fcf3ce44SJohn Forte uint32_t EraseByteCount; 2861fcf3ce44SJohn Forte uint32_t AreaId; 2862fcf3ce44SJohn Forte uint32_t RspProgress = 0; 2863fcf3ce44SJohn Forte uint32_t numBootImage = 0; 2864fcf3ce44SJohn Forte uint32_t ParamsChg = 0; 2865fcf3ce44SJohn Forte uint32_t BufferSize; 2866fcf3ce44SJohn Forte 2867*291a2b48SSukumar Swaminathan if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT, 2868*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2869fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2870fcf3ce44SJohn Forte "%x: Unable to allocate data buffer.", FileType); 2871fcf3ce44SJohn Forte 2872fcf3ce44SJohn Forte return (EMLXS_IMAGE_FAILED); 2873fcf3ce44SJohn Forte } 2874*291a2b48SSukumar Swaminathan 2875fcf3ce44SJohn Forte bzero(DataBuffer, sizeof (DL_SLIM_SEG_BYTE_COUNT)); 2876fcf3ce44SJohn Forte 2877*291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 2878*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 2879fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2880fcf3ce44SJohn Forte "%x: Unable to allocate mailbox buffer.", FileType); 2881fcf3ce44SJohn Forte 2882fcf3ce44SJohn Forte kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 2883fcf3ce44SJohn Forte 2884fcf3ce44SJohn Forte return (EMLXS_IMAGE_FAILED); 2885fcf3ce44SJohn Forte } 2886*291a2b48SSukumar Swaminathan 2887fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 2888fcf3ce44SJohn Forte 2889fcf3ce44SJohn Forte BufferSize = DlByteCount + sizeof (AIF_HDR) + sizeof (uint32_t); 2890fcf3ce44SJohn Forte Buffer = EntireBuffer + sizeof (AIF_HDR); 2891fcf3ce44SJohn Forte 2892fcf3ce44SJohn Forte switch (FileType) { 2893fcf3ce44SJohn Forte case FILE_TYPE_AWC: 2894fcf3ce44SJohn Forte break; 2895fcf3ce44SJohn Forte 2896fcf3ce44SJohn Forte case FILE_TYPE_BWC: 2897*291a2b48SSukumar Swaminathan ParamsChg = emlxs_build_parms_2mb_bwc(hba, 2898*291a2b48SSukumar Swaminathan AifHdr, extType, &AbsWakeUpParms); 2899fcf3ce44SJohn Forte 2900fcf3ce44SJohn Forte if (ParamsChg == FALSE) { 2901fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2902fcf3ce44SJohn Forte "BWC build parms failed."); 2903fcf3ce44SJohn Forte 2904fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 2905fcf3ce44SJohn Forte 2906fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 2907fcf3ce44SJohn Forte } 2908fcf3ce44SJohn Forte break; 2909fcf3ce44SJohn Forte 2910fcf3ce44SJohn Forte case FILE_TYPE_DWC: 2911*291a2b48SSukumar Swaminathan ParamsChg = emlxs_build_parms_2mb_dwc(hba, 2912*291a2b48SSukumar Swaminathan Buffer, 2913*291a2b48SSukumar Swaminathan BufferSize, 2914*291a2b48SSukumar Swaminathan AifHdr, &AbsWakeUpParms, BWCflag, extType, &numBootImage); 2915fcf3ce44SJohn Forte 2916fcf3ce44SJohn Forte if (ParamsChg == FALSE) { 2917fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2918fcf3ce44SJohn Forte "DWC build parms failed."); 2919fcf3ce44SJohn Forte 2920fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 2921fcf3ce44SJohn Forte 2922fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 2923fcf3ce44SJohn Forte } 2924fcf3ce44SJohn Forte break; 2925fcf3ce44SJohn Forte 2926fcf3ce44SJohn Forte default: 2927fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg, 2928fcf3ce44SJohn Forte "Invalid file type: %x", FileType); 2929fcf3ce44SJohn Forte 2930fcf3ce44SJohn Forte rval = EMLXS_IMAGE_BAD; 2931fcf3ce44SJohn Forte 2932fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 2933fcf3ce44SJohn Forte 2934fcf3ce44SJohn Forte } 2935fcf3ce44SJohn Forte 2936fcf3ce44SJohn Forte EraseByteCount = AifHdr->Area_Size; 2937fcf3ce44SJohn Forte AreaId = AifHdr->Area_ID; 2938fcf3ce44SJohn Forte 2939*291a2b48SSukumar Swaminathan emlxs_format_load_area_cmd(mb, 2940*291a2b48SSukumar Swaminathan DlToAddr, 2941*291a2b48SSukumar Swaminathan EraseByteCount, 2942*291a2b48SSukumar Swaminathan ERASE_FLASH, 2943fcf3ce44SJohn Forte 0, DL_FROM_SLIM_OFFSET, AreaId, MBX_LOAD_AREA, CMD_START_ERASE); 2944fcf3ce44SJohn Forte 2945*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != MBX_SUCCESS) { 2946fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2947fcf3ce44SJohn Forte "%x: Could not erase 2MB Flash: Mailbox cmd=%x status=%x", 2948fcf3ce44SJohn Forte FileType, mb->mbxCommand, mb->mbxStatus); 2949fcf3ce44SJohn Forte 2950fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 2951fcf3ce44SJohn Forte 2952fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 2953fcf3ce44SJohn Forte } 2954*291a2b48SSukumar Swaminathan 2955fcf3ce44SJohn Forte while (mb->un.varLdArea.progress != RSP_ERASE_COMPLETE) { 2956fcf3ce44SJohn Forte NextAddr = mb->un.varLdArea.dl_to_adr; 2957fcf3ce44SJohn Forte 2958*291a2b48SSukumar Swaminathan emlxs_format_load_area_cmd(mb, 2959*291a2b48SSukumar Swaminathan NextAddr, 2960*291a2b48SSukumar Swaminathan EraseByteCount, 2961*291a2b48SSukumar Swaminathan ERASE_FLASH, 2962*291a2b48SSukumar Swaminathan 0, 2963*291a2b48SSukumar Swaminathan DL_FROM_SLIM_OFFSET, 2964*291a2b48SSukumar Swaminathan AreaId, MBX_LOAD_AREA, CMD_CONTINUE_ERASE); 2965fcf3ce44SJohn Forte 2966*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 2967*291a2b48SSukumar Swaminathan MBX_SUCCESS) { 2968fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 2969*291a2b48SSukumar Swaminathan "%x: Could not erase 2MB Flash2: Mailbox cmd=%x " 2970*291a2b48SSukumar Swaminathan "status=%x", FileType, mb->mbxCommand, 2971*291a2b48SSukumar Swaminathan mb->mbxStatus); 2972fcf3ce44SJohn Forte 2973fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 2974fcf3ce44SJohn Forte 2975fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 2976fcf3ce44SJohn Forte } 2977fcf3ce44SJohn Forte } 2978fcf3ce44SJohn Forte 2979fcf3ce44SJohn Forte while (DlByteCount) { 2980fcf3ce44SJohn Forte if (DlByteCount >= SegSize) 2981fcf3ce44SJohn Forte DlCount = SegSize; 2982fcf3ce44SJohn Forte else 2983fcf3ce44SJohn Forte DlCount = DlByteCount; 2984fcf3ce44SJohn Forte 2985fcf3ce44SJohn Forte DlByteCount -= DlCount; 2986fcf3ce44SJohn Forte 2987fcf3ce44SJohn Forte Dst = (uint32_t *)DataBuffer; 2988fcf3ce44SJohn Forte Src = (uint32_t *)Buffer; 2989fcf3ce44SJohn Forte 2990fcf3ce44SJohn Forte for (i = 0; i < (DlCount / 4); i++) { 2991fcf3ce44SJohn Forte *Dst = *Src; 2992fcf3ce44SJohn Forte Dst++; 2993fcf3ce44SJohn Forte Src++; 2994fcf3ce44SJohn Forte } 2995fcf3ce44SJohn Forte 2996fcf3ce44SJohn Forte WRITE_SLIM_COPY(hba, (uint32_t *)DataBuffer, 2997*291a2b48SSukumar Swaminathan (volatile uint32_t *)((volatile char *)hba->slim_addr + 2998*291a2b48SSukumar Swaminathan sizeof (MAILBOX)), (DlCount / sizeof (uint32_t))); 2999fcf3ce44SJohn Forte 3000fcf3ce44SJohn Forte if ((RspProgress == RSP_DOWNLOAD_MORE) || (RspProgress == 0)) { 3001*291a2b48SSukumar Swaminathan emlxs_format_load_area_cmd(mb, 3002*291a2b48SSukumar Swaminathan DlToAddr, 3003*291a2b48SSukumar Swaminathan DlCount, 3004*291a2b48SSukumar Swaminathan PROGRAM_FLASH, 3005*291a2b48SSukumar Swaminathan (DlByteCount) ? 0 : 1, 3006*291a2b48SSukumar Swaminathan DL_FROM_SLIM_OFFSET, 3007*291a2b48SSukumar Swaminathan AreaId, 3008*291a2b48SSukumar Swaminathan MBX_LOAD_AREA, 3009fcf3ce44SJohn Forte (DlByteCount) ? CMD_DOWNLOAD : CMD_END_DOWNLOAD); 3010fcf3ce44SJohn Forte 3011*291a2b48SSukumar Swaminathan if (emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0) != 3012fcf3ce44SJohn Forte MBX_SUCCESS) { 3013fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 3014fcf3ce44SJohn Forte &emlxs_download_failed_msg, 3015*291a2b48SSukumar Swaminathan "%x: Could not program 2MB Flash: Mailbox " 3016*291a2b48SSukumar Swaminathan "cmd=%x status=%x", FileType, 3017*291a2b48SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 3018fcf3ce44SJohn Forte 3019fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 3020fcf3ce44SJohn Forte 3021fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 3022fcf3ce44SJohn Forte } 3023fcf3ce44SJohn Forte } 3024*291a2b48SSukumar Swaminathan 3025fcf3ce44SJohn Forte RspProgress = mb->un.varLdArea.progress; 3026fcf3ce44SJohn Forte 3027fcf3ce44SJohn Forte Buffer += DlCount; 3028fcf3ce44SJohn Forte DlToAddr += DlCount; 3029fcf3ce44SJohn Forte } 3030fcf3ce44SJohn Forte 3031fcf3ce44SJohn Forte if (RspProgress != RSP_DOWNLOAD_DONE) { 3032fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3033*291a2b48SSukumar Swaminathan "%x: Failed download response received. %x", FileType, 3034*291a2b48SSukumar Swaminathan RspProgress); 3035fcf3ce44SJohn Forte 3036fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 3037fcf3ce44SJohn Forte 3038fcf3ce44SJohn Forte goto EXIT_ABS_DOWNLOAD; 3039fcf3ce44SJohn Forte } 3040*291a2b48SSukumar Swaminathan 3041fcf3ce44SJohn Forte if (ParamsChg) { 3042fcf3ce44SJohn Forte if (emlxs_update_wakeup_parms(hba, &AbsWakeUpParms, 3043fcf3ce44SJohn Forte &AbsWakeUpParms)) { 3044fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3045fcf3ce44SJohn Forte "%x: Unable to update parms.", FileType); 3046fcf3ce44SJohn Forte 3047fcf3ce44SJohn Forte rval = EMLXS_IMAGE_FAILED; 3048fcf3ce44SJohn Forte } 3049fcf3ce44SJohn Forte } 3050*291a2b48SSukumar Swaminathan 3051fcf3ce44SJohn Forte EXIT_ABS_DOWNLOAD: 3052fcf3ce44SJohn Forte 3053fcf3ce44SJohn Forte if (DataBuffer) { 3054fcf3ce44SJohn Forte kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT); 3055fcf3ce44SJohn Forte } 3056*291a2b48SSukumar Swaminathan 3057fcf3ce44SJohn Forte if (mbox) { 3058fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 3059fcf3ce44SJohn Forte } 3060*291a2b48SSukumar Swaminathan 3061fcf3ce44SJohn Forte return (rval); 3062fcf3ce44SJohn Forte 3063*291a2b48SSukumar Swaminathan } /* emlxs_proc_abs_2mb() */ 3064fcf3ce44SJohn Forte 3065fcf3ce44SJohn Forte 3066fcf3ce44SJohn Forte static void 3067*291a2b48SSukumar Swaminathan emlxs_format_load_area_cmd(MAILBOX * mb, 3068*291a2b48SSukumar Swaminathan uint32_t Base, 3069*291a2b48SSukumar Swaminathan uint32_t DlByteCount, 3070*291a2b48SSukumar Swaminathan uint32_t Function, 3071*291a2b48SSukumar Swaminathan uint32_t Complete, 3072*291a2b48SSukumar Swaminathan uint32_t DataOffset, uint32_t AreaId, uint8_t MbxCmd, uint32_t StepCmd) 3073fcf3ce44SJohn Forte { 3074fcf3ce44SJohn Forte bzero((void *)mb, MAILBOX_CMD_BSIZE); 3075fcf3ce44SJohn Forte 3076fcf3ce44SJohn Forte mb->mbxCommand = MbxCmd; 3077fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 3078fcf3ce44SJohn Forte mb->un.varLdArea.update_flash = 1; 3079fcf3ce44SJohn Forte mb->un.varLdArea.erase_or_prog = Function; 3080fcf3ce44SJohn Forte mb->un.varLdArea.dl_to_adr = Base; 3081fcf3ce44SJohn Forte mb->un.varLdArea.dl_len = DlByteCount; 3082fcf3ce44SJohn Forte mb->un.varLdArea.load_cmplt = Complete; 3083fcf3ce44SJohn Forte mb->un.varLdArea.method = DL_FROM_SLIM; 3084fcf3ce44SJohn Forte mb->un.varLdArea.area_id = AreaId; 3085fcf3ce44SJohn Forte mb->un.varLdArea.step = StepCmd; 3086fcf3ce44SJohn Forte mb->un.varLdArea.un.dl_from_slim_offset = DataOffset; 3087fcf3ce44SJohn Forte 3088*291a2b48SSukumar Swaminathan } /* emlxs_format_load_area_cmd() */ 3089fcf3ce44SJohn Forte 3090fcf3ce44SJohn Forte 3091*291a2b48SSukumar Swaminathan /* ARGSUSED */ 3092fcf3ce44SJohn Forte static uint32_t 3093*291a2b48SSukumar Swaminathan emlxs_build_parms_2mb_bwc(emlxs_hba_t *hba, 3094*291a2b48SSukumar Swaminathan PAIF_HDR AifHdr, uint32_t extType, PWAKE_UP_PARMS AbsWakeUpParms) 3095fcf3ce44SJohn Forte { 3096fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3097fcf3ce44SJohn Forte uint32_t pId[2]; 3098fcf3ce44SJohn Forte uint32_t returnStat; 3099fcf3ce44SJohn Forte 3100fcf3ce44SJohn Forte /* Read wakeup paramters */ 3101fcf3ce44SJohn Forte if (emlxs_read_wakeup_parms(hba, AbsWakeUpParms, 0) == 3102fcf3ce44SJohn Forte CFG_DATA_NO_REGION) { 3103fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3104fcf3ce44SJohn Forte "Unable to get BWC parameters."); 3105fcf3ce44SJohn Forte return (FALSE); 3106fcf3ce44SJohn Forte } 3107*291a2b48SSukumar Swaminathan 3108fcf3ce44SJohn Forte pId[0] = AifHdr->AVersion; 3109fcf3ce44SJohn Forte pId[1] = 0; 3110fcf3ce44SJohn Forte 3111fcf3ce44SJohn Forte if (extType == BWCext) { 3112fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_wd[0] = pId[0]; 3113fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_wd[1] = pId[1]; 3114fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 3115fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 3116*291a2b48SSukumar Swaminathan } 3117*291a2b48SSukumar Swaminathan 3118*291a2b48SSukumar Swaminathan else if (extType == ALLext) { 3119fcf3ce44SJohn Forte if (!AbsWakeUpParms->u0.boot_bios_wd[0]) { 3120fcf3ce44SJohn Forte /* case of EROM inactive */ 3121fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 3122fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 3123fcf3ce44SJohn Forte } else { 3124fcf3ce44SJohn Forte /* case of EROM active */ 3125fcf3ce44SJohn Forte if (AbsWakeUpParms->u0.boot_bios_wd[0] == pId[0]) { 3126fcf3ce44SJohn Forte /* same ID */ 3127fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_wd[0] = pId[0]; 3128fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_wd[1] = pId[1]; 3129fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 3130fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 3131fcf3ce44SJohn Forte } else { 3132fcf3ce44SJohn Forte /* different ID */ 3133fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0]; 3134fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1]; 3135fcf3ce44SJohn Forte 3136*291a2b48SSukumar Swaminathan returnStat = 3137*291a2b48SSukumar Swaminathan emlxs_update_exp_rom(hba, AbsWakeUpParms); 3138fcf3ce44SJohn Forte 3139fcf3ce44SJohn Forte if (returnStat) { 3140fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_wd[0] = 3141fcf3ce44SJohn Forte pId[0]; 3142fcf3ce44SJohn Forte AbsWakeUpParms->u0.boot_bios_wd[1] = 3143fcf3ce44SJohn Forte pId[1]; 3144fcf3ce44SJohn Forte } 3145fcf3ce44SJohn Forte } 3146fcf3ce44SJohn Forte } 3147fcf3ce44SJohn Forte } 3148*291a2b48SSukumar Swaminathan 3149fcf3ce44SJohn Forte return (TRUE); 3150fcf3ce44SJohn Forte 3151*291a2b48SSukumar Swaminathan } /* emlxs_build_parms_2mb_bwc() */ 3152fcf3ce44SJohn Forte 3153fcf3ce44SJohn Forte 3154fcf3ce44SJohn Forte /* ARGSUSED */ 3155fcf3ce44SJohn Forte static uint32_t 3156*291a2b48SSukumar Swaminathan emlxs_build_parms_2mb_dwc(emlxs_hba_t *hba, 3157*291a2b48SSukumar Swaminathan caddr_t Buffer, 3158*291a2b48SSukumar Swaminathan uint32_t BufferSize, 3159*291a2b48SSukumar Swaminathan PAIF_HDR AifHeader, 3160*291a2b48SSukumar Swaminathan PWAKE_UP_PARMS AbsWakeUpParms, 3161*291a2b48SSukumar Swaminathan uint32_t BWCflag, uint32_t extType, uint32_t *numBootImage) 3162fcf3ce44SJohn Forte { 3163fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3164fcf3ce44SJohn Forte uint32_t NextImage; 3165fcf3ce44SJohn Forte uint32_t i; 3166fcf3ce44SJohn Forte IMAGE_HDR ImageHdr; 3167fcf3ce44SJohn Forte uint32_t *ptr1; 3168fcf3ce44SJohn Forte uint32_t *ptr2; 3169fcf3ce44SJohn Forte PROG_ID BootId[MAX_BOOTID]; 3170fcf3ce44SJohn Forte uint32_t ChangeParams = FALSE; 3171fcf3ce44SJohn Forte WAKE_UP_PARMS WakeUpParms; 3172fcf3ce44SJohn Forte caddr_t Sptr; 3173fcf3ce44SJohn Forte caddr_t Dptr; 3174fcf3ce44SJohn Forte 3175fcf3ce44SJohn Forte bzero(&BootId, (sizeof (PROG_ID)) * MAX_BOOTID); 3176fcf3ce44SJohn Forte 3177fcf3ce44SJohn Forte /* Read wakeup paramters */ 3178fcf3ce44SJohn Forte if (emlxs_read_wakeup_parms(hba, AbsWakeUpParms, 0) == 3179fcf3ce44SJohn Forte CFG_DATA_NO_REGION) { 3180fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3181fcf3ce44SJohn Forte "Unable to get DWC parameters."); 3182fcf3ce44SJohn Forte return (FALSE); 3183fcf3ce44SJohn Forte } 3184*291a2b48SSukumar Swaminathan 3185fcf3ce44SJohn Forte bcopy((caddr_t)AbsWakeUpParms, (caddr_t)&WakeUpParms, 3186fcf3ce44SJohn Forte sizeof (WAKE_UP_PARMS)); 3187fcf3ce44SJohn Forte 3188fcf3ce44SJohn Forte if (((BWCflag == ALL_WITHOUT_BWC) || (extType == DWCext)) && 3189fcf3ce44SJohn Forte (WakeUpParms.u0.boot_bios_wd[0])) { 3190fcf3ce44SJohn Forte *numBootImage = 0; 3191fcf3ce44SJohn Forte } 3192*291a2b48SSukumar Swaminathan 3193fcf3ce44SJohn Forte /* incoming buffer is without aif header */ 3194fcf3ce44SJohn Forte NextImage = 0x84 - sizeof (AIF_HDR); 3195fcf3ce44SJohn Forte BufferSize -= (sizeof (AIF_HDR) + sizeof (uint32_t)); 3196fcf3ce44SJohn Forte 3197fcf3ce44SJohn Forte while (BufferSize > NextImage) { 3198fcf3ce44SJohn Forte Sptr = &Buffer[NextImage]; 3199fcf3ce44SJohn Forte Dptr = (caddr_t)&ImageHdr; 3200fcf3ce44SJohn Forte for (i = 0; i < sizeof (IMAGE_HDR); i++) { 3201fcf3ce44SJohn Forte Dptr[i] = Sptr[i]; 3202fcf3ce44SJohn Forte } 3203fcf3ce44SJohn Forte 3204fcf3ce44SJohn Forte if (ImageHdr.BlockSize == 0xffffffff) { 3205fcf3ce44SJohn Forte break; 3206fcf3ce44SJohn Forte } 3207*291a2b48SSukumar Swaminathan 3208fcf3ce44SJohn Forte switch (ImageHdr.Id.Type) { 3209fcf3ce44SJohn Forte case TEST_PROGRAM: 3210fcf3ce44SJohn Forte break; 3211fcf3ce44SJohn Forte 3212fcf3ce44SJohn Forte case FUNC_FIRMWARE: 3213fcf3ce44SJohn Forte AbsWakeUpParms->prog_id = ImageHdr.Id; 3214fcf3ce44SJohn Forte ChangeParams = TRUE; 3215fcf3ce44SJohn Forte break; 3216fcf3ce44SJohn Forte 3217fcf3ce44SJohn Forte case BOOT_BIOS: 3218fcf3ce44SJohn Forte if (!WakeUpParms.u0.boot_bios_wd[0]) { 3219fcf3ce44SJohn Forte if (extType == DWCext) { 3220fcf3ce44SJohn Forte break; 3221fcf3ce44SJohn Forte } else if (BWCflag == ALL_WITHOUT_BWC) { 3222*291a2b48SSukumar Swaminathan /* for possible future changes */ 3223fcf3ce44SJohn Forte break; 3224fcf3ce44SJohn Forte } 3225fcf3ce44SJohn Forte } 3226fcf3ce44SJohn Forte ChangeParams = TRUE; 3227fcf3ce44SJohn Forte 3228fcf3ce44SJohn Forte if (*numBootImage < MAX_BOOTID) { 3229fcf3ce44SJohn Forte BootId[*numBootImage] = ImageHdr.Id; 3230fcf3ce44SJohn Forte (*numBootImage)++; 3231fcf3ce44SJohn Forte } 3232fcf3ce44SJohn Forte break; 3233fcf3ce44SJohn Forte 3234fcf3ce44SJohn Forte case SLI1_OVERLAY: 3235fcf3ce44SJohn Forte AbsWakeUpParms->sli1_prog_id = ImageHdr.Id; 3236fcf3ce44SJohn Forte ChangeParams = TRUE; 3237fcf3ce44SJohn Forte break; 3238fcf3ce44SJohn Forte 3239fcf3ce44SJohn Forte case SLI2_OVERLAY: 3240fcf3ce44SJohn Forte AbsWakeUpParms->sli2_prog_id = ImageHdr.Id; 3241fcf3ce44SJohn Forte ChangeParams = TRUE; 3242fcf3ce44SJohn Forte break; 3243fcf3ce44SJohn Forte 3244fcf3ce44SJohn Forte case SLI3_OVERLAY: 3245fcf3ce44SJohn Forte AbsWakeUpParms->sli3_prog_id = ImageHdr.Id; 3246fcf3ce44SJohn Forte ChangeParams = TRUE; 3247fcf3ce44SJohn Forte break; 3248fcf3ce44SJohn Forte 3249fcf3ce44SJohn Forte case SLI4_OVERLAY: 3250fcf3ce44SJohn Forte AbsWakeUpParms->sli4_prog_id = ImageHdr.Id; 3251fcf3ce44SJohn Forte ChangeParams = TRUE; 3252fcf3ce44SJohn Forte break; 3253fcf3ce44SJohn Forte } 3254fcf3ce44SJohn Forte 3255fcf3ce44SJohn Forte NextImage += ImageHdr.BlockSize; 3256fcf3ce44SJohn Forte } 3257fcf3ce44SJohn Forte 3258fcf3ce44SJohn Forte if ((ChangeParams) && ((BWCflag == ALL_WITHOUT_BWC) || 3259fcf3ce44SJohn Forte (extType == DWCext))) { 3260fcf3ce44SJohn Forte 3261fcf3ce44SJohn Forte if (*numBootImage > 1) { 3262fcf3ce44SJohn Forte for (i = 0; i < *numBootImage; i++) { 3263*291a2b48SSukumar Swaminathan ptr1 = 3264*291a2b48SSukumar Swaminathan (uint32_t *)&WakeUpParms.u0. 3265*291a2b48SSukumar Swaminathan boot_bios_id; 3266fcf3ce44SJohn Forte ptr2 = (uint32_t *)&BootId[i]; 3267fcf3ce44SJohn Forte 3268fcf3ce44SJohn Forte if (ptr1[0] == ptr2[0]) { 3269fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_id = 3270fcf3ce44SJohn Forte BootId[i]; 3271fcf3ce44SJohn Forte (void) emlxs_update_exp_rom(hba, 3272fcf3ce44SJohn Forte AbsWakeUpParms); 3273fcf3ce44SJohn Forte break; 3274fcf3ce44SJohn Forte } 3275fcf3ce44SJohn Forte } 3276fcf3ce44SJohn Forte } else { 3277fcf3ce44SJohn Forte if (*numBootImage == 1) { 3278fcf3ce44SJohn Forte ptr2 = (uint32_t *)&BootId[0]; 3279fcf3ce44SJohn Forte 3280fcf3ce44SJohn Forte if (WakeUpParms.u0.boot_bios_wd[0] == ptr2[0]) { 3281fcf3ce44SJohn Forte AbsWakeUpParms->u1.EROM_prog_id = 3282fcf3ce44SJohn Forte BootId[0]; 3283fcf3ce44SJohn Forte (void) emlxs_update_exp_rom(hba, 3284fcf3ce44SJohn Forte AbsWakeUpParms); 3285fcf3ce44SJohn Forte } 3286fcf3ce44SJohn Forte } 3287fcf3ce44SJohn Forte } 3288fcf3ce44SJohn Forte } 3289*291a2b48SSukumar Swaminathan 3290fcf3ce44SJohn Forte return (ChangeParams); 3291fcf3ce44SJohn Forte 3292fcf3ce44SJohn Forte 3293*291a2b48SSukumar Swaminathan } /* emlxs_build_parms_2mb_dwc() */ 3294fcf3ce44SJohn Forte 3295fcf3ce44SJohn Forte 3296fcf3ce44SJohn Forte extern uint32_t 3297fcf3ce44SJohn Forte emlxs_get_max_sram(emlxs_hba_t *hba, uint32_t *MaxRbusSize, 3298fcf3ce44SJohn Forte uint32_t *MaxIbusSize) 3299fcf3ce44SJohn Forte { 3300fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3301fcf3ce44SJohn Forte MAILBOXQ *mbox; 3302fcf3ce44SJohn Forte MAILBOX *mb; 3303fcf3ce44SJohn Forte uint32_t *Uptr; 3304fcf3ce44SJohn Forte uint32_t rval = 0; 3305fcf3ce44SJohn Forte 3306*291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 3307*291a2b48SSukumar Swaminathan KM_NOSLEEP)) == NULL) { 3308fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3309fcf3ce44SJohn Forte "Unable to allocate mailbox buffer."); 3310fcf3ce44SJohn Forte 3311fcf3ce44SJohn Forte return (1); 3312fcf3ce44SJohn Forte } 3313*291a2b48SSukumar Swaminathan 3314fcf3ce44SJohn Forte mb = (MAILBOX *)mbox; 3315fcf3ce44SJohn Forte 3316fcf3ce44SJohn Forte emlxs_format_dump(mb, DMP_MEM_REG, 0, 2, MAX_RBUS_SRAM_SIZE_ADR); 3317fcf3ce44SJohn Forte 3318*291a2b48SSukumar Swaminathan if ((rval = emlxs_sli_issue_mbox_cmd(hba, mb, MBX_WAIT, 0)) != 3319*291a2b48SSukumar Swaminathan MBX_SUCCESS) { 3320fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg, 3321fcf3ce44SJohn Forte "Unable to get SRAM size: Mailbox cmd=%x status=%x", 3322fcf3ce44SJohn Forte mb->mbxCommand, mb->mbxStatus); 3323fcf3ce44SJohn Forte 3324fcf3ce44SJohn Forte rval = 1; 3325fcf3ce44SJohn Forte 3326fcf3ce44SJohn Forte goto Exit_Function; 3327fcf3ce44SJohn Forte } 3328*291a2b48SSukumar Swaminathan 3329fcf3ce44SJohn Forte Uptr = (uint32_t *)&mb->un.varDmp.resp_offset; 3330fcf3ce44SJohn Forte 3331fcf3ce44SJohn Forte *MaxRbusSize = Uptr[0]; 3332fcf3ce44SJohn Forte *MaxIbusSize = Uptr[1]; 3333fcf3ce44SJohn Forte 3334fcf3ce44SJohn Forte Exit_Function: 3335fcf3ce44SJohn Forte 3336fcf3ce44SJohn Forte if (mbox) { 3337fcf3ce44SJohn Forte kmem_free(mbox, sizeof (MAILBOXQ)); 3338fcf3ce44SJohn Forte } 3339*291a2b48SSukumar Swaminathan 3340fcf3ce44SJohn Forte return (rval); 3341fcf3ce44SJohn Forte 3342*291a2b48SSukumar Swaminathan } /* emlxs_get_max_sram() */ 3343fcf3ce44SJohn Forte 3344fcf3ce44SJohn Forte 3345fcf3ce44SJohn Forte static uint32_t 3346fcf3ce44SJohn Forte emlxs_kern_check(emlxs_hba_t *hba, uint32_t version) 3347fcf3ce44SJohn Forte { 3348fcf3ce44SJohn Forte uint8_t *ptr; 3349fcf3ce44SJohn Forte uint8_t ver; 3350fcf3ce44SJohn Forte 3351fcf3ce44SJohn Forte ver = version & 0xff; 3352fcf3ce44SJohn Forte ptr = hba->model_info.pt_FF; 3353fcf3ce44SJohn Forte 3354fcf3ce44SJohn Forte while (*ptr) { 3355fcf3ce44SJohn Forte if (*ptr++ == ver) { 3356fcf3ce44SJohn Forte return (1); 3357fcf3ce44SJohn Forte } 3358fcf3ce44SJohn Forte } 3359fcf3ce44SJohn Forte 3360fcf3ce44SJohn Forte return (0); 3361fcf3ce44SJohn Forte 3362*291a2b48SSukumar Swaminathan } /* emlxs_kern_check() */ 3363fcf3ce44SJohn Forte 3364fcf3ce44SJohn Forte static uint32_t 3365fcf3ce44SJohn Forte emlxs_stub_check(emlxs_hba_t *hba, uint32_t version) 3366fcf3ce44SJohn Forte { 3367fcf3ce44SJohn Forte uint8_t *ptr; 3368fcf3ce44SJohn Forte uint8_t ver; 3369fcf3ce44SJohn Forte 3370fcf3ce44SJohn Forte ver = version & 0xff; 3371fcf3ce44SJohn Forte ptr = hba->model_info.pt_2; 3372fcf3ce44SJohn Forte 3373fcf3ce44SJohn Forte while (*ptr) { 3374fcf3ce44SJohn Forte if (*ptr++ == ver) { 3375fcf3ce44SJohn Forte return (1); 3376fcf3ce44SJohn Forte } 3377fcf3ce44SJohn Forte } 3378fcf3ce44SJohn Forte 3379fcf3ce44SJohn Forte return (0); 3380fcf3ce44SJohn Forte 3381*291a2b48SSukumar Swaminathan } /* emlxs_stub_check() */ 3382fcf3ce44SJohn Forte 3383fcf3ce44SJohn Forte static uint32_t 3384fcf3ce44SJohn Forte emlxs_bios_check(emlxs_hba_t *hba, uint32_t version) 3385fcf3ce44SJohn Forte { 3386fcf3ce44SJohn Forte uint8_t *ptr; 3387fcf3ce44SJohn Forte uint8_t ver; 3388fcf3ce44SJohn Forte 3389fcf3ce44SJohn Forte ver = version & 0xff; 3390fcf3ce44SJohn Forte ptr = hba->model_info.pt_3; 3391fcf3ce44SJohn Forte 3392fcf3ce44SJohn Forte while (*ptr) { 3393fcf3ce44SJohn Forte if (*ptr++ == ver) { 3394fcf3ce44SJohn Forte return (1); 3395fcf3ce44SJohn Forte } 3396fcf3ce44SJohn Forte } 3397fcf3ce44SJohn Forte 3398fcf3ce44SJohn Forte return (0); 3399fcf3ce44SJohn Forte 3400*291a2b48SSukumar Swaminathan } /* emlxs_bios_check() */ 3401fcf3ce44SJohn Forte 3402fcf3ce44SJohn Forte static uint32_t 3403fcf3ce44SJohn Forte emlxs_sli1_check(emlxs_hba_t *hba, uint32_t version) 3404fcf3ce44SJohn Forte { 3405fcf3ce44SJohn Forte uint8_t *ptr; 3406fcf3ce44SJohn Forte uint8_t ver; 3407fcf3ce44SJohn Forte 3408fcf3ce44SJohn Forte ver = version & 0xff; 3409fcf3ce44SJohn Forte ptr = hba->model_info.pt_6; 3410fcf3ce44SJohn Forte 3411fcf3ce44SJohn Forte while (*ptr) { 3412fcf3ce44SJohn Forte if (*ptr++ == ver) { 3413fcf3ce44SJohn Forte return (1); 3414fcf3ce44SJohn Forte } 3415fcf3ce44SJohn Forte } 3416fcf3ce44SJohn Forte 3417fcf3ce44SJohn Forte return (0); 3418fcf3ce44SJohn Forte 3419*291a2b48SSukumar Swaminathan } /* emlxs_sli1_check() */ 3420fcf3ce44SJohn Forte 3421fcf3ce44SJohn Forte static uint32_t 3422fcf3ce44SJohn Forte emlxs_sli2_check(emlxs_hba_t *hba, uint32_t version) 3423fcf3ce44SJohn Forte { 3424fcf3ce44SJohn Forte uint8_t *ptr; 3425fcf3ce44SJohn Forte uint8_t ver; 3426fcf3ce44SJohn Forte 3427fcf3ce44SJohn Forte ver = version & 0xff; 3428fcf3ce44SJohn Forte ptr = hba->model_info.pt_7; 3429fcf3ce44SJohn Forte 3430fcf3ce44SJohn Forte while (*ptr) { 3431fcf3ce44SJohn Forte if (*ptr++ == ver) { 3432fcf3ce44SJohn Forte return (1); 3433fcf3ce44SJohn Forte } 3434fcf3ce44SJohn Forte } 3435fcf3ce44SJohn Forte 3436fcf3ce44SJohn Forte return (0); 3437fcf3ce44SJohn Forte 3438*291a2b48SSukumar Swaminathan } /* emlxs_sli2_check() */ 3439fcf3ce44SJohn Forte 3440fcf3ce44SJohn Forte static uint32_t 3441fcf3ce44SJohn Forte emlxs_sli3_check(emlxs_hba_t *hba, uint32_t version) 3442fcf3ce44SJohn Forte { 3443fcf3ce44SJohn Forte uint8_t *ptr; 3444fcf3ce44SJohn Forte uint8_t ver; 3445fcf3ce44SJohn Forte 3446fcf3ce44SJohn Forte ver = version & 0xff; 3447fcf3ce44SJohn Forte ptr = hba->model_info.pt_B; 3448fcf3ce44SJohn Forte 3449fcf3ce44SJohn Forte while (*ptr) { 3450fcf3ce44SJohn Forte if (*ptr++ == ver) { 3451fcf3ce44SJohn Forte return (1); 3452fcf3ce44SJohn Forte } 3453fcf3ce44SJohn Forte } 3454fcf3ce44SJohn Forte 3455fcf3ce44SJohn Forte return (0); 3456fcf3ce44SJohn Forte 3457*291a2b48SSukumar Swaminathan } /* emlxs_sli3_check() */ 3458fcf3ce44SJohn Forte 3459fcf3ce44SJohn Forte 3460fcf3ce44SJohn Forte static uint32_t 3461fcf3ce44SJohn Forte emlxs_sli4_check(emlxs_hba_t *hba, uint32_t version) 3462fcf3ce44SJohn Forte { 3463fcf3ce44SJohn Forte uint8_t *ptr; 3464fcf3ce44SJohn Forte uint8_t ver; 3465fcf3ce44SJohn Forte 3466fcf3ce44SJohn Forte ver = version & 0xff; 3467fcf3ce44SJohn Forte ptr = hba->model_info.pt_E; 3468fcf3ce44SJohn Forte 3469fcf3ce44SJohn Forte while (*ptr) { 3470fcf3ce44SJohn Forte if (*ptr++ == ver) { 3471fcf3ce44SJohn Forte return (1); 3472fcf3ce44SJohn Forte } 3473fcf3ce44SJohn Forte } 3474fcf3ce44SJohn Forte 3475fcf3ce44SJohn Forte return (0); 3476fcf3ce44SJohn Forte 3477*291a2b48SSukumar Swaminathan } /* emlxs_sli4_check() */ 3478fcf3ce44SJohn Forte 3479fcf3ce44SJohn Forte 3480fcf3ce44SJohn Forte static uint32_t 3481fcf3ce44SJohn Forte emlxs_sbus_fcode_check(emlxs_hba_t *hba, uint32_t version) 3482fcf3ce44SJohn Forte { 3483fcf3ce44SJohn Forte uint8_t *ptr; 3484fcf3ce44SJohn Forte uint8_t ver; 3485fcf3ce44SJohn Forte 3486fcf3ce44SJohn Forte ver = version & 0xff; 3487fcf3ce44SJohn Forte ptr = hba->model_info.pt_A; 3488fcf3ce44SJohn Forte 3489fcf3ce44SJohn Forte while (*ptr) { 3490fcf3ce44SJohn Forte if (*ptr++ == ver) { 3491fcf3ce44SJohn Forte return (1); 3492fcf3ce44SJohn Forte } 3493fcf3ce44SJohn Forte } 3494fcf3ce44SJohn Forte 3495fcf3ce44SJohn Forte return (0); 3496fcf3ce44SJohn Forte 3497*291a2b48SSukumar Swaminathan } /* emlxs_sbus_fcode_check() */ 3498fcf3ce44SJohn Forte 3499fcf3ce44SJohn Forte static uint32_t 3500fcf3ce44SJohn Forte emlxs_type_check(uint32_t type) 3501fcf3ce44SJohn Forte { 3502fcf3ce44SJohn Forte if (type == 0xff) { 3503fcf3ce44SJohn Forte return (KERNEL_CODE); 3504fcf3ce44SJohn Forte } 3505*291a2b48SSukumar Swaminathan 3506fcf3ce44SJohn Forte if (type >= MAX_PROG_TYPES) { 3507fcf3ce44SJohn Forte return (RESERVED_D); 3508fcf3ce44SJohn Forte } 3509*291a2b48SSukumar Swaminathan 3510fcf3ce44SJohn Forte return (type); 3511fcf3ce44SJohn Forte 3512*291a2b48SSukumar Swaminathan } /* emlxs_type_check() */ 3513fcf3ce44SJohn Forte 3514fcf3ce44SJohn Forte 3515fcf3ce44SJohn Forte 3516*291a2b48SSukumar Swaminathan extern int32_t 3517fcf3ce44SJohn Forte emlxs_boot_code_disable(emlxs_hba_t *hba) 3518fcf3ce44SJohn Forte { 3519fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3520fcf3ce44SJohn Forte PROG_ID Id; 3521fcf3ce44SJohn Forte emlxs_vpd_t *vpd; 3522fcf3ce44SJohn Forte 3523fcf3ce44SJohn Forte vpd = &VPD; 3524fcf3ce44SJohn Forte 3525fcf3ce44SJohn Forte if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 0)) { 3526fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, 3527fcf3ce44SJohn Forte "emlxs_boot_code_disable: Unable to read wake up parms."); 3528fcf3ce44SJohn Forte 3529*291a2b48SSukumar Swaminathan return (FC_FAILURE); 3530fcf3ce44SJohn Forte } 3531*291a2b48SSukumar Swaminathan 3532fcf3ce44SJohn Forte /* Check if boot code is already disabled */ 3533fcf3ce44SJohn Forte if (hba->wakeup_parms.u0.boot_bios_wd[0] == 0) { 3534fcf3ce44SJohn Forte return (FC_SUCCESS); 3535fcf3ce44SJohn Forte } 3536*291a2b48SSukumar Swaminathan 3537fcf3ce44SJohn Forte /* Make sure EROM entry has copy of boot bios entry */ 3538fcf3ce44SJohn Forte if (!(hba->model_info.chip & 3539fcf3ce44SJohn Forte (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP)) && 3540fcf3ce44SJohn Forte (hba->wakeup_parms.u0.boot_bios_wd[0] != 3541fcf3ce44SJohn Forte hba->wakeup_parms.u1.EROM_prog_wd[0]) && 3542fcf3ce44SJohn Forte (hba->wakeup_parms.u0.boot_bios_wd[1] != 3543fcf3ce44SJohn Forte hba->wakeup_parms.u1.EROM_prog_wd[1])) { 3544fcf3ce44SJohn Forte (void) emlxs_update_boot_wakeup_parms(hba, &hba->wakeup_parms, 3545fcf3ce44SJohn Forte &hba->wakeup_parms.u0.boot_bios_id, 1); 3546fcf3ce44SJohn Forte } 3547*291a2b48SSukumar Swaminathan 3548fcf3ce44SJohn Forte /* Update the bios id with a zero id */ 3549fcf3ce44SJohn Forte /* Don't load the EROM this time */ 3550fcf3ce44SJohn Forte bzero(&Id, sizeof (PROG_ID)); 3551fcf3ce44SJohn Forte (void) emlxs_update_boot_wakeup_parms(hba, &hba->wakeup_parms, &Id, 0); 3552fcf3ce44SJohn Forte 3553fcf3ce44SJohn Forte /* Now read the parms again to verify */ 3554fcf3ce44SJohn Forte (void) emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1); 3555fcf3ce44SJohn Forte emlxs_decode_version(hba->wakeup_parms.u0.boot_bios_wd[0], 3556fcf3ce44SJohn Forte vpd->boot_version); 3557fcf3ce44SJohn Forte /* (void) strcpy(vpd->fcode_version, vpd->boot_version); */ 3558fcf3ce44SJohn Forte 3559fcf3ce44SJohn Forte /* Return the result */ 3560*291a2b48SSukumar Swaminathan return ((hba->wakeup_parms.u0.boot_bios_wd[0] == 0) ? 3561*291a2b48SSukumar Swaminathan FC_SUCCESS : FC_FAILURE); 3562fcf3ce44SJohn Forte 3563*291a2b48SSukumar Swaminathan } /* emlxs_boot_code_disable() */ 3564fcf3ce44SJohn Forte 3565fcf3ce44SJohn Forte 3566*291a2b48SSukumar Swaminathan extern int32_t 3567fcf3ce44SJohn Forte emlxs_boot_code_enable(emlxs_hba_t *hba) 3568fcf3ce44SJohn Forte { 3569fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3570fcf3ce44SJohn Forte emlxs_vpd_t *vpd; 3571fcf3ce44SJohn Forte PROG_ID load_list[MAX_LOAD_ENTRY]; 3572fcf3ce44SJohn Forte uint32_t i; 3573fcf3ce44SJohn Forte 3574fcf3ce44SJohn Forte vpd = &VPD; 3575fcf3ce44SJohn Forte 3576fcf3ce44SJohn Forte /* Read the wakeup parms */ 3577fcf3ce44SJohn Forte if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 0)) { 3578fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, 3579fcf3ce44SJohn Forte "emlxs_boot_code_enable: Unable to read wake up parms."); 3580fcf3ce44SJohn Forte 3581*291a2b48SSukumar Swaminathan return (FC_FAILURE); 3582fcf3ce44SJohn Forte } 3583*291a2b48SSukumar Swaminathan 3584fcf3ce44SJohn Forte /* Check if boot code is already enabled */ 3585fcf3ce44SJohn Forte if (hba->wakeup_parms.u0.boot_bios_id.Type == BOOT_BIOS) { 3586fcf3ce44SJohn Forte return (FC_SUCCESS); 3587fcf3ce44SJohn Forte } 3588*291a2b48SSukumar Swaminathan 3589fcf3ce44SJohn Forte if (!(hba->model_info.chip & 3590fcf3ce44SJohn Forte (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) { 3591fcf3ce44SJohn Forte if (hba->wakeup_parms.u1.EROM_prog_id.Type != BOOT_BIOS) { 3592fcf3ce44SJohn Forte return (EMLXS_NO_BOOT_CODE); 3593fcf3ce44SJohn Forte } 3594*291a2b48SSukumar Swaminathan 3595fcf3ce44SJohn Forte /* Update the parms with the boot image id */ 3596fcf3ce44SJohn Forte /* Don't load the EROM this time */ 3597fcf3ce44SJohn Forte (void) emlxs_update_boot_wakeup_parms(hba, &hba->wakeup_parms, 3598fcf3ce44SJohn Forte &hba->wakeup_parms.u1.EROM_prog_id, 0); 3599fcf3ce44SJohn Forte } else { /* (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP) */ 3600*291a2b48SSukumar Swaminathan 3601fcf3ce44SJohn Forte if (emlxs_get_load_list(hba, load_list)) { 3602*291a2b48SSukumar Swaminathan return (FC_FAILURE); 3603fcf3ce44SJohn Forte } 3604*291a2b48SSukumar Swaminathan 3605fcf3ce44SJohn Forte /* Scan load list for a boot image */ 3606fcf3ce44SJohn Forte for (i = 0; i < MAX_LOAD_ENTRY; i++) { 3607fcf3ce44SJohn Forte if (load_list[i].Type == BOOT_BIOS) { 3608fcf3ce44SJohn Forte /* Update the parms with the boot image id */ 3609fcf3ce44SJohn Forte /* Don't load the EROM this time */ 3610fcf3ce44SJohn Forte (void) emlxs_update_boot_wakeup_parms(hba, 3611fcf3ce44SJohn Forte &hba->wakeup_parms, &load_list[i], 0); 3612fcf3ce44SJohn Forte 3613fcf3ce44SJohn Forte break; 3614fcf3ce44SJohn Forte } 3615fcf3ce44SJohn Forte } 3616fcf3ce44SJohn Forte 3617fcf3ce44SJohn Forte if (i == MAX_LOAD_ENTRY) { 3618fcf3ce44SJohn Forte return (EMLXS_NO_BOOT_CODE); 3619fcf3ce44SJohn Forte } 3620fcf3ce44SJohn Forte } 3621fcf3ce44SJohn Forte 3622fcf3ce44SJohn Forte /* Now read the parms again to verify */ 3623fcf3ce44SJohn Forte (void) emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1); 3624fcf3ce44SJohn Forte emlxs_decode_version(hba->wakeup_parms.u0.boot_bios_wd[0], 3625fcf3ce44SJohn Forte vpd->boot_version); 3626*291a2b48SSukumar Swaminathan /* (void) strcpy(vpd->fcode_version, vpd->boot_version); */ 3627fcf3ce44SJohn Forte 3628fcf3ce44SJohn Forte /* return the result */ 3629*291a2b48SSukumar Swaminathan return ((hba->wakeup_parms.u0.boot_bios_wd[0] != 0) ? 3630*291a2b48SSukumar Swaminathan FC_SUCCESS : FC_FAILURE); 3631fcf3ce44SJohn Forte 3632*291a2b48SSukumar Swaminathan } /* emlxs_boot_code_enable() */ 3633fcf3ce44SJohn Forte 3634fcf3ce44SJohn Forte 3635fcf3ce44SJohn Forte 3636*291a2b48SSukumar Swaminathan extern int32_t 3637fcf3ce44SJohn Forte emlxs_boot_code_state(emlxs_hba_t *hba) 3638fcf3ce44SJohn Forte { 3639fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3640fcf3ce44SJohn Forte 3641fcf3ce44SJohn Forte /* Read the wakeup parms */ 3642fcf3ce44SJohn Forte if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1)) { 3643fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg, 3644fcf3ce44SJohn Forte "emlxs_boot_code_state: Unable to read wake up parms."); 3645fcf3ce44SJohn Forte 3646*291a2b48SSukumar Swaminathan return (FC_FAILURE); 3647fcf3ce44SJohn Forte } 3648*291a2b48SSukumar Swaminathan 3649fcf3ce44SJohn Forte /* return the result */ 3650*291a2b48SSukumar Swaminathan return ((hba->wakeup_parms.u0.boot_bios_wd[0] != 0) ? 3651*291a2b48SSukumar Swaminathan FC_SUCCESS : FC_FAILURE); 3652fcf3ce44SJohn Forte 3653*291a2b48SSukumar Swaminathan } /* emlxs_boot_code_state() */ 3654