1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at
9 * http://www.opensource.org/licenses/cddl1.txt.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2004-2012 Emulex. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <emlxs.h>
28
29 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
30 EMLXS_MSG_DEF(EMLXS_DOWNLOAD_C);
31
32 #define MAX_BOOTID 10
33
34 static uint32_t emlxs_erase_fcode_flash(emlxs_hba_t *hba);
35
36 static uint32_t emlxs_write_fcode_flash(emlxs_hba_t *hba,
37 PIMAGE_HDR ImageHdr, caddr_t Buffer);
38
39 static int32_t emlxs_build_parms(caddr_t Buffer, PWAKE_UP_PARMS AbsWakeUpParms,
40 uint32_t BufferSize, PAIF_HDR AifHeader);
41 static uint32_t emlxs_validate_image(emlxs_hba_t *hba, caddr_t Buffer,
42 uint32_t Size, emlxs_fw_image_t *fw_image);
43 static void emlxs_format_dump(emlxs_hba_t *hba, MAILBOXQ *mbq,
44 uint32_t Type, uint32_t RegionId, uint32_t WordCnt,
45 uint32_t BaseAddr);
46 static uint32_t emlxs_start_abs_download(emlxs_hba_t *hba, PAIF_HDR AifHdr,
47 caddr_t Buffer, uint32_t len,
48 PWAKE_UP_PARMS WakeUpParms);
49 static uint32_t emlxs_start_abs_download_2mb(emlxs_hba_t *hba, caddr_t buffer,
50 uint32_t len, uint32_t offline,
51 emlxs_fw_image_t *fw_image);
52 static uint32_t emlxs_proc_abs_2mb(emlxs_hba_t *hba,
53 caddr_t EntireBuffer, uint32_t FileType,
54 uint32_t extType);
55 static void emlxs_format_load_area_cmd(MAILBOXQ *mbq, uint32_t Base,
56 uint32_t DlByteCount, uint32_t Function,
57 uint32_t Complete, uint32_t DataOffset, uint32_t AreaId,
58 uint8_t MbxCmd, uint32_t StepCmd);
59 static uint32_t emlxs_build_parms_2mb_bwc(emlxs_hba_t *hba, PAIF_HDR AifHdr,
60 uint32_t extType, PWAKE_UP_PARMS AbsWakeUpParms);
61 static uint32_t emlxs_update_exp_rom(emlxs_hba_t *hba,
62 PWAKE_UP_PARMS WakeUpParms);
63 extern uint32_t emlxs_get_max_sram(emlxs_hba_t *hba, uint32_t *MaxRbusSize,
64 uint32_t *MaxIbusSize);
65 static void emlxs_format_prog_flash(MAILBOXQ *mbq, uint32_t Base,
66 uint32_t DlByteCount, uint32_t Function,
67 uint32_t Complete, uint32_t BdeAddress,
68 uint32_t BdeSize, PROG_ID *ProgId, uint32_t keep);
69 static void emlxs_format_update_parms(MAILBOXQ *mbq,
70 PWAKE_UP_PARMS WakeUpParms);
71 static void emlxs_format_update_pci_cfg(emlxs_hba_t *hba, MAILBOXQ *mbq,
72 uint32_t region_id, uint32_t size);
73 static uint32_t emlxs_update_wakeup_parms(emlxs_hba_t *hba,
74 PWAKE_UP_PARMS AbsWakeUpParms,
75 PWAKE_UP_PARMS WakeUpParms);
76 static uint32_t emlxs_update_boot_wakeup_parms(emlxs_hba_t *hba,
77 PWAKE_UP_PARMS WakeUpParms, PROG_ID *id,
78 uint32_t proc_erom);
79 static uint32_t emlxs_update_ff_wakeup_parms(emlxs_hba_t *hba,
80 PWAKE_UP_PARMS WakeUpParms, PROG_ID *id);
81 static uint32_t emlxs_update_sli1_wakeup_parms(emlxs_hba_t *hba,
82 PWAKE_UP_PARMS WakeUpParms, PROG_ID *id);
83 static uint32_t emlxs_update_sli2_wakeup_parms(emlxs_hba_t *hba,
84 PWAKE_UP_PARMS WakeUpParms, PROG_ID *id);
85 static uint32_t emlxs_update_sli3_wakeup_parms(emlxs_hba_t *hba,
86 PWAKE_UP_PARMS WakeUpParms, PROG_ID *id);
87 static uint32_t emlxs_update_sli4_wakeup_parms(emlxs_hba_t *hba,
88 PWAKE_UP_PARMS WakeUpParms, PROG_ID *id);
89 static uint32_t emlxs_start_rel_download(emlxs_hba_t *hba, PIMAGE_HDR ImageHdr,
90 caddr_t Buffer, PWAKE_UP_PARMS WakeUpParms,
91 uint32_t dwc_flag);
92 static uint32_t emlxs_read_load_list(emlxs_hba_t *hba, LOAD_LIST *LoadList);
93
94 static uint32_t emlxs_valid_cksum(uint32_t *StartAddr, uint32_t *EndAddr);
95
96 static void emlxs_disp_aif_header(emlxs_hba_t *hba, PAIF_HDR AifHdr);
97
98 static void emlxs_dump_image_header(emlxs_hba_t *hba, PIMAGE_HDR image);
99
100
101 static uint32_t emlxs_type_check(uint32_t type);
102
103 static uint32_t emlxs_kern_check(emlxs_hba_t *hba, uint32_t version);
104
105 static uint32_t emlxs_stub_check(emlxs_hba_t *hba, uint32_t version);
106
107 static uint32_t emlxs_sli1_check(emlxs_hba_t *hba, uint32_t version);
108
109 static uint32_t emlxs_sli2_check(emlxs_hba_t *hba, uint32_t version);
110
111 static uint32_t emlxs_sli3_check(emlxs_hba_t *hba, uint32_t version);
112
113 static uint32_t emlxs_sli4_check(emlxs_hba_t *hba, uint32_t version);
114
115 static uint32_t emlxs_bios_check(emlxs_hba_t *hba, uint32_t version);
116
117 static uint32_t emlxs_sbus_fcode_check(emlxs_hba_t *hba, uint32_t version);
118
119 static uint32_t emlxs_validate_version(emlxs_hba_t *hba,
120 emlxs_fw_file_t *file, uint32_t id, uint32_t type,
121 char *file_type);
122 static uint32_t emlxs_be2_validate_image(emlxs_hba_t *hba, caddr_t buffer,
123 uint32_t len, emlxs_be_fw_image_t *fw_image);
124 static uint32_t emlxs_be3_validate_image(emlxs_hba_t *hba, caddr_t buffer,
125 uint32_t len, emlxs_be_fw_image_t *fw_image);
126
127
128 static int32_t emlxs_be_verify_phy(emlxs_hba_t *hba, emlxs_be_fw_file_t *file,
129 MAILBOXQ *mbq, MATCHMAP *mp);
130 static int32_t emlxs_be_verify_crc(emlxs_hba_t *hba,
131 emlxs_be_fw_file_t *file,
132 MAILBOXQ *mbq, MATCHMAP *mp);
133 static int32_t emlxs_be_flash_image(emlxs_hba_t *hba, caddr_t buffer,
134 emlxs_be_fw_file_t *file, MAILBOXQ *mbq, MATCHMAP *mp);
135 static int32_t emlxs_be_fw_download(emlxs_hba_t *hba, caddr_t buffer,
136 uint32_t len, uint32_t offline);
137 static int32_t emlxs_obj_fw_download(emlxs_hba_t *hba, caddr_t buffer,
138 uint32_t len, uint32_t offline);
139 static int32_t emlxs_obj_flash_image(emlxs_hba_t *hba, caddr_t buffer,
140 uint32_t size, MAILBOXQ *mbq, MATCHMAP *mp,
141 uint32_t *change_status);
142 static uint32_t emlxs_obj_validate_image(emlxs_hba_t *hba, caddr_t buffer,
143 uint32_t len, emlxs_obj_header_t *obj_hdr);
144 static uint32_t emlxs_be_version(caddr_t buffer, uint32_t size,
145 uint32_t *plus_flag);
146 static uint32_t emlxs_proc_rel_2mb(emlxs_hba_t *hba, caddr_t buffer,
147 emlxs_fw_image_t *fw_image);
148 static uint32_t emlxs_delete_load_entry(emlxs_hba_t *hba, PROG_ID *progId);
149
150 static void emlxs_verify_image(emlxs_hba_t *hba, emlxs_fw_image_t *image);
151
152 static uint32_t emlxs_clean_flash(emlxs_hba_t *hba,
153 PWAKE_UP_PARMS OldWakeUpParms,
154 PWAKE_UP_PARMS NewWakeUpParms);
155
156 /* ************************************************************************* */
157
158 extern int32_t
emlxs_fw_download(emlxs_hba_t * hba,caddr_t buffer,uint32_t len,uint32_t offline)159 emlxs_fw_download(emlxs_hba_t *hba, caddr_t buffer, uint32_t len,
160 uint32_t offline)
161 {
162 emlxs_port_t *port = &PPORT;
163 uint32_t *Uptr;
164 IMAGE_HDR ImageHdr;
165 AIF_HDR AifHdr;
166 uint32_t ImageType;
167 WAKE_UP_PARMS WakeUpParms;
168 uint32_t rval = 0;
169 emlxs_fw_image_t fw_image;
170 uint32_t i;
171
172 #ifdef EMLXS_LITTLE_ENDIAN
173 caddr_t local_buffer;
174 uint32_t *bptr1;
175 uint32_t *bptr2;
176 #endif /* EMLXS_LITTLE_ENDIAN */
177
178 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
179 if (hba->model_info.chip & EMLXS_BE_CHIPS) {
180 rval = emlxs_be_fw_download(hba, buffer, len, offline);
181 } else {
182 rval = emlxs_obj_fw_download(hba, buffer, len, offline);
183 }
184 return (rval);
185 }
186
187 if (buffer == NULL || len == 0) {
188 return (EMLXS_IMAGE_BAD);
189 }
190
191 #ifdef EMLXS_LITTLE_ENDIAN
192 /* We need to swap the image buffer before we start */
193
194 /*
195 * Use KM_SLEEP to allocate a temporary buffer
196 */
197 local_buffer = (caddr_t)kmem_zalloc(len, KM_SLEEP);
198
199 /* Perform a 32 bit swap of the image */
200 bptr1 = (uint32_t *)local_buffer;
201 bptr2 = (uint32_t *)buffer;
202 for (i = 0; i < (len / 4); i++) {
203 *bptr1 = LE_SWAP32(*bptr2);
204 bptr1++;
205 bptr2++;
206 }
207
208 /* Replace the original buffer */
209 buffer = local_buffer;
210 #endif /* EMLXS_LITTLE_ENDIAN */
211
212 bzero(&fw_image, sizeof (emlxs_fw_image_t));
213 for (i = 0; i < MAX_PROG_TYPES; i++) {
214 (void) strlcpy(fw_image.prog[i].label, "none",
215 sizeof (fw_image.prog[i].label));
216 }
217
218 /* Validate image */
219 if ((rval = emlxs_validate_image(hba, buffer, len, &fw_image))) {
220 goto done;
221 }
222
223 /* Verify image */
224 emlxs_verify_image(hba, &fw_image);
225
226 /* Get image type */
227 Uptr = (uint32_t *)buffer;
228 ImageType = *Uptr;
229
230 /*
231 * Pegasus and beyond FW download is done differently
232 * for absolute download.
233 */
234
235 /* Check for absolute image */
236 if ((ImageType == NOP_IMAGE_TYPE) &&
237 !(hba->model_info.chip &
238 (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) {
239 /*
240 * Because 2Mb flash download file format is different from
241 * 512k, it needs to be handled differently
242 */
243 if (rval = emlxs_start_abs_download_2mb(hba, buffer, len,
244 offline, &fw_image)) {
245 goto done;
246 }
247
248 /* Offline already handled */
249 offline = 0;
250
251 goto SLI_DOWNLOAD_EXIT;
252 }
253
254 /* Pre-pegasus adapters only */
255
256 /* Initialize headers */
257 if (ImageType == NOP_IMAGE_TYPE) {
258 bcopy(buffer, &AifHdr, sizeof (AIF_HDR));
259 bzero((void *)&ImageHdr, sizeof (IMAGE_HDR));
260 } else { /* PRG file */
261 bzero((void *)&AifHdr, sizeof (AIF_HDR));
262 bcopy(buffer, &ImageHdr, sizeof (IMAGE_HDR));
263 }
264
265 /* Everything checks out, now to just do it */
266
267 if (offline) {
268 if (emlxs_offline(hba, 0) != FC_SUCCESS) {
269 offline = 0;
270
271 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
272 "Unable to take adapter offline.");
273
274 rval = EMLXS_OFFLINE_FAILED;
275 goto SLI_DOWNLOAD_EXIT;
276 }
277
278 if (EMLXS_SLI_HBA_RESET(hba, 1, 1, 0) != FC_SUCCESS) {
279 offline = 0;
280
281 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
282 "Unable to restart adapter.");
283
284 rval = EMLXS_OFFLINE_FAILED;
285 goto SLI_DOWNLOAD_EXIT;
286 }
287 }
288
289 /* Pre-pegasus adapters */
290
291 if (ImageHdr.Id.Type == SBUS_FCODE) {
292 /* Erase Flash */
293 if (emlxs_erase_fcode_flash(hba)) {
294 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
295 "Unable to erase flash.");
296
297 rval = EMLXS_IMAGE_FAILED;
298 goto SLI_DOWNLOAD_EXIT;
299 }
300
301 /* Write FCODE */
302 if (emlxs_write_fcode_flash(hba, &ImageHdr, buffer)) {
303 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
304 "Unable to write flash.");
305
306 rval = EMLXS_IMAGE_FAILED;
307 goto SLI_DOWNLOAD_EXIT;
308 }
309
310 goto SLI_DOWNLOAD_EXIT;
311 }
312
313 /* Pre-pegasus PCI adapters */
314
315 if (emlxs_read_wakeup_parms(hba, &WakeUpParms, 1)) {
316 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
317 "Unable to get parameters.");
318
319 rval = EMLXS_IMAGE_FAILED;
320
321 goto SLI_DOWNLOAD_EXIT;
322 }
323
324 if (ImageType == NOP_IMAGE_TYPE) {
325 if (emlxs_start_abs_download(hba, &AifHdr,
326 buffer, len, &WakeUpParms)) {
327 EMLXS_MSGF(EMLXS_CONTEXT,
328 &emlxs_download_failed_msg,
329 "Failed to program flash.");
330
331 rval = EMLXS_IMAGE_FAILED;
332
333 goto SLI_DOWNLOAD_EXIT;
334 }
335
336 } else { /* Relative PRG file */
337 if (emlxs_start_rel_download(hba, &ImageHdr, buffer,
338 &WakeUpParms, 0)) {
339 EMLXS_MSGF(EMLXS_CONTEXT,
340 &emlxs_download_failed_msg,
341 "Failed to program flash.");
342
343 rval = EMLXS_IMAGE_FAILED;
344
345 goto SLI_DOWNLOAD_EXIT;
346 }
347 }
348
349 SLI_DOWNLOAD_EXIT:
350
351 if (offline) {
352 (void) emlxs_online(hba);
353 }
354
355 if (rval == 0) {
356 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_complete_msg,
357 "Status good.");
358 }
359
360 done:
361
362 #ifdef EMLXS_LITTLE_ENDIAN
363 /* Free the local buffer */
364 kmem_free(local_buffer, len);
365 #endif /* EMLXS_LITTLE_ENDIAN */
366
367 return (rval);
368
369 } /* emlxs_fw_download */
370
371
372 extern void
emlxs_memset(uint8_t * buffer,uint8_t value,uint32_t size)373 emlxs_memset(uint8_t *buffer, uint8_t value, uint32_t size)
374 {
375 while (size--) {
376 *buffer++ = value;
377 }
378
379 } /* emlxs_memset () */
380
381
382 static int32_t
emlxs_be_flash_image(emlxs_hba_t * hba,caddr_t buffer,emlxs_be_fw_file_t * file,MAILBOXQ * mbq,MATCHMAP * mp)383 emlxs_be_flash_image(emlxs_hba_t *hba, caddr_t buffer,
384 emlxs_be_fw_file_t *file, MAILBOXQ *mbq, MATCHMAP *mp)
385 {
386 emlxs_port_t *port = &PPORT;
387 uint8_t *image_ptr;
388 uint32_t *wptr;
389 uint8_t *payload;
390 MAILBOX4 *mb;
391 IOCTL_COMMON_FLASHROM *flashrom;
392 mbox_req_hdr_t *hdr_req;
393 uint32_t image_size;
394 uint32_t block_size;
395 uint32_t xfer_size;
396 uint32_t block_offset;
397 uint32_t count;
398 uint32_t rval = 0;
399
400 if (file->image_size == 0) {
401 return (0);
402 }
403
404 image_ptr = (uint8_t *)buffer + file->image_offset;
405 image_size = file->image_size;
406 block_size = file->block_size;
407 block_offset = 0;
408 mb = (MAILBOX4*)mbq;
409
410 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
411 "%s: Downloading...", file->label);
412
413 while (block_size) {
414 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
415 bzero((void *) mp->virt, mp->size);
416
417 xfer_size = min(BE_MAX_XFER_SIZE, block_size);
418
419 mb->un.varSLIConfig.be.embedded = 0;
420 mbq->nonembed = (void *)mp;
421 mbq->mbox_cmpl = NULL;
422
423 mb->mbxCommand = MBX_SLI_CONFIG;
424 mb->mbxOwner = OWN_HOST;
425
426 hdr_req = (mbox_req_hdr_t *)mp->virt;
427 hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON;
428 hdr_req->opcode = COMMON_OPCODE_WRITE_FLASHROM;
429 hdr_req->timeout = 0;
430 hdr_req->req_length = sizeof (IOCTL_COMMON_FLASHROM) +
431 xfer_size;
432
433 flashrom = (IOCTL_COMMON_FLASHROM *)(hdr_req + 1);
434
435 if (file->type == MGMT_FLASHROM_OPTYPE_PHY_FIRMWARE) {
436 flashrom->params.opcode = ((block_size == xfer_size)?
437 MGMT_PHY_FLASHROM_OPCODE_FLASH:
438 MGMT_PHY_FLASHROM_OPCODE_SAVE);
439 flashrom->params.optype = 0; /* ignored */
440 } else {
441 flashrom->params.opcode = ((block_size == xfer_size)?
442 MGMT_FLASHROM_OPCODE_FLASH:
443 MGMT_FLASHROM_OPCODE_SAVE);
444 flashrom->params.optype = file->type;
445 }
446
447 flashrom->params.data_buffer_size = xfer_size;
448 flashrom->params.offset = block_offset;
449
450 /* Build data buffer payload */
451 payload = (uint8_t *)(&flashrom->params.data_buffer);
452 emlxs_memset(payload, 0xff, xfer_size);
453
454 /* Copy remaining image into payload */
455 if (image_size) {
456 count = min(image_size, xfer_size);
457 BE_SWAP32_BCOPY(image_ptr, payload, count);
458 image_size -= count;
459 image_ptr += count;
460 }
461
462 if ((flashrom->params.opcode == MGMT_FLASHROM_OPCODE_FLASH) ||
463 (flashrom->params.opcode ==
464 MGMT_PHY_FLASHROM_OPCODE_FLASH)) {
465 wptr = (uint32_t *)&payload[(xfer_size - 12)];
466
467 wptr[0] = file->load_address;
468 wptr[1] = file->image_size;
469 wptr[2] = file->block_crc;
470 }
471
472 /* Send write request */
473 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
474 MBX_SUCCESS) {
475 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
476 "%s: Unable to download image. status=%x",
477 file->label, mb->mbxStatus);
478 rval = EMLXS_IMAGE_FAILED;
479 goto done;
480 }
481
482 block_size -= xfer_size;
483 block_offset += xfer_size;
484 }
485
486 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
487 "%s: Download complete.", file->label);
488 done:
489
490 return (rval);
491
492 } /* emlxs_be_flash_image() */
493
494
495
496
497 static int32_t
emlxs_be_verify_crc(emlxs_hba_t * hba,emlxs_be_fw_file_t * file,MAILBOXQ * mbq,MATCHMAP * mp)498 emlxs_be_verify_crc(emlxs_hba_t *hba,
499 emlxs_be_fw_file_t *file, MAILBOXQ *mbq, MATCHMAP *mp)
500 {
501 emlxs_port_t *port = &PPORT;
502 uint32_t *wptr;
503 uint8_t *payload;
504 MAILBOX4 *mb;
505 IOCTL_COMMON_FLASHROM *flashrom;
506 mbox_req_hdr_t *hdr_req;
507 uint32_t xfer_size;
508 uint32_t block_offset;
509 uint32_t rval = 0;
510 uint32_t value;
511
512 if (file->type == MGMT_FLASHROM_OPTYPE_PHY_FIRMWARE) {
513 /* PHY Firmware can't be verified */
514 return (1);
515 }
516
517 xfer_size = 8;
518 block_offset = file->block_size - xfer_size;
519 mb = (MAILBOX4*)mbq;
520
521 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
522 "%s: Verifying CRC...", file->label);
523
524 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
525 bzero((void *) mp->virt, mp->size);
526
527 mb->un.varSLIConfig.be.embedded = 0;
528 mbq->nonembed = (void *)mp;
529 mbq->mbox_cmpl = NULL;
530
531 mb->mbxCommand = MBX_SLI_CONFIG;
532 mb->mbxOwner = OWN_HOST;
533
534 hdr_req = (mbox_req_hdr_t *)mp->virt;
535 hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON;
536 hdr_req->opcode = COMMON_OPCODE_READ_FLASHROM;
537 hdr_req->timeout = 0;
538 hdr_req->req_length = sizeof (IOCTL_COMMON_FLASHROM) +
539 xfer_size;
540
541 flashrom = (IOCTL_COMMON_FLASHROM *)(hdr_req + 1);
542 flashrom->params.opcode = MGMT_FLASHROM_OPCODE_REPORT;
543 flashrom->params.optype = file->type;
544 flashrom->params.data_buffer_size = xfer_size;
545 flashrom->params.offset = block_offset;
546
547 /* Send read request */
548 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
549 MBX_SUCCESS) {
550 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
551 "%s: Unable to read CRC. status=%x",
552 file->label, mb->mbxStatus);
553
554 rval = 2;
555 goto done;
556 }
557
558 payload = (uint8_t *)(&flashrom->params.data_buffer);
559 wptr = (uint32_t *)(payload + xfer_size - 8);
560
561 /* Verify image size */
562 value = *wptr++;
563 if (value != file->image_size) {
564 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
565 "%s: Image size mismatch. %08x != %08x",
566 file->label, value, file->image_size);
567
568 rval = 1;
569 goto done;
570 }
571
572 /* Verify block crc */
573 value = *wptr;
574 if (value != file->block_crc) {
575 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
576 "%s: CRC mismatch. %08x != %08x",
577 file->label, value, file->block_crc);
578 rval = 1;
579 }
580
581 done:
582
583 if (rval == 0) {
584 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
585 "%s: CRC verified.", file->label);
586 }
587
588 return (rval);
589
590 } /* emlxs_be_verify_crc() */
591
592
593 static int32_t
emlxs_be_verify_phy(emlxs_hba_t * hba,emlxs_be_fw_file_t * file,MAILBOXQ * mbq,MATCHMAP * mp)594 emlxs_be_verify_phy(emlxs_hba_t *hba,
595 emlxs_be_fw_file_t *file, MAILBOXQ *mbq, MATCHMAP *mp)
596 {
597 emlxs_port_t *port = &PPORT;
598 MAILBOX4 *mb;
599 IOCTL_COMMON_GET_PHY_DETAILS *phy;
600 mbox_req_hdr_t *hdr_req;
601 uint32_t rval = 0;
602
603 if (file->type != MGMT_FLASHROM_OPTYPE_PHY_FIRMWARE) {
604 return (1);
605 }
606
607 mb = (MAILBOX4*)mbq;
608
609 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
610 "%s: Getting PHY Details...", file->label);
611
612 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
613 bzero((void *) mp->virt, mp->size);
614
615 mb->un.varSLIConfig.be.embedded = 0;
616 mbq->nonembed = (void *)mp;
617 mbq->mbox_cmpl = NULL;
618
619 mb->mbxCommand = MBX_SLI_CONFIG;
620 mb->mbxOwner = OWN_HOST;
621
622 hdr_req = (mbox_req_hdr_t *)mp->virt;
623 hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON;
624 hdr_req->opcode = COMMON_OPCODE_GET_PHY_DETAILS;
625 hdr_req->timeout = 0;
626 hdr_req->req_length = sizeof (IOCTL_COMMON_GET_PHY_DETAILS);
627
628 phy = (IOCTL_COMMON_GET_PHY_DETAILS *)(hdr_req + 1);
629
630 /* Send read request */
631 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
632 MBX_SUCCESS) {
633 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
634 "%s: Unable to get PHY details. status=%x",
635 file->label, mb->mbxStatus);
636
637 rval = 2;
638 goto done;
639 }
640
641 if ((phy->params.response.phy_type != PHY_TN_8022) ||
642 (phy->params.response.interface_type != BASET_10GB_TYPE)) {
643 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
644 "%s: PHY not applicable. %08x,%08x",
645 file->label,
646 phy->params.response.phy_type,
647 phy->params.response.interface_type);
648
649 rval = 1;
650 }
651
652 done:
653
654 if (rval == 0) {
655 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
656 "%s: PHY verified. %x,%x",
657 file->label,
658 phy->params.response.phy_type,
659 phy->params.response.interface_type);
660 }
661
662 return (rval);
663
664 } /* emlxs_be_verify_phy() */
665
666
667 extern int32_t
emlxs_be_read_fw_version(emlxs_hba_t * hba,emlxs_firmware_t * fw)668 emlxs_be_read_fw_version(emlxs_hba_t *hba, emlxs_firmware_t *fw)
669 {
670 emlxs_port_t *port = &PPORT;
671 MAILBOXQ *mbq = NULL;
672 MATCHMAP *mp = NULL;
673 MAILBOX4 *mb;
674 uint32_t *wptr;
675 uint8_t *payload;
676 IOCTL_COMMON_FLASHROM *flashrom;
677 mbox_req_hdr_t *hdr_req;
678 uint32_t xfer_size;
679 uint32_t block_offset;
680 uint32_t rval = 0;
681
682 bzero((void *) fw, sizeof (emlxs_firmware_t));
683
684 if ((mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
685 KM_SLEEP)) == NULL) {
686 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
687 "read_fw_version: Unable to allocate mailbox buffer.");
688
689 rval = 1;
690 goto done;
691 }
692
693 if ((mp = emlxs_mem_buf_alloc(hba, (sizeof (mbox_req_hdr_t) +
694 sizeof (IOCTL_COMMON_FLASHROM) + 32))) == NULL) {
695 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
696 "read_fw_version: Unable to allocate payload buffer.");
697
698 rval = EMLXS_IMAGE_FAILED;
699 goto done;
700 }
701
702 mb = (MAILBOX4*)mbq;
703
704 /* Read CRC and size */
705 xfer_size = 8;
706 block_offset = 0x140000 - xfer_size;
707
708 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
709 bzero((void *) mp->virt, mp->size);
710
711 mb->un.varSLIConfig.be.embedded = 0;
712 mbq->nonembed = (void *)mp;
713 mbq->mbox_cmpl = NULL;
714
715 mb->mbxCommand = MBX_SLI_CONFIG;
716 mb->mbxOwner = OWN_HOST;
717
718 hdr_req = (mbox_req_hdr_t *)mp->virt;
719 hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON;
720 hdr_req->opcode = COMMON_OPCODE_READ_FLASHROM;
721 hdr_req->timeout = 0;
722 hdr_req->req_length = sizeof (IOCTL_COMMON_FLASHROM) +
723 xfer_size;
724
725 flashrom = (IOCTL_COMMON_FLASHROM *)(hdr_req + 1);
726 flashrom->params.opcode = MGMT_FLASHROM_OPCODE_REPORT;
727 flashrom->params.optype = MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE;
728 flashrom->params.data_buffer_size = xfer_size;
729 flashrom->params.offset = block_offset;
730
731 /* Send read request */
732 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
733 MBX_SUCCESS) {
734 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
735 "read_fw_version: Unable to read CRC. status=%x",
736 mb->mbxStatus);
737
738 rval = 1;
739 goto done;
740 }
741
742 payload = (uint8_t *)(&flashrom->params.data_buffer);
743
744 wptr = (uint32_t *)payload;
745 fw->size = *wptr++; /* image size */
746 fw->sli4 = *wptr; /* block crc */
747 fw->kern = *wptr;
748 fw->stub = *wptr;
749
750 /* Read version label */
751 xfer_size = 32;
752 block_offset = 0x30;
753
754 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
755 bzero((void *) mp->virt, mp->size);
756
757 mb->un.varSLIConfig.be.embedded = 0;
758 mbq->nonembed = (void *)mp;
759 mbq->mbox_cmpl = NULL;
760
761 mb->mbxCommand = MBX_SLI_CONFIG;
762 mb->mbxOwner = OWN_HOST;
763
764 hdr_req = (mbox_req_hdr_t *)mp->virt;
765 hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON;
766 hdr_req->opcode = COMMON_OPCODE_READ_FLASHROM;
767 hdr_req->timeout = 0;
768 hdr_req->req_length = sizeof (IOCTL_COMMON_FLASHROM) +
769 xfer_size;
770
771 flashrom = (IOCTL_COMMON_FLASHROM *)(hdr_req + 1);
772 flashrom->params.opcode = MGMT_FLASHROM_OPCODE_REPORT;
773 flashrom->params.optype = MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE;
774 flashrom->params.data_buffer_size = xfer_size;
775 flashrom->params.offset = block_offset;
776
777 /* Send read request */
778 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
779 MBX_SUCCESS) {
780 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
781 "read_fw_version: Unable to read version string. status=%x",
782 mb->mbxStatus);
783
784 rval = 1;
785 goto done;
786 }
787
788 payload = (uint8_t *)(&flashrom->params.data_buffer);
789 BE_SWAP32_BCOPY(payload, (uint8_t *)fw->label, 32);
790
791 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
792 "FCOE FIRMWARE: size=%x version=%s (0x%08x)",
793 fw->size, fw->label, fw->sli4);
794
795 done:
796
797 if (mbq) {
798 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
799 }
800
801 if (mp) {
802 emlxs_mem_buf_free(hba, mp);
803 }
804
805 return (rval);
806
807 } /* emlxs_be_read_fw_version() */
808
809
810 static uint32_t
emlxs_be_version(caddr_t buffer,uint32_t size,uint32_t * plus_flag)811 emlxs_be_version(caddr_t buffer, uint32_t size, uint32_t *plus_flag)
812 {
813 emlxs_be2_ufi_header_t *ufi_hdr;
814 char signature[BE2_SIGNATURE_SIZE];
815 uint32_t be_version = 0;
816
817 if (size < sizeof (emlxs_be2_ufi_header_t)) {
818 return (0);
819 }
820 ufi_hdr = (emlxs_be2_ufi_header_t *)buffer;
821
822 (void) snprintf(signature, BE2_SIGNATURE_SIZE, "%s+", BE_SIGNATURE);
823
824 /* Check if this is a UFI image */
825 if (strncmp(signature, (char *)ufi_hdr->signature,
826 strlen(BE_SIGNATURE)) != 0) {
827 return (0);
828 }
829
830 /* Check if this is a UFI plus image */
831 if (plus_flag) {
832 /* Check if this is a UFI plus image */
833 if (strncmp(signature, (char *)ufi_hdr->signature,
834 strlen(BE_SIGNATURE)+1) == 0) {
835 *plus_flag = 1;
836 } else {
837 *plus_flag = 0;
838 }
839 }
840
841 if ((ufi_hdr->build[0] >= '1') && (ufi_hdr->build[0] <= '9')) {
842 be_version = ufi_hdr->build[0] - '0';
843 }
844
845 return (be_version);
846
847 } /* emlxs_be_version() */
848
849
850 static uint32_t
emlxs_be2_validate_image(emlxs_hba_t * hba,caddr_t buffer,uint32_t len,emlxs_be_fw_image_t * fw_image)851 emlxs_be2_validate_image(emlxs_hba_t *hba, caddr_t buffer,
852 uint32_t len, emlxs_be_fw_image_t *fw_image)
853 {
854 emlxs_port_t *port = &PPORT;
855 emlxs_be2_ufi_header_t *ufi_hdr;
856 emlxs_be2_flash_dir_t *flash_dir;
857 emlxs_be2_flash_entry_t *entry;
858 uint8_t *bptr;
859 uint32_t *wptr;
860 uint32_t i;
861 uint32_t k;
862 uint32_t mask;
863 uint32_t value;
864 uint32_t image_size;
865 emlxs_be_fw_file_t *file;
866 emlxs_be_fw_file_t *file2;
867 uint32_t ufi_plus = 0;
868 uint32_t be_version = 0;
869 uint32_t found;
870
871 bzero(fw_image, sizeof (emlxs_be_fw_image_t));
872
873 if (hba->model_info.chip != EMLXS_BE2_CHIP) {
874 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
875 "Invalid adapter model.");
876 return (EMLXS_IMAGE_INCOMPATIBLE);
877 }
878
879 if (len < (sizeof (emlxs_be2_ufi_header_t) +
880 sizeof (emlxs_be2_flash_dir_t))) {
881 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
882 "Image too small. (%d < %d)",
883 len, (sizeof (emlxs_be2_ufi_header_t) +
884 sizeof (emlxs_be2_flash_dir_t)));
885 return (EMLXS_IMAGE_BAD);
886 }
887
888 be_version = emlxs_be_version(buffer, len, &ufi_plus);
889
890 /* Check if this is a standard BE2 image */
891 if (be_version != 2) {
892 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
893 "Invalid image provided.");
894 return (EMLXS_IMAGE_INCOMPATIBLE);
895 }
896
897 ufi_hdr = (emlxs_be2_ufi_header_t *)buffer;
898
899 #ifdef EMLXS_BIG_ENDIAN
900 /* Big Endian Swapping */
901 /* Swap ufi header */
902 ufi_hdr->checksum =
903 SWAP32(ufi_hdr->checksum);
904 ufi_hdr->antidote =
905 SWAP32(ufi_hdr->antidote);
906 ufi_hdr->controller.vendor_id =
907 SWAP32(ufi_hdr->controller.vendor_id);
908 ufi_hdr->controller.device_id =
909 SWAP32(ufi_hdr->controller.device_id);
910 ufi_hdr->controller.sub_vendor_id =
911 SWAP32(ufi_hdr->controller.sub_vendor_id);
912 ufi_hdr->controller.sub_device_id =
913 SWAP32(ufi_hdr->controller.sub_device_id);
914 ufi_hdr->file_length =
915 SWAP32(ufi_hdr->file_length);
916 ufi_hdr->chunk_num =
917 SWAP32(ufi_hdr->chunk_num);
918 ufi_hdr->chunk_cnt =
919 SWAP32(ufi_hdr->chunk_cnt);
920 ufi_hdr->image_cnt =
921 SWAP32(ufi_hdr->image_cnt);
922 #endif /* EMLXS_BIG_ENDIAN */
923
924 if (len != ufi_hdr->file_length) {
925 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
926 "Invalid image size (%d != %d)",
927 len, ufi_hdr->file_length);
928
929 return (EMLXS_IMAGE_BAD);
930 }
931
932 /* Scan for flash dir signature */
933 bptr = (uint8_t *)buffer;
934 flash_dir = NULL;
935 for (i = 0; i < len; i++, bptr++) {
936 if (strncmp((char *)bptr, BE_DIR_SIGNATURE,
937 sizeof (BE_DIR_SIGNATURE)) == 0) {
938 flash_dir = (emlxs_be2_flash_dir_t *)bptr;
939 break;
940 }
941 }
942
943 if (!flash_dir) {
944 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
945 "Unable to find flash directory.");
946
947 return (EMLXS_IMAGE_BAD);
948 }
949
950 #ifdef EMLXS_BIG_ENDIAN
951 /* Big Endian Swapping */
952 /* Swap flash dir */
953 flash_dir->header.format_rev =
954 SWAP32(flash_dir->header.format_rev);
955 flash_dir->header.checksum =
956 SWAP32(flash_dir->header.checksum);
957 flash_dir->header.antidote =
958 SWAP32(flash_dir->header.antidote);
959 flash_dir->header.build_num =
960 SWAP32(flash_dir->header.build_num);
961 flash_dir->header.active_entry_mask =
962 SWAP32(flash_dir->header.active_entry_mask);
963 flash_dir->header.valid_entry_mask =
964 SWAP32(flash_dir->header.valid_entry_mask);
965 flash_dir->header.orig_content_mask =
966 SWAP32(flash_dir->header.orig_content_mask);
967 flash_dir->header.resv0 = SWAP32(flash_dir->header.resv0);
968 flash_dir->header.resv1 = SWAP32(flash_dir->header.resv1);
969 flash_dir->header.resv2 = SWAP32(flash_dir->header.resv2);
970 flash_dir->header.resv3 = SWAP32(flash_dir->header.resv3);
971 flash_dir->header.resv4 = SWAP32(flash_dir->header.resv4);
972
973 for (i = 0; i < BE_CONTROLLER_SIZE; i++) {
974 flash_dir->header.controller[i].vendor_id =
975 SWAP32(flash_dir->header.controller[i].vendor_id);
976 flash_dir->header.controller[i].device_id =
977 SWAP32(flash_dir->header.controller[i].device_id);
978 flash_dir->header.controller[i].sub_vendor_id =
979 SWAP32(flash_dir->header.controller[i].sub_vendor_id);
980 flash_dir->header.controller[i].sub_device_id =
981 SWAP32(flash_dir->header.controller[i].sub_device_id);
982 }
983
984 for (i = 0, mask = 1; i < BE_FLASH_ENTRIES; i++, mask <<= 1) {
985
986 if (!(flash_dir->header.valid_entry_mask & mask)) {
987 continue;
988 }
989
990 entry = &flash_dir->entry[i];
991
992 if ((entry->type == 0) ||
993 (entry->type == (uint32_t)-1) ||
994 (entry->image_size == 0)) {
995 continue;
996 }
997
998 flash_dir->entry[i].type =
999 SWAP32(flash_dir->entry[i].type);
1000 flash_dir->entry[i].offset =
1001 SWAP32(flash_dir->entry[i].offset);
1002 flash_dir->entry[i].pad_size =
1003 SWAP32(flash_dir->entry[i].pad_size);
1004 flash_dir->entry[i].image_size =
1005 SWAP32(flash_dir->entry[i].image_size);
1006 flash_dir->entry[i].checksum =
1007 SWAP32(flash_dir->entry[i].checksum);
1008 flash_dir->entry[i].entry_point =
1009 SWAP32(flash_dir->entry[i].entry_point);
1010 flash_dir->entry[i].resv0 =
1011 SWAP32(flash_dir->entry[i].resv0);
1012 flash_dir->entry[i].resv1 =
1013 SWAP32(flash_dir->entry[i].resv1);
1014 }
1015 #endif /* EMLXS_BIG_ENDIAN */
1016
1017 /* Verify adapter model */
1018 found = 0;
1019 for (i = 0; i < BE_CONTROLLER_SIZE; i++) {
1020 if (flash_dir->header.controller[i].device_id ==
1021 hba->model_info.device_id) {
1022 found = 1;
1023 }
1024 }
1025
1026 if (!found) {
1027 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
1028 "Invalid adapter device id=0x%x.",
1029 hba->model_info.device_id);
1030 return (EMLXS_IMAGE_INCOMPATIBLE);
1031 }
1032
1033 /* Build fw_image table */
1034 fw_image->be_version = 2;
1035 fw_image->ufi_plus = ufi_plus;
1036 for (i = 0, mask = 1; i < BE_FLASH_ENTRIES; i++, mask <<= 1) {
1037
1038 if (!(flash_dir->header.valid_entry_mask & mask)) {
1039 continue;
1040 }
1041
1042 entry = &flash_dir->entry[i];
1043
1044 if ((entry->type == 0) ||
1045 (entry->type == (uint32_t)-1) ||
1046 (entry->image_size == 0)) {
1047 continue;
1048 }
1049
1050 switch (entry->type) {
1051 case BE_FLASHTYPE_REDBOOT:
1052 file = &fw_image->file[REDBOOT_FLASHTYPE];
1053 (void) strlcpy(file->label, "REDBOOT",
1054 sizeof (file->label));
1055 file->type = MGMT_FLASHROM_OPTYPE_REDBOOT;
1056 break;
1057 case BE_FLASHTYPE_ISCSI_BIOS:
1058 file = &fw_image->file[ISCSI_BIOS_FLASHTYPE];
1059 (void) strlcpy(file->label, "ISCSI BIOS",
1060 sizeof (file->label));
1061 file->type = MGMT_FLASHROM_OPTYPE_ISCSI_BIOS;
1062 break;
1063 case BE_FLASHTYPE_PXE_BIOS:
1064 file = &fw_image->file[PXE_BIOS_FLASHTYPE];
1065 (void) strlcpy(file->label, "PXE BIOS",
1066 sizeof (file->label));
1067 file->type = MGMT_FLASHROM_OPTYPE_PXE_BIOS;
1068 break;
1069 case BE_FLASHTYPE_FCOE_BIOS:
1070 file = &fw_image->file[FCOE_BIOS_FLASHTYPE];
1071 (void) strlcpy(file->label, "FCOE BIOS",
1072 sizeof (file->label));
1073 file->type = MGMT_FLASHROM_OPTYPE_FCOE_BIOS;
1074 break;
1075 case BE_FLASHTYPE_ISCSI_FIRMWARE:
1076 file = &fw_image->file[ISCSI_FIRMWARE_FLASHTYPE];
1077 (void) strlcpy(file->label, "ISCSI FIRMWARE",
1078 sizeof (file->label));
1079 file->type = MGMT_FLASHROM_OPTYPE_ISCSI_FIRMWARE;
1080 break;
1081 case BE_FLASHTYPE_FCOE_FIRMWARE:
1082 file = &fw_image->file[FCOE_FIRMWARE_FLASHTYPE];
1083 (void) strlcpy(file->label, "FCOE FIRMWARE",
1084 sizeof (file->label));
1085 file->type = MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE;
1086 break;
1087 case BE_FLASHTYPE_FCOE_BACKUP:
1088 case BE_FLASHTYPE_ISCSI_BACKUP:
1089 continue;
1090
1091 default:
1092 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
1093 "Unknown image type found. type=%x",
1094 entry->type);
1095 continue;
1096 }
1097
1098 file->be_version = fw_image->be_version;
1099 file->ufi_plus = fw_image->ufi_plus;
1100 file->image_size = entry->image_size;
1101 image_size = BE_SWAP32(entry->image_size);
1102
1103 if (ufi_plus) {
1104 file->image_offset = entry->offset;
1105 file->block_size = entry->pad_size;
1106 file->block_crc = entry->checksum;
1107 file->load_address = entry->entry_point;
1108
1109 } else {
1110 file->image_offset = entry->offset +
1111 sizeof (emlxs_be2_ufi_header_t);
1112
1113 /* Get entry block size and crc */
1114 k = file->image_offset + file->image_size;
1115 k &= 0xFFFFFFFC;
1116
1117 wptr = (uint32_t *)(buffer + k);
1118 for (; k < len; k += 4) {
1119 if (*wptr++ == image_size) {
1120 /* Calculate block_size */
1121 file->block_size = (k + 8) -
1122 file->image_offset;
1123
1124 /* Read load_address */
1125 value = *(wptr - 2);
1126 file->load_address = BE_SWAP32(value);
1127
1128 /* Read block_crc */
1129 value = *wptr;
1130 file->block_crc = BE_SWAP32(value);
1131
1132 break;
1133 }
1134 }
1135
1136 if (k >= len) {
1137 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
1138 "%s: End of block not found. offset=%x",
1139 file->label, file->image_offset);
1140
1141 bzero(fw_image, sizeof (emlxs_be_fw_image_t));
1142 return (EMLXS_IMAGE_BAD);
1143 }
1144 }
1145
1146 /* Make sure image will fit in block specified */
1147 if (file->image_size + 12 > file->block_size) {
1148 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
1149 "%s: Image too large for block. image=%x block=%x",
1150 file->label, file->image_size, file->block_size);
1151
1152 bzero(fw_image, sizeof (emlxs_be_fw_image_t));
1153 return (EMLXS_IMAGE_BAD);
1154 }
1155
1156 /* Automatically create a backup file entry for firmware */
1157 if (file->type == MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE) {
1158 file2 = &fw_image->file[FCOE_BACKUP_FLASHTYPE];
1159
1160 bcopy((uint8_t *)file, (uint8_t *)file2,
1161 sizeof (emlxs_be_fw_file_t));
1162 file2->type = MGMT_FLASHROM_OPTYPE_FCOE_BACKUP;
1163 (void) strlcpy(file2->label, "FCOE BACKUP",
1164 sizeof (file2->label));
1165
1166 /* Save FCOE version info */
1167 bptr = (uint8_t *)buffer + file->image_offset + 0x30;
1168 (void) strncpy(fw_image->fcoe_label, (char *)bptr,
1169 BE_VERSION_SIZE);
1170 fw_image->fcoe_version = file->block_crc;
1171
1172 } else if (file->type ==
1173 MGMT_FLASHROM_OPTYPE_ISCSI_FIRMWARE) {
1174 file2 = &fw_image->file[ISCSI_BACKUP_FLASHTYPE];
1175
1176 bcopy((uint8_t *)file, (uint8_t *)file2,
1177 sizeof (emlxs_be_fw_file_t));
1178 file2->type = MGMT_FLASHROM_OPTYPE_ISCSI_BACKUP;
1179 (void) strlcpy(file2->label, "ISCSI BACKUP",
1180 sizeof (file2->label));
1181
1182 /* Save ISCSI version info */
1183 bptr = (uint8_t *)buffer + file->image_offset + 0x30;
1184 (void) strncpy(fw_image->iscsi_label, (char *)bptr,
1185 BE_VERSION_SIZE);
1186 fw_image->iscsi_version = file->block_crc;
1187 }
1188 }
1189
1190 if (fw_image->fcoe_version == 0) {
1191 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
1192 "Unable to find FCOE firmware component.");
1193
1194 bzero(fw_image, sizeof (emlxs_be_fw_image_t));
1195 return (EMLXS_IMAGE_BAD);
1196 }
1197
1198 /* Display contents */
1199 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
1200 "BE2 UFI Image: %08x, %s", fw_image->fcoe_version,
1201 fw_image->fcoe_label);
1202
1203 for (i = 0; i < BE_MAX_FLASHTYPES; i++) {
1204 file = &fw_image->file[i];
1205
1206 if (file->image_size == 0) {
1207 continue;
1208 }
1209
1210 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
1211 "%s: be=%x%s type=%x block=%x image=%x offset=%x crc=%x "
1212 "load=%x",
1213 file->label, file->be_version, (file->ufi_plus)?"+":"",
1214 file->type, file->block_size, file->image_size,
1215 file->image_offset, file->block_crc, file->load_address);
1216 }
1217
1218 return (0);
1219
1220 } /* emlxs_be2_validate_image() */
1221
1222
1223 static uint32_t
emlxs_be3_validate_image(emlxs_hba_t * hba,caddr_t buffer,uint32_t len,emlxs_be_fw_image_t * fw_image)1224 emlxs_be3_validate_image(emlxs_hba_t *hba, caddr_t buffer,
1225 uint32_t len, emlxs_be_fw_image_t *fw_image)
1226 {
1227 emlxs_port_t *port = &PPORT;
1228 emlxs_be3_ufi_header_t *ufi_hdr;
1229 emlxs_be3_flash_dir_t *flash_dir;
1230 emlxs_be3_flash_entry_t *entry;
1231 emlxs_be3_image_header_t *flash_image_hdr;
1232 emlxs_be3_image_header_t *image_hdr;
1233 uint8_t *bptr;
1234 uint32_t *wptr;
1235 uint32_t i;
1236 uint32_t value;
1237 emlxs_be_fw_file_t *file;
1238 emlxs_be_fw_file_t *file2;
1239 uint32_t ufi_plus = 0;
1240 uint32_t be_version = 0;
1241 uint32_t found;
1242
1243 bzero(fw_image, sizeof (emlxs_be_fw_image_t));
1244
1245 if (hba->model_info.chip != EMLXS_BE3_CHIP) {
1246 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
1247 "Invalid adapter model.");
1248 return (EMLXS_IMAGE_INCOMPATIBLE);
1249 }
1250
1251 if (len < (sizeof (emlxs_be3_ufi_header_t) +
1252 sizeof (emlxs_be3_flash_dir_t))) {
1253 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
1254 "Image too small. (%d < %d)",
1255 len, (sizeof (emlxs_be3_ufi_header_t) +
1256 sizeof (emlxs_be3_flash_dir_t)));
1257 return (EMLXS_IMAGE_BAD);
1258 }
1259
1260 be_version = emlxs_be_version(buffer, len, &ufi_plus);
1261
1262 /* Check if this is a standard BE3 image */
1263 if (be_version != 3) {
1264 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
1265 "Invalid image provided.");
1266 return (EMLXS_IMAGE_INCOMPATIBLE);
1267 }
1268
1269 ufi_hdr = (emlxs_be3_ufi_header_t *)buffer;
1270
1271 #ifdef EMLXS_BIG_ENDIAN
1272 /* Big Endian Swapping */
1273 /* Swap ufi header */
1274 ufi_hdr->ufi_version =
1275 SWAP32(ufi_hdr->ufi_version);
1276 ufi_hdr->file_length =
1277 SWAP32(ufi_hdr->file_length);
1278 ufi_hdr->checksum =
1279 SWAP32(ufi_hdr->checksum);
1280 ufi_hdr->antidote =
1281 SWAP32(ufi_hdr->antidote);
1282 ufi_hdr->image_cnt =
1283 SWAP32(ufi_hdr->image_cnt);
1284 #endif /* EMLXS_BIG_ENDIAN */
1285
1286 if (len != ufi_hdr->file_length) {
1287 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
1288 "Invalid image size (%d != %d)",
1289 len, ufi_hdr->file_length);
1290
1291 return (EMLXS_IMAGE_BAD);
1292 }
1293
1294 flash_image_hdr = NULL;
1295 image_hdr = (emlxs_be3_image_header_t *)(buffer +
1296 sizeof (emlxs_be3_ufi_header_t));
1297 for (i = 0; i < ufi_hdr->image_cnt; i++, image_hdr++) {
1298 #ifdef EMLXS_BIG_ENDIAN
1299 image_hdr->id = SWAP32(image_hdr->id);
1300 image_hdr->offset = SWAP32(image_hdr->offset);
1301 image_hdr->length = SWAP32(image_hdr->length);
1302 image_hdr->checksum = SWAP32(image_hdr->checksum);
1303 #endif /* EMLXS_BIG_ENDIAN */
1304
1305 if (image_hdr->id == UFI_BE3_FLASH_ID) {
1306 flash_image_hdr = image_hdr;
1307 }
1308 }
1309
1310 if (!flash_image_hdr) {
1311 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
1312 "No flash image found.");
1313
1314 return (EMLXS_IMAGE_BAD);
1315 }
1316
1317 /* Scan for flash dir signature */
1318 bptr = (uint8_t *)buffer + flash_image_hdr->offset;
1319 flash_dir = NULL;
1320 for (i = 0; i < flash_image_hdr->length; i++, bptr++) {
1321 if (strncmp((char *)bptr, BE_DIR_SIGNATURE,
1322 sizeof (BE_DIR_SIGNATURE)) == 0) {
1323 flash_dir = (emlxs_be3_flash_dir_t *)bptr;
1324 break;
1325 }
1326 }
1327
1328 if (!flash_dir) {
1329 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
1330 "Unable to find flash directory.");
1331
1332 return (EMLXS_IMAGE_BAD);
1333 }
1334
1335 #ifdef EMLXS_BIG_ENDIAN
1336 /* Big Endian Swapping */
1337 /* Swap flash dir */
1338 flash_dir->header.format_rev =
1339 SWAP32(flash_dir->header.format_rev);
1340 flash_dir->header.checksum =
1341 SWAP32(flash_dir->header.checksum);
1342 flash_dir->header.antidote =
1343 SWAP32(flash_dir->header.antidote);
1344 flash_dir->header.entry_count =
1345 SWAP32(flash_dir->header.entry_count);
1346 flash_dir->header.resv0 = SWAP32(flash_dir->header.resv0);
1347 flash_dir->header.resv1 = SWAP32(flash_dir->header.resv1);
1348 flash_dir->header.resv2 = SWAP32(flash_dir->header.resv2);
1349 flash_dir->header.resv3 = SWAP32(flash_dir->header.resv3);
1350
1351 for (i = 0; i < BE_CONTROLLER_SIZE; i++) {
1352 flash_dir->header.controller[i].vendor_id =
1353 SWAP32(flash_dir->header.controller[i].vendor_id);
1354 flash_dir->header.controller[i].device_id =
1355 SWAP32(flash_dir->header.controller[i].device_id);
1356 flash_dir->header.controller[i].sub_vendor_id =
1357 SWAP32(flash_dir->header.controller[i].sub_vendor_id);
1358 flash_dir->header.controller[i].sub_device_id =
1359 SWAP32(flash_dir->header.controller[i].sub_device_id);
1360 }
1361
1362 for (i = 0; i < flash_dir->header.entry_count; i++) {
1363 entry = &flash_dir->entry[i];
1364
1365 if ((entry->type == 0) ||
1366 (entry->type == (uint32_t)-1) ||
1367 (entry->image_size == 0)) {
1368 continue;
1369 }
1370
1371 flash_dir->entry[i].type =
1372 SWAP32(flash_dir->entry[i].type);
1373 flash_dir->entry[i].offset =
1374 SWAP32(flash_dir->entry[i].offset);
1375 flash_dir->entry[i].block_size =
1376 SWAP32(flash_dir->entry[i].block_size);
1377 flash_dir->entry[i].image_size =
1378 SWAP32(flash_dir->entry[i].image_size);
1379 flash_dir->entry[i].checksum =
1380 SWAP32(flash_dir->entry[i].checksum);
1381 flash_dir->entry[i].entry_point =
1382 SWAP32(flash_dir->entry[i].entry_point);
1383 flash_dir->entry[i].resv0 =
1384 SWAP32(flash_dir->entry[i].resv0);
1385 flash_dir->entry[i].resv1 =
1386 SWAP32(flash_dir->entry[i].resv1);
1387 }
1388 #endif /* EMLXS_BIG_ENDIAN */
1389
1390 /* Verify image checksum */
1391 if (flash_dir->header.checksum != flash_image_hdr->checksum) {
1392 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
1393 "Invalid flash directory checksum. (%x != %x)\n",
1394 flash_dir->header.checksum, flash_image_hdr->checksum);
1395 return (EMLXS_IMAGE_BAD);
1396 }
1397
1398 /* Verify adapter model */
1399 found = 0;
1400 for (i = 0; i < BE_CONTROLLER_SIZE; i++) {
1401 if (flash_dir->header.controller[i].device_id ==
1402 hba->model_info.device_id) {
1403 found = 1;
1404 }
1405 }
1406
1407 if (!found) {
1408 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
1409 "Invalid adapter device id=0x%x.",
1410 hba->model_info.device_id);
1411 return (EMLXS_IMAGE_INCOMPATIBLE);
1412 }
1413
1414 /* Build fw_image table */
1415 fw_image->be_version = 3;
1416 fw_image->ufi_plus = ufi_plus;
1417 for (i = 0; i < flash_dir->header.entry_count; i++) {
1418 entry = &flash_dir->entry[i];
1419
1420 if ((entry->type == 0) ||
1421 (entry->type == (uint32_t)-1) ||
1422 (entry->image_size == 0)) {
1423 continue;
1424 }
1425
1426 switch (entry->type) {
1427 case BE_FLASHTYPE_REDBOOT:
1428 file = &fw_image->file[REDBOOT_FLASHTYPE];
1429 (void) strlcpy(file->label, "REDBOOT",
1430 sizeof (file->label));
1431 file->type = MGMT_FLASHROM_OPTYPE_REDBOOT;
1432 break;
1433 case BE_FLASHTYPE_ISCSI_BIOS:
1434 file = &fw_image->file[ISCSI_BIOS_FLASHTYPE];
1435 (void) strlcpy(file->label, "ISCSI BIOS",
1436 sizeof (file->label));
1437 file->type = MGMT_FLASHROM_OPTYPE_ISCSI_BIOS;
1438 break;
1439 case BE_FLASHTYPE_PXE_BIOS:
1440 file = &fw_image->file[PXE_BIOS_FLASHTYPE];
1441 (void) strlcpy(file->label, "PXE BIOS",
1442 sizeof (file->label));
1443 file->type = MGMT_FLASHROM_OPTYPE_PXE_BIOS;
1444 break;
1445 case BE_FLASHTYPE_FCOE_BIOS:
1446 file = &fw_image->file[FCOE_BIOS_FLASHTYPE];
1447 (void) strlcpy(file->label, "FCOE BIOS",
1448 sizeof (file->label));
1449 file->type = MGMT_FLASHROM_OPTYPE_FCOE_BIOS;
1450 break;
1451 case BE_FLASHTYPE_ISCSI_FIRMWARE:
1452 file = &fw_image->file[ISCSI_FIRMWARE_FLASHTYPE];
1453 (void) strlcpy(file->label, "ISCSI FIRMWARE",
1454 sizeof (file->label));
1455 file->type = MGMT_FLASHROM_OPTYPE_ISCSI_FIRMWARE;
1456 break;
1457 case BE_FLASHTYPE_FCOE_FIRMWARE:
1458 file = &fw_image->file[FCOE_FIRMWARE_FLASHTYPE];
1459 (void) strlcpy(file->label, "FCOE FIRMWARE",
1460 sizeof (file->label));
1461 file->type = MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE;
1462 break;
1463 case BE_FLASHTYPE_NCSI_FIRMWARE:
1464 file = &fw_image->file[NCSI_FIRMWARE_FLASHTYPE];
1465 (void) strlcpy(file->label, "NCSI FIRMWARE",
1466 sizeof (file->label));
1467 file->type = MGMT_FLASHROM_OPTYPE_NCSI_FIRMWARE;
1468 break;
1469 case BE_FLASHTYPE_FLASH_ISM:
1470 case BE_FLASHTYPE_FCOE_BACKUP:
1471 case BE_FLASHTYPE_ISCSI_BACKUP:
1472 continue;
1473 case BE_FLASHTYPE_PHY_FIRMWARE:
1474 file = &fw_image->file[PHY_FIRMWARE_FLASHTYPE];
1475 (void) strlcpy(file->label, "PHY FIRMWARE",
1476 sizeof (file->label));
1477 file->type = MGMT_FLASHROM_OPTYPE_PHY_FIRMWARE;
1478 break;
1479
1480 default:
1481 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
1482 "Unknown image type found. type=%x",
1483 entry->type);
1484 continue;
1485 }
1486
1487 file->be_version = fw_image->be_version;
1488 file->ufi_plus = fw_image->ufi_plus;
1489 file->image_size = entry->image_size;
1490
1491 if (ufi_plus) {
1492 file->image_offset = entry->offset;
1493 file->block_size = entry->block_size;
1494 file->block_crc = entry->checksum;
1495 file->load_address = entry->entry_point;
1496 } else {
1497 file->image_offset = entry->offset +
1498 flash_image_hdr->offset;
1499 file->block_size = entry->block_size;
1500
1501 wptr = (uint32_t *)(buffer + file->image_offset +
1502 file->block_size);
1503
1504 /* Read load address */
1505 value = *(wptr - 3);
1506 file->load_address = BE_SWAP32(value);
1507
1508 /* Read block_crc */
1509 value = *(wptr - 1);
1510 file->block_crc = BE_SWAP32(value);
1511 }
1512
1513 /* Make sure image will fit in block specified */
1514 if (file->image_size + 12 > file->block_size) {
1515 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
1516 "%s: Image too large for block. image=%x block=%x",
1517 file->label, file->image_size, file->block_size);
1518
1519 bzero(fw_image, sizeof (emlxs_be_fw_image_t));
1520 return (EMLXS_IMAGE_BAD);
1521 }
1522
1523 /* Automatically create a backup file entry for firmware */
1524 if (file->type == MGMT_FLASHROM_OPTYPE_FCOE_FIRMWARE) {
1525 file2 = &fw_image->file[FCOE_BACKUP_FLASHTYPE];
1526
1527 bcopy((uint8_t *)file, (uint8_t *)file2,
1528 sizeof (emlxs_be_fw_file_t));
1529 file2->type = MGMT_FLASHROM_OPTYPE_FCOE_BACKUP;
1530 (void) strlcpy(file2->label, "FCOE BACKUP",
1531 sizeof (file2->label));
1532
1533 /* Save FCOE version info */
1534 bptr = (uint8_t *)buffer + file->image_offset + 0x30;
1535 (void) strncpy(fw_image->fcoe_label, (char *)bptr,
1536 BE_VERSION_SIZE);
1537 fw_image->fcoe_version = file->block_crc;
1538
1539 } else if (file->type ==
1540 MGMT_FLASHROM_OPTYPE_ISCSI_FIRMWARE) {
1541 file2 = &fw_image->file[ISCSI_BACKUP_FLASHTYPE];
1542
1543 bcopy((uint8_t *)file, (uint8_t *)file2,
1544 sizeof (emlxs_be_fw_file_t));
1545 file2->type = MGMT_FLASHROM_OPTYPE_ISCSI_BACKUP;
1546 (void) strlcpy(file2->label, "ISCSI BACKUP",
1547 sizeof (file->label));
1548
1549 /* Save ISCSI version info */
1550 bptr = (uint8_t *)buffer + file->image_offset + 0x30;
1551 (void) strncpy(fw_image->iscsi_label, (char *)bptr,
1552 BE_VERSION_SIZE);
1553 fw_image->iscsi_version = file->block_crc;
1554 }
1555 }
1556
1557 if (fw_image->fcoe_version == 0) {
1558 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
1559 "Unable to find FCOE firmware component.");
1560
1561 bzero(fw_image, sizeof (emlxs_be_fw_image_t));
1562 return (EMLXS_IMAGE_BAD);
1563 }
1564
1565 /* Display contents */
1566 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
1567 "BE3 UFI Image: %08x, %s", fw_image->fcoe_version,
1568 fw_image->fcoe_label);
1569
1570 for (i = 0; i < BE_MAX_FLASHTYPES; i++) {
1571 file = &fw_image->file[i];
1572
1573 if (file->image_size == 0) {
1574 continue;
1575 }
1576
1577 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
1578 "%s: be=%x%s type=%x block=%x image=%x offset=%x crc=%x "
1579 "load=%x",
1580 file->label, file->be_version, (file->ufi_plus)? "+":"",
1581 file->type, file->block_size, file->image_size,
1582 file->image_offset, file->block_crc, file->load_address);
1583 }
1584
1585 return (0);
1586
1587 } /* emlxs_be3_validate_image() */
1588
1589
1590 static int32_t
emlxs_be_fw_download(emlxs_hba_t * hba,caddr_t buffer,uint32_t len,uint32_t offline)1591 emlxs_be_fw_download(emlxs_hba_t *hba, caddr_t buffer, uint32_t len,
1592 uint32_t offline)
1593 {
1594 emlxs_port_t *port = &PPORT;
1595 uint32_t i;
1596 uint32_t update = 0;
1597 uint32_t rval = 0;
1598 MAILBOXQ *mbq = NULL;
1599 MATCHMAP *mp = NULL;
1600 emlxs_be_fw_image_t fw_image;
1601 emlxs_be_fw_file_t *file;
1602 uint32_t be_version;
1603
1604 /* For now we will not take the driver offline during a download */
1605 offline = 0;
1606
1607 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) {
1608 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
1609 "Invalid sli_mode. mode=%d", hba->sli_mode);
1610 return (EMLXS_IMAGE_INCOMPATIBLE);
1611 }
1612
1613 if (!(hba->model_info.chip & EMLXS_BE_CHIPS)) {
1614 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
1615 "Invalid adapter model. chip=%x", hba->model_info.chip);
1616 return (EMLXS_IMAGE_INCOMPATIBLE);
1617 }
1618
1619 if (buffer == NULL || len == 0) {
1620 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
1621 "Empty buffer provided. buf=%p size=%d", buffer, len);
1622 return (EMLXS_IMAGE_BAD);
1623 }
1624
1625 be_version = emlxs_be_version(buffer, len, 0);
1626
1627 switch (be_version) {
1628 case 0:
1629 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
1630 "Invalid image provided. Non-UFI format.");
1631 return (EMLXS_IMAGE_INCOMPATIBLE);
1632 case 2:
1633 rval = emlxs_be2_validate_image(hba, buffer, len, &fw_image);
1634 if (rval) {
1635 return (rval);
1636 }
1637 break;
1638 case 3:
1639 rval = emlxs_be3_validate_image(hba, buffer, len, &fw_image);
1640 if (rval) {
1641 return (rval);
1642 }
1643 break;
1644 default:
1645 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
1646 "Invalid image provided. Unknown BE version. (%x)",
1647 be_version);
1648 return (EMLXS_IMAGE_INCOMPATIBLE);
1649 }
1650
1651 /* Allocate resources */
1652
1653 if ((mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
1654 KM_SLEEP)) == NULL) {
1655 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
1656 "Unable to allocate mailbox buffer.");
1657
1658 offline = 0;
1659 rval = EMLXS_IMAGE_FAILED;
1660 goto done;
1661 }
1662
1663 if ((mp = emlxs_mem_buf_alloc(hba, (sizeof (mbox_req_hdr_t) +
1664 sizeof (IOCTL_COMMON_FLASHROM) + BE_MAX_XFER_SIZE))) == NULL) {
1665 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
1666 "Unable to allocate flash buffer.");
1667
1668 offline = 0;
1669 rval = EMLXS_IMAGE_FAILED;
1670 goto done;
1671 }
1672
1673 /* Check if update is required */
1674 for (i = 0; i < BE_MAX_FLASHTYPES; i++) {
1675 file = &fw_image.file[i];
1676
1677 if (file->image_size == 0) {
1678 continue;
1679 }
1680
1681 if (file->type == MGMT_FLASHROM_OPTYPE_PHY_FIRMWARE) {
1682 rval = emlxs_be_verify_phy(hba, file, mbq, mp);
1683
1684 if (rval != 0) {
1685 /* Do not update */
1686 file->image_size = 0;
1687 continue;
1688 }
1689 } else {
1690 rval = emlxs_be_verify_crc(hba, file, mbq, mp);
1691 if (rval == 0) {
1692 /* Do not update */
1693 file->image_size = 0;
1694 continue;
1695 }
1696 }
1697
1698 update++;
1699 }
1700
1701 if (!update) {
1702 offline = 0;
1703 rval = 0;
1704 goto done;
1705 }
1706
1707 /*
1708 * Everything checks out, now to just do it
1709 */
1710 if (offline) {
1711 if (emlxs_offline(hba, 0) != FC_SUCCESS) {
1712
1713 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
1714 "Unable to take adapter offline.");
1715
1716 offline = 0;
1717 rval = EMLXS_OFFLINE_FAILED;
1718 goto done;
1719 }
1720 }
1721
1722 /* Download entries which require update */
1723 for (i = 0; i < BE_MAX_FLASHTYPES; i++) {
1724 file = &fw_image.file[i];
1725
1726 if (file->image_size == 0) {
1727 continue;
1728 }
1729
1730 rval = emlxs_be_flash_image(hba, buffer, file, mbq, mp);
1731
1732 if (rval != 0) {
1733 goto done;
1734 }
1735 }
1736
1737 done:
1738 if (mbq) {
1739 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
1740 }
1741
1742 if (mp) {
1743 emlxs_mem_buf_free(hba, mp);
1744 }
1745
1746 if (offline) {
1747 (void) emlxs_online(hba);
1748 }
1749
1750 if (rval == 0) {
1751 if (update) {
1752 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_complete_msg,
1753 "Status good.");
1754
1755 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_updated_msg,
1756 "The new firmware will not be activated until "
1757 "the adapter is power cycled: %s",
1758 fw_image.fcoe_label);
1759
1760 } else {
1761 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
1762 "No firmware update required.");
1763 }
1764 }
1765
1766 return (rval);
1767
1768 } /* emlxs_be_fw_download() */
1769
1770
1771 static int32_t
emlxs_obj_flash_image(emlxs_hba_t * hba,caddr_t buffer,uint32_t size,MAILBOXQ * mbq,MATCHMAP * mp,uint32_t * change_status)1772 emlxs_obj_flash_image(emlxs_hba_t *hba, caddr_t buffer, uint32_t size,
1773 MAILBOXQ *mbq, MATCHMAP *mp, uint32_t *change_status)
1774 {
1775 emlxs_port_t *port = &PPORT;
1776 uint8_t *image_ptr;
1777 MAILBOX4 *mb;
1778 mbox_req_hdr_t *hdr_req;
1779 mbox_rsp_hdr_t *hdr_rsp;
1780 uint32_t image_size;
1781 uint32_t xfer_size;
1782 uint32_t image_offset;
1783 uint32_t rval = 0;
1784 IOCTL_COMMON_WRITE_OBJECT *write_obj;
1785 uint32_t cstatus = 0;
1786
1787 if (!buffer || size == 0) {
1788 return (0);
1789 }
1790
1791 image_ptr = (uint8_t *)buffer;
1792 image_size = size;
1793 image_offset = 0;
1794 mb = (MAILBOX4*)mbq;
1795
1796 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
1797 "OBJ File: Downloading...");
1798
1799 while (image_size) {
1800 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
1801 bzero((void *) mp->virt, mp->size);
1802
1803 xfer_size = min(OBJ_MAX_XFER_SIZE, image_size);
1804
1805 mb->un.varSLIConfig.be.embedded = 1;
1806 mbq->nonembed = NULL;
1807 mbq->mbox_cmpl = NULL;
1808
1809 mb->mbxCommand = MBX_SLI_CONFIG;
1810 mb->mbxOwner = OWN_HOST;
1811
1812 hdr_req = (mbox_req_hdr_t *)
1813 &mb->un.varSLIConfig.be.un_hdr.hdr_req;
1814 hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON;
1815 hdr_req->opcode = COMMON_OPCODE_WRITE_OBJ;
1816 hdr_req->timeout = 0;
1817
1818 write_obj = (IOCTL_COMMON_WRITE_OBJECT *)(hdr_req + 1);
1819 write_obj->params.request.EOF =
1820 ((xfer_size == image_size)? 1:0);
1821 write_obj->params.request.desired_write_length = xfer_size;
1822 write_obj->params.request.write_offset = image_offset;
1823
1824 (void) strlcpy((char *)write_obj->params.request.object_name,
1825 "/prg", sizeof (write_obj->params.request.object_name));
1826 BE_SWAP32_BUFFER((uint8_t *)
1827 write_obj->params.request.object_name,
1828 sizeof (write_obj->params.request.object_name));
1829
1830 write_obj->params.request.buffer_desc_count = 1;
1831 write_obj->params.request.buffer_length = xfer_size;
1832 write_obj->params.request.buffer_addrlo = PADDR_LO(mp->phys);
1833 write_obj->params.request.buffer_addrhi = PADDR_HI(mp->phys);
1834
1835 hdr_req->req_length = 116 +
1836 (write_obj->params.request.buffer_desc_count * 12);
1837
1838 bcopy(image_ptr, mp->virt, xfer_size);
1839
1840 hdr_rsp = (mbox_rsp_hdr_t *)
1841 &mb->un.varSLIConfig.be.un_hdr.hdr_rsp;
1842 write_obj = (IOCTL_COMMON_WRITE_OBJECT *)(hdr_rsp + 1);
1843
1844 /* Send write request */
1845 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
1846 MBX_SUCCESS) {
1847 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
1848 "OBJ File: Unable to download image. status=%x "
1849 "(%x,%x)",
1850 mb->mbxStatus, hdr_rsp->status,
1851 hdr_rsp->extra_status);
1852
1853 return (EMLXS_IMAGE_FAILED);
1854 }
1855
1856 /* Check header status */
1857 if (hdr_rsp->status) {
1858 if ((hdr_rsp->status == MBX_RSP_STATUS_FAILED) &&
1859 (hdr_rsp->extra_status ==
1860 MGMT_ADDI_STATUS_INCOMPATIBLE)) {
1861 EMLXS_MSGF(EMLXS_CONTEXT,
1862 &emlxs_download_failed_msg,
1863 "OBJ File: Image file incompatible with "
1864 "adapter hardware.");
1865 return (EMLXS_IMAGE_INCOMPATIBLE);
1866 }
1867
1868 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
1869 "OBJ File: Unable to download image. "
1870 "hdr_status=%x,%x size=%d,%d",
1871 hdr_rsp->status, hdr_rsp->extra_status,
1872 write_obj->params.response.actual_write_length,
1873 xfer_size);
1874
1875 return (EMLXS_IMAGE_FAILED);
1876 }
1877
1878 /* Check response length */
1879 if (write_obj->params.response.actual_write_length == 0) {
1880 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
1881 "OBJ File: No data actually written.");
1882
1883 return (EMLXS_IMAGE_FAILED);
1884 }
1885
1886 if (write_obj->params.response.actual_write_length >
1887 xfer_size) {
1888 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
1889 "OBJ File: Mismatch in data xfer size. "
1890 "size=%d,%d offset=%d",
1891 write_obj->params.response.actual_write_length,
1892 xfer_size, image_offset);
1893
1894 return (EMLXS_IMAGE_FAILED);
1895 }
1896
1897 /* Set xfer_size to actual write length */
1898 xfer_size = write_obj->params.response.actual_write_length;
1899
1900 image_ptr += xfer_size;
1901 image_offset += xfer_size;
1902 image_size -= xfer_size;
1903
1904 if (image_size == 0) {
1905 cstatus = write_obj->params.response.change_status;
1906 }
1907 }
1908
1909 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
1910 "OBJ File: Download complete. (cstatus=%d)",
1911 cstatus);
1912
1913 if (change_status) {
1914 *change_status = cstatus;
1915 }
1916
1917 return (rval);
1918
1919 } /* emlxs_obj_flash_image() */
1920
1921
1922 static uint32_t
emlxs_obj_validate_image(emlxs_hba_t * hba,caddr_t buffer,uint32_t len,emlxs_obj_header_t * obj_hdr_in)1923 emlxs_obj_validate_image(emlxs_hba_t *hba, caddr_t buffer, uint32_t len,
1924 emlxs_obj_header_t *obj_hdr_in)
1925 {
1926 emlxs_port_t *port = &PPORT;
1927 emlxs_obj_header_t obj_hdr;
1928
1929 if (obj_hdr_in) {
1930 bzero(obj_hdr_in, sizeof (emlxs_obj_header_t));
1931 }
1932
1933 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) {
1934 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
1935 "Invalid sli_mode. mode=%d", hba->sli_mode);
1936 return (EMLXS_IMAGE_INCOMPATIBLE);
1937 }
1938
1939 if (hba->model_info.chip & EMLXS_BE_CHIPS) {
1940 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
1941 "Invalid adapter model. chip=%x", hba->model_info.chip);
1942 return (EMLXS_IMAGE_INCOMPATIBLE);
1943 }
1944
1945 if (len < sizeof (emlxs_obj_header_t)) {
1946 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
1947 "Image too small. (%d < %d)",
1948 len, sizeof (emlxs_obj_header_t));
1949
1950 return (EMLXS_IMAGE_BAD);
1951 }
1952
1953 bcopy(buffer, (uint8_t *)&obj_hdr, sizeof (emlxs_obj_header_t));
1954
1955 /* Swap first 3 words */
1956 LE_SWAP32_BUFFER((uint8_t *)&obj_hdr, 12);
1957
1958 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
1959 "Object Header: size=%d magic=%04x,%04x type=%02x id=%02x",
1960 obj_hdr.FileSize,
1961 obj_hdr.MagicNumHi, obj_hdr.MagicNumLo,
1962 obj_hdr.FileType,
1963 obj_hdr.Id);
1964
1965 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
1966 "Object Header: Date=%s Rev=%s",
1967 obj_hdr.Date,
1968 obj_hdr.Revision);
1969
1970 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
1971 "Object Header: Name=%s",
1972 obj_hdr.RevName);
1973
1974 if ((obj_hdr.MagicNumHi != OBJ_MAGIC_NUM_HI) ||
1975 (obj_hdr.MagicNumLo != OBJ_MAGIC_NUM_LO)) {
1976 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
1977 "Wrong Magic Number: %x,%x",
1978 obj_hdr.MagicNumHi, obj_hdr.MagicNumLo);
1979
1980 return (EMLXS_IMAGE_INCOMPATIBLE);
1981 }
1982
1983 if (obj_hdr.FileSize != len) {
1984 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
1985 "Image too small. (%d < %d)",
1986 len, obj_hdr.FileSize);
1987
1988 return (EMLXS_IMAGE_BAD);
1989 }
1990
1991 if ((hba->model_info.chip & EMLXS_LANCER_CHIP) &&
1992 (obj_hdr.Id != OBJ_LANCER_ID)) {
1993 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
1994 "Invalid adapter model. chip=%x fwid=%x",
1995 hba->model_info.chip,
1996 obj_hdr.Id);
1997 return (EMLXS_IMAGE_INCOMPATIBLE);
1998 }
1999
2000 if (obj_hdr_in) {
2001 bcopy(&obj_hdr, obj_hdr_in, sizeof (emlxs_obj_header_t));
2002 }
2003
2004 return (0);
2005
2006 } /* emlxs_obj_validate_image() */
2007
2008
2009 static int32_t
emlxs_obj_fw_download(emlxs_hba_t * hba,caddr_t buffer,uint32_t len,uint32_t offline)2010 emlxs_obj_fw_download(emlxs_hba_t *hba, caddr_t buffer, uint32_t len,
2011 uint32_t offline)
2012 {
2013 emlxs_port_t *port = &PPORT;
2014 uint32_t rval = 0;
2015 MAILBOXQ *mbq = NULL;
2016 MATCHMAP *mp = NULL;
2017 uint32_t change_status = 0;
2018
2019 /* For now we will not take the driver offline during a download */
2020 offline = 0;
2021
2022 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) {
2023 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
2024 "Invalid sli_mode. mode=%d", hba->sli_mode);
2025 return (EMLXS_IMAGE_INCOMPATIBLE);
2026 }
2027
2028 if (hba->model_info.chip & EMLXS_BE_CHIPS) {
2029 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
2030 "Invalid adapter model. chip=%x", hba->model_info.chip);
2031 return (EMLXS_IMAGE_INCOMPATIBLE);
2032 }
2033
2034 if (buffer == NULL || len == 0) {
2035 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
2036 "Empty buffer provided. buf=%p size=%d", buffer, len);
2037 return (EMLXS_IMAGE_BAD);
2038 }
2039
2040 rval = emlxs_obj_validate_image(hba, buffer, len, 0);
2041
2042 if (rval) {
2043 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
2044 "Invalid image provided.");
2045 return (EMLXS_IMAGE_INCOMPATIBLE);
2046 }
2047
2048 /* Allocate resources */
2049
2050 if ((mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
2051 KM_SLEEP)) == NULL) {
2052 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2053 "Unable to allocate mailbox buffer.");
2054
2055 offline = 0;
2056 rval = EMLXS_IMAGE_FAILED;
2057 goto done;
2058 }
2059
2060 if ((mp = emlxs_mem_buf_alloc(hba, OBJ_MAX_XFER_SIZE)) == NULL) {
2061 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2062 "Unable to allocate flash buffer.");
2063
2064 offline = 0;
2065 rval = EMLXS_IMAGE_FAILED;
2066 goto done;
2067 }
2068
2069 /*
2070 * Everything checks out, now to just do it
2071 */
2072 if (offline) {
2073 if (emlxs_offline(hba, 0) != FC_SUCCESS) {
2074
2075 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2076 "Unable to take adapter offline.");
2077
2078 offline = 0;
2079 rval = EMLXS_OFFLINE_FAILED;
2080 goto done;
2081 }
2082 }
2083
2084 rval = emlxs_obj_flash_image(hba, buffer, len, mbq, mp, &change_status);
2085
2086 done:
2087 if (mbq) {
2088 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
2089 }
2090
2091 if (mp) {
2092 emlxs_mem_buf_free(hba, mp);
2093 }
2094
2095 if (offline) {
2096 (void) emlxs_online(hba);
2097 }
2098
2099 if (rval == 0) {
2100 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_complete_msg,
2101 "Status good.");
2102
2103 switch (change_status) {
2104 case CS_NO_RESET:
2105 break;
2106
2107 case CS_REBOOT_RQD:
2108 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_updated_msg,
2109 "The new firmware will not be activated until "
2110 "the adapter is power cycled.");
2111 rval = EMLXS_REBOOT_REQUIRED;
2112 break;
2113
2114 case CS_FW_RESET_RQD:
2115 case CS_PROTO_RESET_RQD:
2116 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_updated_msg,
2117 "Resetting all ports to activate new firmware.");
2118
2119 emlxs_sli4_hba_reset_all(hba, 0);
2120 }
2121 }
2122
2123 return (rval);
2124
2125 } /* emlxs_obj_fw_download() */
2126
2127
2128 extern int32_t
emlxs_cfl_download(emlxs_hba_t * hba,uint32_t region,caddr_t buffer,uint32_t len)2129 emlxs_cfl_download(emlxs_hba_t *hba, uint32_t region, caddr_t buffer,
2130 uint32_t len)
2131 {
2132 emlxs_port_t *port = &PPORT;
2133 MAILBOXQ *mbox = NULL;
2134 MAILBOX *mb;
2135 uint32_t rval = 0;
2136 uint32_t region_id;
2137 uint32_t id;
2138 #ifdef EMLXS_BIG_ENDIAN
2139 caddr_t local_buffer;
2140 uint32_t *bptr1;
2141 uint32_t *bptr2;
2142 uint32_t i;
2143 #endif /* EMLXS_BIG_ENDIAN */
2144
2145 if (buffer == NULL || len == 0) {
2146 return (EMLXS_IMAGE_BAD);
2147 }
2148
2149 #ifdef EMLXS_BIG_ENDIAN
2150 /* We need to swap the image buffer before we start */
2151
2152 /*
2153 * Use KM_SLEEP to allocate a temporary buffer
2154 */
2155 local_buffer = (caddr_t)kmem_zalloc(len, KM_SLEEP);
2156
2157 /* Perform a 32 bit swap of the image */
2158 bptr1 = (uint32_t *)local_buffer;
2159 bptr2 = (uint32_t *)buffer;
2160
2161 for (i = 0; i < (len / 4); i++) {
2162 *bptr1 = SWAP32(*bptr2);
2163 bptr1++;
2164 bptr2++;
2165 }
2166
2167 /* Replace the original buffer */
2168 buffer = local_buffer;
2169
2170 #endif /* EMLXS_BIG_ENDIAN */
2171
2172 if (len > 128) {
2173 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
2174 "Invalid image length: 0x%x > 128", len);
2175
2176 return (EMLXS_IMAGE_BAD);
2177 }
2178
2179 /* Check the region number */
2180 if ((region > 2) && (region != 0xff)) {
2181 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
2182 "Invalid region id: 0x%x", region);
2183
2184 return (EMLXS_IMAGE_BAD);
2185
2186 }
2187
2188 /* Check the image vendor id */
2189 id = *(int32_t *)buffer;
2190 if ((id & 0xffff) != 0x10df) {
2191 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
2192 "Invalid image id: 0x%x", id);
2193
2194 return (EMLXS_IMAGE_BAD);
2195 }
2196
2197 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
2198 KM_NOSLEEP)) == NULL) {
2199 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2200 "Unable to allocate mailbox buffer.");
2201
2202 rval = 1;
2203
2204 goto done;
2205 }
2206
2207 mb = (MAILBOX *)mbox;
2208
2209 /*
2210 * Everything checks out, now to just do it
2211 */
2212 if (emlxs_offline(hba, 0) != FC_SUCCESS) {
2213 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2214 "Unable to take HBA offline.");
2215
2216 rval = EMLXS_OFFLINE_FAILED;
2217
2218 goto done;
2219 }
2220
2221 if (EMLXS_SLI_HBA_RESET(hba, 1, 1, 0) != FC_SUCCESS) {
2222 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2223 "Unable to restart adapter.");
2224
2225 rval = EMLXS_OFFLINE_FAILED;
2226
2227 goto done;
2228 }
2229
2230 /* Check if default region is requested */
2231 if (region == 0xff) {
2232 /*
2233 * Sun-branded Helios and Zypher have different
2234 * default PCI region
2235 */
2236 if ((hba->model_info.flags & EMLXS_ORACLE_BRANDED) &&
2237 (hba->model_info.chip &
2238 (EMLXS_HELIOS_CHIP | EMLXS_ZEPHYR_CHIP))) {
2239 region = 2;
2240 } else {
2241 region = 0;
2242 }
2243 }
2244
2245 /* Set region id based on PCI region requested */
2246 region_id = DEF_PCI_CFG_REGION_ID + region;
2247
2248 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
2249 "PCI configuration: PCI%d region=%d id=0x%x size=%d", region,
2250 region_id, id, len);
2251
2252 /* Copy the data buffer to SLIM */
2253 WRITE_SLIM_COPY(hba, (uint32_t *)buffer,
2254 (volatile uint32_t *)((volatile char *)hba->sli.sli3.slim_addr +
2255 sizeof (MAILBOX)), (len / sizeof (uint32_t)));
2256
2257 #ifdef FMA_SUPPORT
2258 if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle)
2259 != DDI_FM_OK) {
2260 EMLXS_MSGF(EMLXS_CONTEXT,
2261 &emlxs_invalid_access_handle_msg, NULL);
2262 rval = 1;
2263 }
2264 #endif /* FMA_SUPPORT */
2265
2266 emlxs_format_update_pci_cfg(hba, mbox, region_id, len);
2267
2268 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) {
2269 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2270 "Unable to update PCI configuration: Mailbox cmd=%x "
2271 "status=%x info=%d", mb->mbxCommand, mb->mbxStatus,
2272 mb->un.varUpdateCfg.rsp_info);
2273
2274 rval = 1;
2275 }
2276
2277 (void) emlxs_online(hba);
2278
2279 if (rval == 0) {
2280 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_complete_msg,
2281 "Status good.");
2282 }
2283
2284 done:
2285
2286 if (mbox) {
2287 kmem_free(mbox, sizeof (MAILBOXQ));
2288 }
2289
2290 #ifdef EMLXS_BIG_ENDIAN
2291 /* Free the local buffer */
2292 kmem_free(local_buffer, len);
2293 #endif /* EMLXS_BIG_ENDIAN */
2294
2295 return (rval);
2296
2297 } /* emlxs_cfl_download */
2298
2299
2300 static uint32_t
emlxs_valid_cksum(uint32_t * StartAddr,uint32_t * EndAddr)2301 emlxs_valid_cksum(uint32_t *StartAddr, uint32_t *EndAddr)
2302 {
2303 uint32_t Temp;
2304 uint32_t CkSum;
2305
2306 EndAddr++;
2307 CkSum = SLI_CKSUM_SEED;
2308
2309 CkSum = (CkSum >> 1) | (CkSum << 31);
2310 while (StartAddr != EndAddr) {
2311 CkSum = (CkSum << 1) | (CkSum >> 31);
2312 Temp = *StartAddr;
2313
2314 CkSum ^= Temp;
2315 StartAddr++;
2316 }
2317
2318 return (CkSum << 1) | (CkSum >> 31);
2319
2320 } /* emlxs_valid_cksum() */
2321
2322
2323 static void
emlxs_disp_aif_header(emlxs_hba_t * hba,PAIF_HDR AifHdr)2324 emlxs_disp_aif_header(emlxs_hba_t *hba, PAIF_HDR AifHdr)
2325 {
2326 emlxs_port_t *port = &PPORT;
2327
2328 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "AIF Header: ");
2329 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2330 "AIF Header: compress_br = 0x%x", AifHdr->CompressBr);
2331 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2332 "AIF Header: reloc_br = 0x%x", AifHdr->RelocBr);
2333 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2334 "AIF Header: zinit_br = 0x%x", AifHdr->ZinitBr);
2335 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2336 "AIF Header: entry_br = 0x%x", AifHdr->EntryBr);
2337 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2338 "AIF Header: area_id = 0x%x", AifHdr->Area_ID);
2339 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2340 "AIF Header: rosize = 0x%x", AifHdr->RoSize);
2341 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2342 "AIF Header: dbgsize = 0x%x", AifHdr->DbgSize);
2343 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2344 "AIF Header: zinitsize = 0x%x", AifHdr->ZinitSize);
2345 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2346 "AIF Header: dbgtype = 0x%x", AifHdr->DbgType);
2347 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2348 "AIF Header: imagebase = 0x%x", AifHdr->ImageBase);
2349 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2350 "AIF Header: area_size = 0x%x", AifHdr->Area_Size);
2351 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2352 "AIF Header: address_mode = 0x%x", AifHdr->AddressMode);
2353 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2354 "AIF Header: database = 0x%x", AifHdr->DataBase);
2355 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2356 "AIF Header: aversion = 0x%x", AifHdr->AVersion);
2357 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2358 "AIF Header: spare2 = 0x%x", AifHdr->Spare2);
2359 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2360 "AIF Header: debug_swi = 0x%x", AifHdr->DebugSwi);
2361 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2362 "AIF Header: zinitcode[0] = 0x%x", AifHdr->ZinitCode[0]);
2363 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2364 "AIF Header: zinitcode[1] = 0x%x", AifHdr->ZinitCode[1]);
2365
2366 } /* emlxs_disp_aif_header() */
2367
2368
2369
2370 static void
emlxs_dump_image_header(emlxs_hba_t * hba,PIMAGE_HDR image)2371 emlxs_dump_image_header(emlxs_hba_t *hba, PIMAGE_HDR image)
2372 {
2373 emlxs_port_t *port = &PPORT;
2374
2375 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "Img Header: ");
2376 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2377 "Img Header: BlockSize = 0x%x", image->BlockSize);
2378 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2379 "Img Header: PROG_ID Type = 0x%x", image->Id.Type);
2380 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2381 "Img Header: PROG_ID Id = 0x%x", image->Id.Id);
2382 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2383 "Img Header: PROG_ID Ver = 0x%x", image->Id.Ver);
2384 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2385 "Img Header: PROG_ID Rev = 0x%x", image->Id.Rev);
2386 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2387 "Img Header: PROG_ID revcomp = 0x%x", image->Id.un.revcomp);
2388 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2389 "Img Header: Flags = 0x%x", image->Flags);
2390 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2391 "Img Header: EntryAdr = 0x%x", image->EntryAdr);
2392 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2393 "Img Header: InitAdr = 0x%x", image->InitAdr);
2394 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2395 "Img Header: ExitAdr = 0x%x", image->ExitAdr);
2396 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2397 "Img Header: ImageBase = 0x%x", image->ImageBase);
2398 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2399 "Img Header: ImageSize = 0x%x", image->ImageSize);
2400 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2401 "Img Header: ZinitSize = 0x%x", image->ZinitSize);
2402 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2403 "Img Header: RelocSize = 0x%x", image->RelocSize);
2404 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2405 "Img Header: HdrCks = 0x%x", image->HdrCks);
2406
2407 } /* emlxs_dump_image_header() */
2408
2409
2410 static void
emlxs_format_dump(emlxs_hba_t * hba,MAILBOXQ * mbq,uint32_t Type,uint32_t RegionId,uint32_t WordCount,uint32_t BaseAddr)2411 emlxs_format_dump(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t Type,
2412 uint32_t RegionId, uint32_t WordCount, uint32_t BaseAddr)
2413 {
2414
2415 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
2416 MAILBOX4 *mb = (MAILBOX4 *)mbq;
2417
2418 /* Clear the local dump_region */
2419 bzero(hba->sli.sli4.dump_region.virt,
2420 hba->sli.sli4.dump_region.size);
2421
2422 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
2423
2424 mb->mbxCommand = MBX_DUMP_MEMORY;
2425 mb->un.varDmp4.type = Type;
2426 mb->un.varDmp4.entry_index = BaseAddr;
2427 mb->un.varDmp4.region_id = RegionId;
2428
2429 mb->un.varDmp4.available_cnt = min((WordCount*4),
2430 hba->sli.sli4.dump_region.size);
2431 mb->un.varDmp4.addrHigh =
2432 PADDR_HI(hba->sli.sli4.dump_region.phys);
2433 mb->un.varDmp4.addrLow =
2434 PADDR_LO(hba->sli.sli4.dump_region.phys);
2435 mb->un.varDmp4.rsp_cnt = 0;
2436
2437 mb->mbxOwner = OWN_HOST;
2438
2439 } else {
2440 MAILBOX *mb = (MAILBOX *)mbq;
2441
2442 bzero((void *)mb, MAILBOX_CMD_BSIZE);
2443
2444 mb->mbxCommand = MBX_DUMP_MEMORY;
2445 mb->un.varDmp.type = Type;
2446 mb->un.varDmp.region_id = RegionId;
2447 mb->un.varDmp.word_cnt = WordCount;
2448 mb->un.varDmp.base_adr = BaseAddr;
2449 mb->mbxOwner = OWN_HOST;
2450 }
2451
2452 mbq->mbox_cmpl = NULL; /* no cmpl needed */
2453
2454 return;
2455
2456 } /* emlxs_format_dump() */
2457
2458
2459 /* ARGSUSED */
2460 static uint32_t
emlxs_start_abs_download(emlxs_hba_t * hba,PAIF_HDR AifHdr,caddr_t Buffer,uint32_t len,PWAKE_UP_PARMS WakeUpParms)2461 emlxs_start_abs_download(emlxs_hba_t *hba,
2462 PAIF_HDR AifHdr,
2463 caddr_t Buffer,
2464 uint32_t len,
2465 PWAKE_UP_PARMS WakeUpParms)
2466 {
2467 emlxs_port_t *port = &PPORT;
2468 uint32_t DlByteCount = AifHdr->RoSize + AifHdr->RwSize;
2469 uint32_t *Src;
2470 uint32_t *Dst;
2471 caddr_t DataBuffer = NULL;
2472 MAILBOXQ *mbox;
2473 MAILBOX *mb;
2474 uint32_t rval = 1;
2475 uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT;
2476 uint32_t DlToAddr = AifHdr->ImageBase;
2477 uint32_t DlCount;
2478 uint32_t i;
2479 WAKE_UP_PARMS AbsWakeUpParms;
2480 int32_t AbsChangeParams;
2481
2482 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2483 "Performing absolute download...");
2484
2485 if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT,
2486 KM_NOSLEEP)) == NULL) {
2487 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2488 "Unable to allocate data buffer.");
2489
2490 return (rval);
2491 }
2492
2493 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
2494 KM_NOSLEEP)) == NULL) {
2495 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2496 "Unable to allocate mailbox buffer.");
2497
2498 kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT);
2499
2500 return (rval);
2501 }
2502 mb = (MAILBOX *)mbox;
2503
2504 AbsChangeParams = emlxs_build_parms(Buffer,
2505 &AbsWakeUpParms, len, AifHdr);
2506
2507 Buffer += sizeof (AIF_HDR);
2508
2509 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "Erasing flash...");
2510
2511 if (AifHdr->ImageBase == 0x20000) {
2512 /* DWC File */
2513 emlxs_format_prog_flash(mbox, 0x20000, 0x50000, ERASE_FLASH, 0,
2514 0, 0, NULL, 0);
2515 } else {
2516 emlxs_format_prog_flash(mbox, DlToAddr, DlByteCount,
2517 ERASE_FLASH, 0, 0, 0, NULL, 0);
2518 }
2519
2520 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) {
2521 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2522 "Unable to erase Flash: Mailbox cmd=%x status=%x",
2523 mb->mbxCommand, mb->mbxStatus);
2524
2525 rval = 1;
2526
2527 goto EXIT_ABS_DOWNLOAD;
2528 }
2529
2530 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
2531 "Programming flash...");
2532
2533 while (DlByteCount) {
2534
2535 if (DlByteCount > SegSize) {
2536 DlCount = SegSize;
2537 } else {
2538 DlCount = DlByteCount;
2539 }
2540 DlByteCount -= DlCount;
2541
2542 Dst = (uint32_t *)DataBuffer;
2543 Src = (uint32_t *)Buffer;
2544
2545 for (i = 0; i < (DlCount / 4); i++) {
2546 *Dst = *Src;
2547 Dst++;
2548 Src++;
2549 }
2550
2551 WRITE_SLIM_COPY(hba, (uint32_t *)DataBuffer,
2552 (volatile uint32_t *)
2553 ((volatile char *)hba->sli.sli3.slim_addr +
2554 sizeof (MAILBOX)), (DlCount / sizeof (uint32_t)));
2555
2556 emlxs_format_prog_flash(mbox, DlToAddr, DlCount,
2557 PROGRAM_FLASH, (DlByteCount) ? 0 : 1, 0, DlCount, NULL, 0);
2558
2559 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) !=
2560 MBX_SUCCESS) {
2561 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2562 "Unable to program Flash: Mailbox cmd=%x status=%x",
2563 mb->mbxCommand, mb->mbxStatus);
2564
2565 rval = 1;
2566
2567 goto EXIT_ABS_DOWNLOAD;
2568 }
2569
2570 Buffer += DlCount;
2571 DlToAddr += DlCount;
2572 }
2573
2574 #ifdef FMA_SUPPORT
2575 if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle)
2576 != DDI_FM_OK) {
2577 EMLXS_MSGF(EMLXS_CONTEXT,
2578 &emlxs_invalid_access_handle_msg, NULL);
2579
2580 rval = 1;
2581
2582 goto EXIT_ABS_DOWNLOAD;
2583 }
2584 #endif /* FMA_SUPPORT */
2585
2586 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, "Updating params...");
2587
2588 if (AbsChangeParams) {
2589 rval =
2590 emlxs_update_wakeup_parms(hba, &AbsWakeUpParms,
2591 WakeUpParms);
2592 }
2593
2594 EXIT_ABS_DOWNLOAD:
2595 if (DataBuffer) {
2596 kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT);
2597 }
2598
2599 if (mbox) {
2600 kmem_free(mbox, sizeof (MAILBOXQ));
2601 }
2602
2603 return (rval);
2604
2605 } /* emlxs_start_abs_download() */
2606
2607
2608 /* ARGSUSED */
2609 static void
emlxs_format_prog_flash(MAILBOXQ * mbq,uint32_t Base,uint32_t DlByteCount,uint32_t Function,uint32_t Complete,uint32_t BdeAddress,uint32_t BdeSize,PROG_ID * ProgId,uint32_t keep)2610 emlxs_format_prog_flash(MAILBOXQ *mbq,
2611 uint32_t Base,
2612 uint32_t DlByteCount,
2613 uint32_t Function,
2614 uint32_t Complete,
2615 uint32_t BdeAddress,
2616 uint32_t BdeSize,
2617 PROG_ID *ProgId,
2618 uint32_t keep)
2619 {
2620 MAILBOX *mb = (MAILBOX *)mbq;
2621
2622 bzero((void *)mb, MAILBOX_CMD_BSIZE);
2623
2624 if (ProgId) {
2625 mb->mbxCommand = MBX_DOWN_LOAD;
2626 } else {
2627 mb->mbxCommand = MBX_LOAD_SM;
2628 }
2629
2630 mb->un.varLdSM.load_cmplt = Complete;
2631 mb->un.varLdSM.method = DL_FROM_SLIM;
2632 mb->un.varLdSM.update_flash = 1;
2633 mb->un.varLdSM.erase_or_prog = Function;
2634 mb->un.varLdSM.dl_to_adr = Base;
2635 mb->un.varLdSM.dl_len = DlByteCount;
2636 mb->un.varLdSM.keep = keep;
2637
2638 if (BdeSize) {
2639 mb->un.varLdSM.un.dl_from_slim_offset = DL_FROM_SLIM_OFFSET;
2640 } else if (ProgId) {
2641 mb->un.varLdSM.un.prog_id = *ProgId;
2642 } else {
2643 mb->un.varLdSM.un.dl_from_slim_offset = 0;
2644 }
2645
2646 mb->mbxOwner = OWN_HOST;
2647 mbq->mbox_cmpl = NULL;
2648
2649 } /* emlxs_format_prog_flash() */
2650
2651
2652 static void
emlxs_format_update_parms(MAILBOXQ * mbq,PWAKE_UP_PARMS WakeUpParms)2653 emlxs_format_update_parms(MAILBOXQ *mbq, PWAKE_UP_PARMS WakeUpParms)
2654 {
2655 MAILBOX *mb = (MAILBOX *)mbq;
2656
2657 bzero((void *)mb, MAILBOX_CMD_BSIZE);
2658
2659 mb->mbxCommand = MBX_UPDATE_CFG;
2660 mb->un.varUpdateCfg.req_type = UPDATE_DATA;
2661 mb->un.varUpdateCfg.region_id = WAKE_UP_PARMS_REGION_ID;
2662 mb->un.varUpdateCfg.entry_len = sizeof (WAKE_UP_PARMS);
2663 mb->un.varUpdateCfg.byte_len = sizeof (WAKE_UP_PARMS);
2664
2665 bcopy((caddr_t)WakeUpParms,
2666 (caddr_t)&(mb->un.varUpdateCfg.cfg_data),
2667 sizeof (WAKE_UP_PARMS));
2668 mbq->mbox_cmpl = NULL;
2669
2670 } /* emlxs_format_update_parms () */
2671
2672
2673 /* ARGSUSED */
2674 static void
emlxs_format_update_pci_cfg(emlxs_hba_t * hba,MAILBOXQ * mbq,uint32_t region_id,uint32_t size)2675 emlxs_format_update_pci_cfg(emlxs_hba_t *hba, MAILBOXQ *mbq,
2676 uint32_t region_id, uint32_t size)
2677 {
2678 MAILBOX *mb = (MAILBOX *)mbq;
2679
2680 bzero((void *)mb, MAILBOX_CMD_BSIZE);
2681
2682 mb->mbxCommand = MBX_UPDATE_CFG;
2683 mb->un.varUpdateCfg.Vbit = 1;
2684 mb->un.varUpdateCfg.Obit = 1;
2685 mb->un.varUpdateCfg.cfg_data = DL_FROM_SLIM_OFFSET;
2686 mb->un.varUpdateCfg.req_type = UPDATE_DATA;
2687 mb->un.varUpdateCfg.region_id = region_id;
2688 mb->un.varUpdateCfg.entry_len = size;
2689 mb->un.varUpdateCfg.byte_len = size;
2690 mbq->mbox_cmpl = NULL;
2691
2692 } /* emlxs_format_update_pci_cfg() */
2693
2694
2695
2696 static uint32_t
emlxs_update_boot_wakeup_parms(emlxs_hba_t * hba,PWAKE_UP_PARMS WakeUpParms,PROG_ID * prog_id,uint32_t proc_erom)2697 emlxs_update_boot_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms,
2698 PROG_ID * prog_id, uint32_t proc_erom)
2699 {
2700 emlxs_port_t *port = &PPORT;
2701 MAILBOX *mb;
2702 MAILBOXQ *mbox;
2703 uint32_t rval = 0;
2704 PROG_ID old_prog_id;
2705
2706 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
2707 KM_NOSLEEP)) == NULL) {
2708 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2709 "Unable to allocate mailbox buffer.");
2710
2711 return (1);
2712 }
2713
2714 mb = (MAILBOX *)mbox;
2715
2716 if (proc_erom && !(hba->model_info.chip &
2717 (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) {
2718 WakeUpParms->u1.EROM_prog_id = *prog_id;
2719 (void) emlxs_update_exp_rom(hba, WakeUpParms);
2720 }
2721
2722 old_prog_id = WakeUpParms->u0.boot_bios_id;
2723 WakeUpParms->u0.boot_bios_id = *prog_id;
2724
2725 emlxs_format_update_parms(mbox, WakeUpParms);
2726
2727 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) {
2728 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2729 "Unable to update boot wakeup parms: Mailbox cmd=%x "
2730 "status=%x", mb->mbxCommand, mb->mbxStatus);
2731
2732 WakeUpParms->u0.boot_bios_id = old_prog_id;
2733 rval = 1;
2734 }
2735
2736 if (mbox) {
2737 kmem_free(mbox, sizeof (MAILBOXQ));
2738 }
2739
2740 return (rval);
2741
2742 } /* emlxs_update_boot_wakeup_parms() */
2743
2744
2745
2746 static uint32_t
emlxs_update_ff_wakeup_parms(emlxs_hba_t * hba,PWAKE_UP_PARMS WakeUpParms,PROG_ID * prog_id)2747 emlxs_update_ff_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms,
2748 PROG_ID *prog_id)
2749 {
2750 emlxs_port_t *port = &PPORT;
2751 uint32_t rval = 0;
2752 MAILBOXQ *mbox;
2753 MAILBOX *mb;
2754 PROG_ID old_prog_id;
2755
2756 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
2757 KM_NOSLEEP)) == NULL) {
2758 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2759 "Unable to allocate mailbox buffer.");
2760
2761 return (1);
2762 }
2763
2764 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
2765 "FF: Updating parms...");
2766
2767 mb = (MAILBOX *)mbox;
2768
2769 old_prog_id = WakeUpParms->prog_id;
2770 WakeUpParms->prog_id = *prog_id;
2771
2772 emlxs_format_update_parms(mbox, WakeUpParms);
2773
2774 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) {
2775 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2776 "Unable to update wakeup parameters: Mailbox cmd=%x "
2777 "status=%x", mb->mbxCommand, mb->mbxStatus);
2778
2779 WakeUpParms->prog_id = old_prog_id;
2780 rval = 1;
2781 }
2782
2783 if (mbox) {
2784 kmem_free(mbox, sizeof (MAILBOXQ));
2785 }
2786
2787 return (rval);
2788
2789 } /* emlxs_update_ff_wakeup_parms() */
2790
2791
2792 static uint32_t
emlxs_update_sli1_wakeup_parms(emlxs_hba_t * hba,PWAKE_UP_PARMS WakeUpParms,PROG_ID * prog_id)2793 emlxs_update_sli1_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms,
2794 PROG_ID * prog_id)
2795 {
2796 emlxs_port_t *port = &PPORT;
2797 uint32_t rval = 0;
2798 MAILBOXQ *mbox;
2799 MAILBOX *mb;
2800 PROG_ID old_prog_id;
2801
2802 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
2803 KM_NOSLEEP)) == NULL) {
2804 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2805 "Unable to allocate mailbox buffer.");
2806
2807 return (1);
2808 }
2809
2810 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
2811 "SLI1: Updating parms...");
2812
2813 mb = (MAILBOX *)mbox;
2814
2815 old_prog_id = WakeUpParms->sli1_prog_id;
2816 WakeUpParms->sli1_prog_id = *prog_id;
2817
2818 emlxs_format_update_parms(mbox, WakeUpParms);
2819
2820 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) {
2821 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2822 "Unable to update wakeup parameters. Mailbox cmd=%x "
2823 "status=%x", mb->mbxCommand, mb->mbxStatus);
2824
2825 WakeUpParms->sli1_prog_id = old_prog_id;
2826 rval = 1;
2827 }
2828
2829 if (mbox) {
2830 kmem_free(mbox, sizeof (MAILBOXQ));
2831 }
2832
2833 return (rval);
2834
2835 } /* emlxs_update_sli1_wakeup_parms() */
2836
2837
2838 static uint32_t
emlxs_update_sli2_wakeup_parms(emlxs_hba_t * hba,PWAKE_UP_PARMS WakeUpParms,PROG_ID * prog_id)2839 emlxs_update_sli2_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms,
2840 PROG_ID * prog_id)
2841 {
2842 emlxs_port_t *port = &PPORT;
2843 uint32_t rval = 0;
2844 MAILBOXQ *mbox;
2845 MAILBOX *mb;
2846 PROG_ID old_prog_id;
2847
2848 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
2849 KM_NOSLEEP)) == NULL) {
2850 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2851 "Unable to allocate mailbox buffer.");
2852
2853 return (1);
2854 }
2855
2856 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
2857 "SLI2: Updating parms...");
2858
2859 mb = (MAILBOX *)mbox;
2860
2861 old_prog_id = WakeUpParms->sli2_prog_id;
2862 WakeUpParms->sli2_prog_id = *prog_id;
2863
2864 emlxs_format_update_parms(mbox, WakeUpParms);
2865
2866 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) {
2867 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2868 "Unable to update wakeup parameters. Mailbox cmd=%x "
2869 "status=%x", mb->mbxCommand, mb->mbxStatus);
2870
2871 WakeUpParms->sli2_prog_id = old_prog_id;
2872 rval = 1;
2873 }
2874
2875 if (mbox) {
2876 kmem_free(mbox, sizeof (MAILBOXQ));
2877 }
2878
2879 return (rval);
2880
2881 } /* emlxs_update_sli2_wakeup_parms() */
2882
2883
2884 static uint32_t
emlxs_update_sli3_wakeup_parms(emlxs_hba_t * hba,PWAKE_UP_PARMS WakeUpParms,PROG_ID * prog_id)2885 emlxs_update_sli3_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms,
2886 PROG_ID *prog_id)
2887 {
2888 emlxs_port_t *port = &PPORT;
2889 uint32_t rval = 0;
2890 MAILBOXQ *mbox;
2891 MAILBOX *mb;
2892 PROG_ID old_prog_id;
2893
2894 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
2895 KM_NOSLEEP)) == NULL) {
2896 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2897 "Unable to allocate mailbox buffer.");
2898
2899 return (1);
2900 }
2901
2902 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
2903 "SLI3: Updating parms...");
2904
2905 mb = (MAILBOX *)mbox;
2906
2907 old_prog_id = WakeUpParms->sli3_prog_id;
2908 WakeUpParms->sli3_prog_id = *prog_id;
2909
2910 emlxs_format_update_parms(mbox, WakeUpParms);
2911
2912 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) {
2913 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2914 "Unable to update wakeup parameters. Mailbox cmd=%x "
2915 "status=%x", mb->mbxCommand, mb->mbxStatus);
2916
2917 WakeUpParms->sli3_prog_id = old_prog_id;
2918 rval = 1;
2919 }
2920
2921 if (mbox) {
2922 kmem_free(mbox, sizeof (MAILBOXQ));
2923 }
2924
2925 return (rval);
2926
2927 } /* emlxs_update_sli3_wakeup_parms() */
2928
2929
2930 static uint32_t
emlxs_update_sli4_wakeup_parms(emlxs_hba_t * hba,PWAKE_UP_PARMS WakeUpParms,PROG_ID * prog_id)2931 emlxs_update_sli4_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms,
2932 PROG_ID *prog_id)
2933 {
2934 emlxs_port_t *port = &PPORT;
2935 uint32_t rval = 0;
2936 MAILBOXQ *mbox;
2937 MAILBOX *mb;
2938 PROG_ID old_prog_id;
2939
2940 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
2941 KM_NOSLEEP)) == NULL) {
2942 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2943 "Unable to allocate mailbox buffer.");
2944
2945 return (1);
2946 }
2947
2948 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
2949 "SLI4: Updating parms...");
2950
2951 mb = (MAILBOX *)mbox;
2952
2953 old_prog_id = WakeUpParms->sli4_prog_id;
2954 WakeUpParms->sli4_prog_id = *prog_id;
2955
2956 emlxs_format_update_parms(mbox, WakeUpParms);
2957
2958 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) {
2959 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
2960 "Unable to update wakeup parameters. Mailbox cmd=%x "
2961 "status=%x", mb->mbxCommand, mb->mbxStatus);
2962
2963 WakeUpParms->sli4_prog_id = old_prog_id;
2964 rval = 1;
2965 }
2966
2967 if (mbox) {
2968 kmem_free(mbox, sizeof (MAILBOXQ));
2969 }
2970
2971 return (rval);
2972
2973 } /* emlxs_update_sli4_wakeup_parms() */
2974
2975
2976 static uint32_t
emlxs_clean_flash(emlxs_hba_t * hba,PWAKE_UP_PARMS OldWakeUpParms,PWAKE_UP_PARMS NewWakeUpParms)2977 emlxs_clean_flash(emlxs_hba_t *hba,
2978 PWAKE_UP_PARMS OldWakeUpParms, PWAKE_UP_PARMS NewWakeUpParms)
2979 {
2980 emlxs_port_t *port = &PPORT;
2981 PROG_ID load_list[MAX_LOAD_ENTRY];
2982 PROG_ID *wakeup_list[MAX_LOAD_ENTRY];
2983 uint32_t count;
2984 uint32_t i;
2985 uint32_t j;
2986 uint32_t k = 0;
2987 uint32_t *wptr;
2988
2989 if (!NewWakeUpParms) {
2990 return (1);
2991 }
2992
2993 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
2994 "Cleaning flash...");
2995
2996 /* If old wakeup parameter list is available, */
2997 /* then cleanup old entries */
2998 if (OldWakeUpParms) {
2999 if (bcmp(&OldWakeUpParms->prog_id, &NewWakeUpParms->prog_id,
3000 sizeof (PROG_ID))) {
3001
3002 wptr = (uint32_t *)&OldWakeUpParms->prog_id;
3003 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
3004 "OLD: prog_id: 0x%08x 0x%08x Removing.",
3005 wptr[0], wptr[1]);
3006
3007 (void) emlxs_delete_load_entry(hba,
3008 &OldWakeUpParms->prog_id);
3009 }
3010
3011 if (bcmp(&OldWakeUpParms->u0.boot_bios_id,
3012 &NewWakeUpParms->u0.boot_bios_id, sizeof (PROG_ID))) {
3013
3014 wptr = (uint32_t *)&OldWakeUpParms->u0.boot_bios_id;
3015 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
3016 "OLD: boot_bios_id: 0x%08x 0x%08x Removing.",
3017 wptr[0], wptr[1]);
3018
3019 (void) emlxs_delete_load_entry(hba,
3020 &OldWakeUpParms->u0.boot_bios_id);
3021 }
3022
3023 if (bcmp(&OldWakeUpParms->sli1_prog_id,
3024 &NewWakeUpParms->sli1_prog_id, sizeof (PROG_ID))) {
3025
3026 wptr = (uint32_t *)&OldWakeUpParms->sli1_prog_id;
3027 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
3028 "OLD: sli1_prog_id: 0x%08x 0x%08x Removing.",
3029 wptr[0], wptr[1]);
3030
3031 (void) emlxs_delete_load_entry(hba,
3032 &OldWakeUpParms->sli1_prog_id);
3033 }
3034
3035 if (bcmp(&OldWakeUpParms->sli2_prog_id,
3036 &NewWakeUpParms->sli2_prog_id, sizeof (PROG_ID))) {
3037
3038 wptr = (uint32_t *)&OldWakeUpParms->sli2_prog_id;
3039 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
3040 "OLD: sli2_prog_id: 0x%08x 0x%08x Removing.",
3041 wptr[0], wptr[1]);
3042
3043 (void) emlxs_delete_load_entry(hba,
3044 &OldWakeUpParms->sli2_prog_id);
3045 }
3046
3047 if (bcmp(&OldWakeUpParms->sli3_prog_id,
3048 &NewWakeUpParms->sli3_prog_id, sizeof (PROG_ID))) {
3049
3050 wptr = (uint32_t *)&OldWakeUpParms->sli3_prog_id;
3051 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
3052 "OLD: sli3_prog_id: 0x%08x 0x%08x Removing.",
3053 wptr[0], wptr[1]);
3054
3055 (void) emlxs_delete_load_entry(hba,
3056 &OldWakeUpParms->sli3_prog_id);
3057 }
3058
3059 if (bcmp(&OldWakeUpParms->sli4_prog_id,
3060 &NewWakeUpParms->sli4_prog_id, sizeof (PROG_ID))) {
3061
3062 wptr = (uint32_t *)&OldWakeUpParms->sli4_prog_id;
3063 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
3064 "OLD: sli4_prog_id: 0x%08x 0x%08x Removing.",
3065 wptr[0], wptr[1]);
3066
3067 (void) emlxs_delete_load_entry(hba,
3068 &OldWakeUpParms->sli4_prog_id);
3069 }
3070
3071 return (0);
3072 }
3073
3074 /* Otherwise use the current load list */
3075 count = emlxs_get_load_list(hba, load_list);
3076
3077 if (!count) {
3078 return (1);
3079 }
3080
3081 /* Init the wakeup list */
3082 wptr = (uint32_t *)&NewWakeUpParms->prog_id;
3083 if (*wptr) {
3084 wakeup_list[k++] = &NewWakeUpParms->prog_id;
3085 }
3086
3087 wptr = (uint32_t *)&NewWakeUpParms->u0.boot_bios_id;
3088 if (*wptr) {
3089 wakeup_list[k++] = &NewWakeUpParms->u0.boot_bios_id;
3090 }
3091
3092 wptr = (uint32_t *)&NewWakeUpParms->sli1_prog_id;
3093 if (*wptr) {
3094 wakeup_list[k++] = &NewWakeUpParms->sli1_prog_id;
3095 }
3096
3097 wptr = (uint32_t *)&NewWakeUpParms->sli2_prog_id;
3098 if (*wptr) {
3099 wakeup_list[k++] = &NewWakeUpParms->sli2_prog_id;
3100 }
3101
3102 wptr = (uint32_t *)&NewWakeUpParms->sli3_prog_id;
3103 if (*wptr) {
3104 wakeup_list[k++] = &NewWakeUpParms->sli3_prog_id;
3105 }
3106
3107 wptr = (uint32_t *)&NewWakeUpParms->sli4_prog_id;
3108 if (*wptr) {
3109 wakeup_list[k++] = &NewWakeUpParms->sli4_prog_id;
3110 }
3111
3112 if (k == 0) {
3113 return (0);
3114 }
3115
3116 /* Match load list to wakeup list */
3117 for (i = 0; i < count; i++) {
3118
3119 wptr = (uint32_t *)&load_list[i];
3120
3121 for (j = 0; j < k; j++) {
3122 if (bcmp((uint8_t *)wakeup_list[j],
3123 (uint8_t *)&load_list[i], sizeof (PROG_ID)) == 0) {
3124 break;
3125 }
3126 }
3127
3128 /* No match */
3129 if (j == k) {
3130 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
3131 "Load List[%d]: %08x %08x Removing.",
3132 i, wptr[0], wptr[1]);
3133
3134 (void) emlxs_delete_load_entry(hba, &load_list[i]);
3135 } else {
3136 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
3137 "Load List[%d]: %08x %08x Preserving.",
3138 i, wptr[0], wptr[1]);
3139 }
3140 }
3141
3142 return (0);
3143
3144 } /* emlxs_clean_flash() */
3145
3146
3147 /* ARGSUSED */
3148 static uint32_t
emlxs_start_rel_download(emlxs_hba_t * hba,PIMAGE_HDR ImageHdr,caddr_t Buffer,PWAKE_UP_PARMS WakeUpParms,uint32_t dwc_flag)3149 emlxs_start_rel_download(emlxs_hba_t *hba,
3150 PIMAGE_HDR ImageHdr,
3151 caddr_t Buffer,
3152 PWAKE_UP_PARMS WakeUpParms,
3153 uint32_t dwc_flag)
3154 {
3155 emlxs_port_t *port = &PPORT;
3156 MAILBOXQ *mbox;
3157 MAILBOX *mb;
3158 uint32_t *Src;
3159 uint32_t *Dst;
3160 caddr_t DataBuffer = NULL;
3161 uint32_t rval = 0;
3162 uint32_t DlByteCount;
3163 uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT;
3164 uint32_t DlCount;
3165 uint32_t i;
3166 uint32_t *wptr;
3167
3168 wptr = (uint32_t *)&ImageHdr->Id;
3169 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
3170 "Relative download: %08x %08x", wptr[0], wptr[1]);
3171
3172 if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT,
3173 KM_NOSLEEP)) == NULL) {
3174 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
3175 "Unable to allocate data buffer.");
3176
3177 return (1);
3178 }
3179
3180 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
3181 KM_NOSLEEP)) == NULL) {
3182 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
3183 "Unable to allocate mailbox buffer.");
3184
3185 kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT);
3186
3187 return (1);
3188 }
3189
3190 mb = (MAILBOX *)mbox;
3191
3192 DlByteCount = ImageHdr->BlockSize;
3193
3194 emlxs_format_prog_flash(mbox, 0, DlByteCount, ERASE_FLASH, 0, 0, 0,
3195 &ImageHdr->Id, 0);
3196
3197 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
3198 " Erasing flash...");
3199
3200 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0);
3201
3202 if (rval) {
3203 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
3204 "Unable to erase flash. Mailbox cmd=%x status=%x",
3205 mb->mbxCommand, mb->mbxStatus);
3206
3207 goto EXIT_REL_DOWNLOAD;
3208 }
3209
3210 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
3211 " Programming flash...");
3212
3213 while (DlByteCount) {
3214 if (DlByteCount > SegSize) {
3215 DlCount = SegSize;
3216 } else {
3217 DlCount = DlByteCount;
3218 }
3219 DlByteCount -= DlCount;
3220
3221 Dst = (uint32_t *)DataBuffer;
3222 Src = (uint32_t *)Buffer;
3223
3224 for (i = 0; i < (DlCount / 4); i++) {
3225 *Dst = *Src;
3226 Dst++;
3227 Src++;
3228 }
3229
3230 WRITE_SLIM_COPY(hba, (uint32_t *)DataBuffer,
3231 (volatile uint32_t *)
3232 ((volatile char *)hba->sli.sli3.slim_addr +
3233 sizeof (MAILBOX)), (DlCount / sizeof (uint32_t)));
3234
3235 emlxs_format_prog_flash(mbox,
3236 0,
3237 DlCount,
3238 PROGRAM_FLASH,
3239 (DlByteCount) ? 0 : 1,
3240 0, DlCount, &ImageHdr->Id, dwc_flag);
3241
3242 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0);
3243
3244 if (rval) {
3245 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
3246 "Unable to program flash. Mailbox cmd=%x status=%x",
3247 mb->mbxCommand, mb->mbxStatus);
3248
3249 goto EXIT_REL_DOWNLOAD;
3250 }
3251
3252 Buffer += DlCount;
3253 }
3254
3255 #ifdef FMA_SUPPORT
3256 if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle)
3257 != DDI_FM_OK) {
3258 EMLXS_MSGF(EMLXS_CONTEXT,
3259 &emlxs_invalid_access_handle_msg, NULL);
3260
3261 rval = 1;
3262
3263 goto EXIT_REL_DOWNLOAD;
3264 }
3265 #endif /* FMA_SUPPORT */
3266
3267 /* Update wakeup parameters */
3268 switch (ImageHdr->Id.Type) {
3269 case TEST_PROGRAM:
3270 break;
3271
3272 case FUNC_FIRMWARE:
3273 if (!dwc_flag) {
3274 rval = emlxs_update_ff_wakeup_parms(hba, WakeUpParms,
3275 &ImageHdr->Id);
3276 } else {
3277 WakeUpParms->prog_id = ImageHdr->Id;
3278 }
3279 break;
3280
3281 case BOOT_BIOS:
3282 if (!dwc_flag) {
3283 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
3284 "BOOT: Updating parms...");
3285
3286 rval = emlxs_update_boot_wakeup_parms(hba, WakeUpParms,
3287 &ImageHdr->Id, 1);
3288 } else {
3289 if (hba->wakeup_parms.u0.boot_bios_wd[0]) {
3290 WakeUpParms->u0.boot_bios_id = ImageHdr->Id;
3291 }
3292
3293 if (!(hba->model_info.chip &
3294 (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) {
3295 WakeUpParms->u1.EROM_prog_id = ImageHdr->Id;
3296 }
3297 }
3298 break;
3299
3300 case SLI1_OVERLAY:
3301 if (!dwc_flag) {
3302 rval = emlxs_update_sli1_wakeup_parms(hba, WakeUpParms,
3303 &ImageHdr->Id);
3304 } else {
3305 WakeUpParms->sli1_prog_id = ImageHdr->Id;
3306 }
3307 break;
3308
3309 case SLI2_OVERLAY:
3310 if (!dwc_flag) {
3311 rval = emlxs_update_sli2_wakeup_parms(hba, WakeUpParms,
3312 &ImageHdr->Id);
3313 } else {
3314 WakeUpParms->sli2_prog_id = ImageHdr->Id;
3315 }
3316 break;
3317
3318 case SLI3_OVERLAY:
3319 if (!dwc_flag) {
3320 rval = emlxs_update_sli3_wakeup_parms(hba, WakeUpParms,
3321 &ImageHdr->Id);
3322 } else {
3323 WakeUpParms->sli3_prog_id = ImageHdr->Id;
3324 }
3325 break;
3326
3327 case SLI4_OVERLAY:
3328 if (!dwc_flag) {
3329 rval = emlxs_update_sli4_wakeup_parms(hba, WakeUpParms,
3330 &ImageHdr->Id);
3331 } else {
3332 WakeUpParms->sli4_prog_id = ImageHdr->Id;
3333 }
3334 break;
3335
3336 default:
3337 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
3338 "Image type not supported. Type=%x", ImageHdr->Id.Type);
3339
3340 break;
3341 }
3342
3343 EXIT_REL_DOWNLOAD:
3344 if (DataBuffer) {
3345 kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT);
3346 }
3347
3348 if (mbox) {
3349 kmem_free(mbox, sizeof (MAILBOXQ));
3350 }
3351
3352 return (rval);
3353
3354 } /* emlxs_start_rel_download() */
3355
3356
3357 static uint32_t
emlxs_proc_rel_2mb(emlxs_hba_t * hba,caddr_t buffer,emlxs_fw_image_t * fw_image)3358 emlxs_proc_rel_2mb(emlxs_hba_t *hba, caddr_t buffer, emlxs_fw_image_t *fw_image)
3359 {
3360 emlxs_port_t *port = &PPORT;
3361 uint32_t rval = 0;
3362 WAKE_UP_PARMS RelWakeUpParms;
3363 WAKE_UP_PARMS WakeUpParms;
3364 uint32_t i;
3365 IMAGE_HDR ImageHdr;
3366 caddr_t bptr;
3367 uint32_t flash_cleaned = 0;
3368
3369 if (emlxs_read_wakeup_parms(hba, &WakeUpParms, 0)) {
3370 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
3371 "Unable to get wakeup parameters.");
3372
3373 return (EMLXS_IMAGE_FAILED);
3374 }
3375
3376 download:
3377
3378 bcopy(&WakeUpParms, &RelWakeUpParms, sizeof (WAKE_UP_PARMS));
3379
3380 for (i = 0; i < MAX_PROG_TYPES; i++) {
3381 if (!fw_image->prog[i].version) {
3382 continue;
3383 }
3384
3385 bptr = buffer + fw_image->prog[i].offset;
3386
3387 bcopy(bptr, &ImageHdr, sizeof (IMAGE_HDR));
3388
3389 rval = emlxs_start_rel_download(hba, &ImageHdr, bptr,
3390 &RelWakeUpParms, 1);
3391
3392 if (rval) {
3393 EMLXS_MSGF(EMLXS_CONTEXT,
3394 &emlxs_download_failed_msg,
3395 "Failed to program flash.");
3396
3397 if ((rval == NO_FLASH_MEM_AVAIL) && !flash_cleaned) {
3398 /* Cleanup using current load list */
3399 (void) emlxs_clean_flash(hba, 0, &WakeUpParms);
3400
3401 flash_cleaned = 1;
3402 goto download;
3403 }
3404
3405 return (EMLXS_IMAGE_FAILED);
3406 }
3407 }
3408
3409 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
3410 "Updating wakeup parameters.");
3411
3412 if (emlxs_update_wakeup_parms(hba, &RelWakeUpParms,
3413 &RelWakeUpParms)) {
3414 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
3415 "Unable to update parameters.");
3416
3417 return (EMLXS_IMAGE_FAILED);
3418 }
3419
3420 /* Cleanup using old wakeup paramters */
3421 (void) emlxs_clean_flash(hba, &WakeUpParms, &RelWakeUpParms);
3422
3423 return (0);
3424
3425 } /* emlxs_proc_rel_2mb() */
3426
3427
3428 #define FLASH_POLLING_BIT 0x80
3429 #define FLASH_ERROR_BIT 0x20
3430
3431 typedef struct _flash_t
3432 {
3433 uint32_t offset;
3434 uint8_t val;
3435 } flash_t;
3436
3437
3438
3439 static uint32_t
emlxs_write_fcode_flash(emlxs_hba_t * hba,PIMAGE_HDR ImageHdr,caddr_t Buffer)3440 emlxs_write_fcode_flash(emlxs_hba_t *hba,
3441 PIMAGE_HDR ImageHdr, caddr_t Buffer)
3442 {
3443 emlxs_port_t *port = &PPORT;
3444 uint8_t bb;
3445 uint8_t cc;
3446 uint8_t *src;
3447 uint32_t DlByteCount = ImageHdr->BlockSize;
3448 uint32_t i;
3449 uint32_t j;
3450 uint32_t k;
3451
3452 flash_t wr[3] = {
3453 {0x555, 0xaa},
3454 {0x2aa, 0x55},
3455 {0x555, 0xa0}
3456 };
3457
3458 /* Load Fcode */
3459 src = (uint8_t *)Buffer + sizeof (IMAGE_HDR);
3460 for (i = 0; i < DlByteCount; i++) {
3461 for (k = 0; k < 3; k++) {
3462 SBUS_WRITE_FLASH_COPY(hba, wr[k].offset, wr[k].val);
3463 }
3464
3465 /* Reverse Endian word alignment */
3466 j = (i & 3) ^ 3;
3467
3468 bb = src[j];
3469
3470 if (j == 0) {
3471 src += 4;
3472 }
3473
3474 SBUS_WRITE_FLASH_COPY(hba, i, bb);
3475
3476 /* check for complete */
3477 for (;;) {
3478 BUSYWAIT_US(20);
3479
3480 cc = SBUS_READ_FLASH_COPY(hba, i);
3481
3482 /* If data matches then continue */
3483 if (cc == bb) {
3484 break;
3485 }
3486
3487 /* Polling bit will be inverse final value */
3488 /* while active */
3489 if ((cc ^ bb) & FLASH_POLLING_BIT) {
3490 /* Still busy */
3491
3492 /* Check for error bit */
3493 if (cc & FLASH_ERROR_BIT) {
3494 /* Read data one more time */
3495 cc = SBUS_READ_FLASH_COPY(hba, i);
3496
3497 /* Check if data matches */
3498 if (cc == bb) {
3499 break;
3500 }
3501
3502 EMLXS_MSGF(EMLXS_CONTEXT,
3503 &emlxs_download_failed_msg,
3504 "FCode write error: offset:%x "
3505 "wrote:%x read:%x\n", i, bb, cc);
3506
3507 return (1);
3508 }
3509 }
3510 }
3511 }
3512
3513 /* Load Header */
3514 src = (uint8_t *)ImageHdr;
3515
3516 for (i = (0xFFFF - sizeof (IMAGE_HDR)); i < 0xFFFF; i++) {
3517 for (k = 0; k < 3; k++) {
3518 SBUS_WRITE_FLASH_COPY(hba, wr[k].offset, wr[k].val);
3519 }
3520
3521 /* Reverse Endian word alignment */
3522 j = (i & 3) ^ 3;
3523
3524 bb = src[j];
3525
3526 if (j == 0) {
3527 src += 4;
3528 }
3529
3530 SBUS_WRITE_FLASH_COPY(hba, i, bb);
3531
3532 /* check for complete */
3533 for (;;) {
3534 BUSYWAIT_US(20);
3535
3536 cc = SBUS_READ_FLASH_COPY(hba, i);
3537
3538 /* If data matches then continue */
3539 if (cc == bb) {
3540 break;
3541 }
3542
3543 /* Polling bit will be inverse final value */
3544 /* while active */
3545 if ((cc ^ bb) & FLASH_POLLING_BIT) {
3546 /* Still busy */
3547
3548 /* Check for error bit */
3549 if (cc & FLASH_ERROR_BIT) {
3550 /* Read data one more time */
3551 cc = SBUS_READ_FLASH_COPY(hba, i);
3552
3553 /* Check if data matches */
3554 if (cc == bb) {
3555 break;
3556 }
3557
3558 EMLXS_MSGF(EMLXS_CONTEXT,
3559 &emlxs_download_failed_msg,
3560 "FCode write error: offset:%x "
3561 "wrote:%x read:%x\n", i, bb, cc);
3562
3563 return (1);
3564 }
3565 }
3566 }
3567 }
3568
3569 #ifdef FMA_SUPPORT
3570 if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.sbus_flash_acc_handle)
3571 != DDI_FM_OK) {
3572 EMLXS_MSGF(EMLXS_CONTEXT,
3573 &emlxs_invalid_access_handle_msg, NULL);
3574 return (1);
3575 }
3576 #endif /* FMA_SUPPORT */
3577
3578 return (0);
3579
3580 } /* emlxs_write_fcode_flash() */
3581
3582
3583
3584 static uint32_t
emlxs_erase_fcode_flash(emlxs_hba_t * hba)3585 emlxs_erase_fcode_flash(emlxs_hba_t *hba)
3586 {
3587 emlxs_port_t *port = &PPORT;
3588 int32_t i, j;
3589 uint8_t cc;
3590 uint32_t offset;
3591
3592 flash_t ef[6] = {
3593 {0x555, 0xaa},
3594 {0x2aa, 0x55},
3595 {0x555, 0x80},
3596 {0x555, 0xaa},
3597 {0x2aa, 0x55},
3598 {0x555, 0x10}
3599 };
3600
3601 /* Auto select */
3602 flash_t as[3] = {
3603 {0x555, 0xaa},
3604 {0x2aa, 0x55},
3605 {0x555, 0x90}
3606 };
3607
3608
3609 /* Check Manufacturers Code */
3610 for (i = 0; i < 3; i++) {
3611 SBUS_WRITE_FLASH_COPY(hba, as[i].offset, as[i].val);
3612 }
3613
3614 cc = SBUS_READ_FLASH_COPY(hba, 0);
3615
3616 /* Check Device Code */
3617 for (i = 0; i < 3; i++) {
3618 SBUS_WRITE_FLASH_COPY(hba, as[i].offset, as[i].val);
3619 }
3620
3621 cc = SBUS_READ_FLASH_COPY(hba, 1);
3622
3623
3624 /* Check block protections (up to 4 16K blocks = 64K) */
3625 for (j = 0; j < 4; j++) {
3626 for (i = 0; i < 3; i++) {
3627 SBUS_WRITE_FLASH_COPY(hba, as[i].offset, as[i].val);
3628 }
3629
3630 offset = (j << 14) | 0x2;
3631
3632 cc = SBUS_READ_FLASH_COPY(hba, offset);
3633
3634 if (cc == 0x01) {
3635 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
3636 "Block %d is protected and can't be erased.", j);
3637 }
3638 }
3639
3640 /* Write erase flash sequence */
3641 for (i = 0; i < 6; i++) {
3642 SBUS_WRITE_FLASH_COPY(hba, ef[i].offset, ef[i].val);
3643 }
3644
3645 /* check for complete */
3646 for (;;) {
3647 /* Delay 3 seconds */
3648 BUSYWAIT_MS(3000);
3649
3650 cc = SBUS_READ_FLASH_COPY(hba, 0);
3651
3652
3653 /* If data matches then continue; */
3654 if (cc == 0xff) {
3655 break;
3656 }
3657
3658 /* Polling bit will be inverse final value while active */
3659 if ((cc ^ 0xff) & FLASH_POLLING_BIT) {
3660 /* Still busy */
3661
3662 /* Check for error bit */
3663 if (cc & FLASH_ERROR_BIT) {
3664 /* Read data one more time */
3665 cc = SBUS_READ_FLASH_COPY(hba, 0);
3666
3667 /* Check if data matches */
3668 if (cc == 0xff) {
3669 break;
3670 }
3671
3672 EMLXS_MSGF(EMLXS_CONTEXT,
3673 &emlxs_download_failed_msg,
3674 "FCode write error: offset:%x wrote:%x "
3675 "read:%x\n", i, 0xff, cc);
3676
3677 return (1);
3678 }
3679 }
3680 }
3681
3682 #ifdef FMA_SUPPORT
3683 if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.sbus_flash_acc_handle)
3684 != DDI_FM_OK) {
3685 EMLXS_MSGF(EMLXS_CONTEXT,
3686 &emlxs_invalid_access_handle_msg, NULL);
3687 return (1);
3688 }
3689 #endif /* FMA_SUPPORT */
3690
3691 return (0);
3692
3693 } /* emlxs_erase_fcode_flash() */
3694
3695
3696 static uint32_t
emlxs_delete_load_entry(emlxs_hba_t * hba,PROG_ID * progId)3697 emlxs_delete_load_entry(emlxs_hba_t *hba, PROG_ID *progId)
3698 {
3699 emlxs_port_t *port = &PPORT;
3700 MAILBOXQ *mbox = NULL;
3701 MAILBOX *mb;
3702 uint32_t rval = 0;
3703
3704 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
3705 KM_NOSLEEP)) == NULL) {
3706 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
3707 "Unable to allocate mailbox buffer.");
3708
3709 return (1);
3710 }
3711
3712 mb = (MAILBOX *)mbox;
3713 mb->mbxCommand = MBX_DEL_LD_ENTRY;
3714 mb->un.varDelLdEntry.list_req = FLASH_LOAD_LIST;
3715 mb->un.varDelLdEntry.prog_id = *progId;
3716
3717 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) {
3718 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
3719 "Unable to delete load entry: Mailbox cmd=%x status=%x",
3720 mb->mbxCommand, mb->mbxStatus);
3721
3722 rval = 1;
3723 }
3724
3725 done:
3726
3727 if (mbox) {
3728 kmem_free(mbox, sizeof (MAILBOXQ));
3729 }
3730
3731 return (rval);
3732
3733 } /* emlxs_delete_load_entry() */
3734
3735
3736 extern uint32_t
emlxs_get_load_list(emlxs_hba_t * hba,PROG_ID * load_list)3737 emlxs_get_load_list(emlxs_hba_t *hba, PROG_ID *load_list)
3738 {
3739 emlxs_port_t *port = &PPORT;
3740 LOAD_ENTRY *LoadEntry;
3741 LOAD_LIST *LoadList = NULL;
3742 uint32_t i;
3743 uint32_t count = 0;
3744
3745 bzero(load_list, (sizeof (PROG_ID) * MAX_LOAD_ENTRY));
3746
3747 if ((LoadList = (LOAD_LIST *)kmem_zalloc(sizeof (LOAD_LIST),
3748 KM_NOSLEEP)) == NULL) {
3749 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
3750 "Unable to allocate LOADLIST buffer.");
3751
3752 goto done;
3753 }
3754
3755 if (emlxs_read_load_list(hba, LoadList)) {
3756 goto done;
3757 }
3758
3759 for (i = 0; i < LoadList->entry_cnt; i++) {
3760 LoadEntry = &LoadList->load_entry[i];
3761 if ((LoadEntry->un.wd[0] != 0) &&
3762 (LoadEntry->un.wd[0] != 0xffffffff)) {
3763 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
3764 "Load List[%d]: %08x %08x", count,
3765 LoadEntry->un.wd[0], LoadEntry->un.wd[1]);
3766
3767 load_list[count++] = LoadEntry->un.id;
3768 }
3769 }
3770
3771 done:
3772
3773 if (LoadList) {
3774 kmem_free(LoadList, sizeof (LOAD_LIST));
3775 }
3776
3777 return (count);
3778
3779 } /* emlxs_get_load_list() */
3780
3781
3782 extern uint32_t
emlxs_read_wakeup_parms(emlxs_hba_t * hba,PWAKE_UP_PARMS WakeUpParms,uint32_t verbose)3783 emlxs_read_wakeup_parms(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms,
3784 uint32_t verbose)
3785 {
3786 emlxs_port_t *port = &PPORT;
3787 MAILBOXQ *mbox;
3788 MAILBOX *mb;
3789 uint32_t rval = 0;
3790 uint32_t *wd;
3791
3792 bzero(WakeUpParms, sizeof (WAKE_UP_PARMS));
3793
3794 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
3795 KM_NOSLEEP)) == NULL) {
3796 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
3797 "Unable to allocate mailbox buffer.");
3798
3799 return (1);
3800 }
3801
3802 mb = (MAILBOX *)mbox;
3803
3804 emlxs_format_dump(hba, mbox,
3805 DMP_NV_PARAMS,
3806 WAKE_UP_PARMS_REGION_ID,
3807 sizeof (WAKE_UP_PARMS) / sizeof (uint32_t), 0);
3808
3809 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) {
3810 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
3811 "Unable to get parameters: Mailbox cmd=%x status=%x",
3812 mb->mbxCommand, mb->mbxStatus);
3813
3814 if (mb->un.varDmp.word_cnt == (uint32_t)CFG_DATA_NO_REGION) {
3815 rval = (uint32_t)CFG_DATA_NO_REGION;
3816 } else {
3817 rval = 1;
3818 }
3819 } else {
3820 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3821 EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle,
3822 0, hba->sli.sli4.dump_region.size,
3823 DDI_DMA_SYNC_FORKERNEL);
3824
3825 bcopy((caddr_t)hba->sli.sli4.dump_region.virt,
3826 (caddr_t)WakeUpParms, sizeof (WAKE_UP_PARMS));
3827 } else {
3828 bcopy((caddr_t)&mb->un.varDmp.resp_offset,
3829 (caddr_t)WakeUpParms, sizeof (WAKE_UP_PARMS));
3830 }
3831
3832 if (verbose) {
3833 wd = (uint32_t *)&WakeUpParms->prog_id;
3834 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
3835 "Wakeup: prog_id=%08x %08x", wd[0], wd[1]);
3836
3837 wd = (uint32_t *)&WakeUpParms->u0.boot_bios_id;
3838 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
3839 "Wakeup: boot_bios_id=%08x %08x", wd[0], wd[1]);
3840
3841 wd = (uint32_t *)&WakeUpParms->sli1_prog_id;
3842 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
3843 "Wakeup: sli1_prog_id=%08x %08x", wd[0], wd[1]);
3844
3845 wd = (uint32_t *)&WakeUpParms->sli2_prog_id;
3846 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
3847 "Wakeup: sli2_prog_id=%08x %08x", wd[0], wd[1]);
3848
3849 wd = (uint32_t *)&WakeUpParms->sli3_prog_id;
3850 if (wd[0] || wd[1]) {
3851 EMLXS_MSGF(EMLXS_CONTEXT,
3852 &emlxs_init_debug_msg,
3853 "Wakeup: sli3_prog_id=%08x %08x", wd[0],
3854 wd[1]);
3855 }
3856
3857 wd = (uint32_t *)&WakeUpParms->sli4_prog_id;
3858 if (wd[0] || wd[1]) {
3859 EMLXS_MSGF(EMLXS_CONTEXT,
3860 &emlxs_init_debug_msg,
3861 "Wakeup: sli4_prog_id=%08x %08x", wd[0],
3862 wd[1]);
3863 }
3864
3865 wd = (uint32_t *)&WakeUpParms->u1.EROM_prog_id;
3866 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
3867 "Wakeup: EROM_prog_id=%08x %08x", wd[0], wd[1]);
3868
3869 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
3870 "Wakeup: pci_cfg_rsvd=%x",
3871 WakeUpParms->pci_cfg_rsvd);
3872 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
3873 "Wakeup: use_hdw_def=%x",
3874 WakeUpParms->use_hdw_def);
3875 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
3876 "Wakeup: pci_cfg_sel=%x",
3877 WakeUpParms->pci_cfg_sel);
3878 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
3879 "Wakeup: cfg_lookup=%x",
3880 WakeUpParms->pci_cfg_lookup_sel);
3881 }
3882 }
3883
3884 done:
3885
3886 if (mbox) {
3887 kmem_free(mbox, sizeof (MAILBOXQ));
3888 }
3889
3890 #ifdef FMA_SUPPORT
3891 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3892 if (emlxs_fm_check_dma_handle(hba,
3893 hba->sli.sli4.dump_region.dma_handle) != DDI_FM_OK) {
3894 EMLXS_MSGF(EMLXS_CONTEXT,
3895 &emlxs_invalid_dma_handle_msg,
3896 "read_wakeup_parms: hdl=%p",
3897 hba->sli.sli4.dump_region.dma_handle);
3898 rval = 1;
3899 }
3900 }
3901 #endif /* FMA_SUPPORT */
3902
3903 return (rval);
3904
3905 } /* emlxs_read_wakeup_parms() */
3906
3907
3908 static uint32_t
emlxs_read_load_list(emlxs_hba_t * hba,LOAD_LIST * LoadList)3909 emlxs_read_load_list(emlxs_hba_t *hba, LOAD_LIST *LoadList)
3910 {
3911 emlxs_port_t *port = &PPORT;
3912 LOAD_ENTRY *LoadEntry;
3913 uint32_t *Uptr;
3914 uint32_t CurEntryAddr;
3915 MAILBOXQ *mbox = NULL;
3916 MAILBOX *mb;
3917
3918 bzero((caddr_t)LoadList, sizeof (LOAD_LIST));
3919
3920 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
3921 KM_NOSLEEP)) == NULL) {
3922 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
3923 "Unable to allocate mailbox buffer.");
3924
3925 return (1);
3926 }
3927
3928 mb = (MAILBOX *)mbox;
3929
3930 emlxs_format_dump(hba, mbox, DMP_MEM_REG, 0, 2, FLASH_LOAD_LIST_ADR);
3931
3932 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) {
3933 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
3934 "Unable to get load list: Mailbox cmd=%x status=%x",
3935 mb->mbxCommand, mb->mbxStatus);
3936
3937 goto done;
3938 }
3939
3940 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3941 EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle, 0,
3942 hba->sli.sli4.dump_region.size, DDI_DMA_SYNC_FORKERNEL);
3943 Uptr = (uint32_t *)hba->sli.sli4.dump_region.virt;
3944 } else {
3945 Uptr = (uint32_t *)&mb->un.varDmp.resp_offset;
3946 }
3947
3948 LoadList->head = Uptr[0];
3949 LoadList->tail = Uptr[1];
3950
3951 CurEntryAddr = LoadList->head;
3952
3953 while ((CurEntryAddr != FLASH_LOAD_LIST_ADR) &&
3954 (LoadList->entry_cnt < MAX_LOAD_ENTRY)) {
3955 LoadEntry = &LoadList->load_entry[LoadList->entry_cnt];
3956 LoadList->entry_cnt++;
3957
3958 emlxs_format_dump(hba, mbox,
3959 DMP_MEM_REG, 0, FLASH_LOAD_ENTRY_SIZE, CurEntryAddr);
3960
3961 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) !=
3962 MBX_SUCCESS) {
3963 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
3964 "Unable to get load list (%d): Mailbox cmd=%x "
3965 "status=%x", LoadList->entry_cnt, mb->mbxCommand,
3966 mb->mbxStatus);
3967
3968 goto done;
3969 }
3970
3971 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3972 EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle,
3973 0, hba->sli.sli4.dump_region.size,
3974 DDI_DMA_SYNC_FORKERNEL);
3975 Uptr = (uint32_t *)hba->sli.sli4.dump_region.virt;
3976 } else {
3977 Uptr = (uint32_t *)&mb->un.varDmp.resp_offset;
3978 }
3979
3980 LoadEntry->next = Uptr[0];
3981 LoadEntry->prev = Uptr[1];
3982 LoadEntry->start_adr = Uptr[2];
3983 LoadEntry->len = Uptr[3];
3984 LoadEntry->un.wd[0] = Uptr[4];
3985 LoadEntry->un.wd[1] = Uptr[5];
3986
3987 /* update next current load entry address */
3988 CurEntryAddr = LoadEntry->next;
3989
3990 } /* end of while (not end of list) */
3991
3992 done:
3993
3994 if (mbox) {
3995 kmem_free(mbox, sizeof (MAILBOXQ));
3996 }
3997
3998 #ifdef FMA_SUPPORT
3999 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
4000 if (emlxs_fm_check_dma_handle(hba,
4001 hba->sli.sli4.dump_region.dma_handle) != DDI_FM_OK) {
4002 EMLXS_MSGF(EMLXS_CONTEXT,
4003 &emlxs_invalid_dma_handle_msg,
4004 "read_load_list: hdl=%p",
4005 hba->sli.sli4.dump_region.dma_handle);
4006 return (1);
4007 }
4008 }
4009 #endif /* FMA_SUPPORT */
4010
4011 return (0);
4012
4013 } /* emlxs_read_load_list() */
4014
4015
4016 extern uint32_t
emlxs_get_boot_config(emlxs_hba_t * hba,uint8_t * boot_state)4017 emlxs_get_boot_config(emlxs_hba_t *hba, uint8_t *boot_state)
4018 {
4019 emlxs_port_t *port = &PPORT;
4020 MAILBOXQ *mbq;
4021 MAILBOX4 *mb;
4022 mbox_req_hdr_t *hdr_req;
4023 IOCTL_COMMON_BOOT_CFG *boot_cfg;
4024
4025 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) {
4026 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
4027 "Invalid sli_mode. mode=%d", hba->sli_mode);
4028
4029 return (1);
4030 }
4031
4032 if ((mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
4033 KM_NOSLEEP)) == NULL) {
4034 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
4035 "Unable to allocate mailbox buffer.");
4036
4037 return (1);
4038 }
4039
4040 mb = (MAILBOX4 *)mbq;
4041 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
4042
4043 mb->un.varSLIConfig.be.embedded = 1;
4044 mbq->nonembed = NULL;
4045 mbq->mbox_cmpl = NULL;
4046
4047 mb->mbxCommand = MBX_SLI_CONFIG;
4048 mb->mbxOwner = OWN_HOST;
4049
4050 hdr_req = (mbox_req_hdr_t *)
4051 &mb->un.varSLIConfig.be.un_hdr.hdr_req;
4052 hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON;
4053 hdr_req->opcode = COMMON_OPCODE_GET_BOOT_CFG;
4054
4055 boot_cfg = (IOCTL_COMMON_BOOT_CFG *)(hdr_req + 1);
4056
4057 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) {
4058 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
4059 "Unable to read boot config: Mailbox cmd=%x "
4060 "status=%x", mb->mbxCommand, mb->mbxStatus);
4061
4062 kmem_free(mbq, sizeof (MAILBOXQ));
4063 return (1);
4064 }
4065
4066 *boot_state = boot_cfg->params.response.boot_status;
4067
4068 kmem_free(mbq, sizeof (MAILBOXQ));
4069 return (0);
4070 }
4071
4072
4073 extern uint32_t
emlxs_set_boot_config(emlxs_hba_t * hba,uint8_t boot_state)4074 emlxs_set_boot_config(emlxs_hba_t *hba, uint8_t boot_state)
4075 {
4076 emlxs_port_t *port = &PPORT;
4077 MAILBOXQ *mbq;
4078 MAILBOX4 *mb;
4079 mbox_req_hdr_t *hdr_req;
4080 IOCTL_COMMON_BOOT_CFG *boot_cfg;
4081
4082 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) {
4083 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
4084 "Invalid sli_mode. mode=%d", hba->sli_mode);
4085
4086 return (1);
4087 }
4088
4089 if ((mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
4090 KM_NOSLEEP)) == NULL) {
4091 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
4092 "Unable to allocate mailbox buffer.");
4093
4094 return (1);
4095 }
4096
4097 mb = (MAILBOX4 *)mbq;
4098 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
4099
4100 mb->un.varSLIConfig.be.embedded = 1;
4101 mbq->nonembed = NULL;
4102 mbq->mbox_cmpl = NULL;
4103
4104 mb->mbxCommand = MBX_SLI_CONFIG;
4105 mb->mbxOwner = OWN_HOST;
4106
4107 hdr_req = (mbox_req_hdr_t *)
4108 &mb->un.varSLIConfig.be.un_hdr.hdr_req;
4109 hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON;
4110 hdr_req->opcode = COMMON_OPCODE_SET_BOOT_CFG;
4111
4112 boot_cfg = (IOCTL_COMMON_BOOT_CFG *)(hdr_req + 1);
4113 boot_cfg->params.request.boot_status = boot_state;
4114
4115 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) {
4116 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
4117 "Unable to read boot config: Mailbox cmd=%x "
4118 "status=%x", mb->mbxCommand, mb->mbxStatus);
4119
4120 kmem_free(mbq, sizeof (MAILBOXQ));
4121 return (1);
4122 }
4123
4124 kmem_free(mbq, sizeof (MAILBOXQ));
4125 return (0);
4126 }
4127
4128
4129
4130
4131 static int
emlxs_build_parms(caddr_t Buffer,PWAKE_UP_PARMS AbsWakeUpParms,uint32_t BufferSize,PAIF_HDR AifHeader)4132 emlxs_build_parms(caddr_t Buffer,
4133 PWAKE_UP_PARMS AbsWakeUpParms,
4134 uint32_t BufferSize, PAIF_HDR AifHeader)
4135 {
4136 IMAGE_HDR ImageHdr;
4137 uint32_t NextImage;
4138 uint32_t i;
4139 int32_t ChangeParams = FALSE;
4140 caddr_t Sptr;
4141 caddr_t Dptr;
4142
4143 bzero((caddr_t)AbsWakeUpParms, sizeof (WAKE_UP_PARMS));
4144
4145 if ((AifHeader->ImageBase != 0x20000) &&
4146 ((AifHeader->RoSize + AifHeader->RwSize) <= 0x20000)) {
4147 return (FALSE);
4148 }
4149
4150 NextImage = SLI_IMAGE_START - AifHeader->ImageBase;
4151
4152 while (BufferSize > NextImage) {
4153 Sptr = &Buffer[NextImage];
4154 Dptr = (caddr_t)&ImageHdr;
4155 for (i = 0; i < sizeof (IMAGE_HDR); i++) {
4156 Dptr[i] = Sptr[i];
4157 }
4158
4159 if (ImageHdr.BlockSize == 0xffffffff)
4160 break;
4161
4162 switch (ImageHdr.Id.Type) {
4163 case TEST_PROGRAM:
4164 break;
4165 case FUNC_FIRMWARE:
4166 AbsWakeUpParms->prog_id = ImageHdr.Id;
4167 ChangeParams = TRUE;
4168 break;
4169 case BOOT_BIOS:
4170 AbsWakeUpParms->u0.boot_bios_id = ImageHdr.Id;
4171 ChangeParams = TRUE;
4172 break;
4173 case SLI1_OVERLAY:
4174 AbsWakeUpParms->sli1_prog_id = ImageHdr.Id;
4175 ChangeParams = TRUE;
4176 break;
4177 case SLI2_OVERLAY:
4178 AbsWakeUpParms->sli2_prog_id = ImageHdr.Id;
4179 ChangeParams = TRUE;
4180 break;
4181 case SLI3_OVERLAY:
4182 AbsWakeUpParms->sli3_prog_id = ImageHdr.Id;
4183 ChangeParams = TRUE;
4184 break;
4185 case SLI4_OVERLAY:
4186 AbsWakeUpParms->sli4_prog_id = ImageHdr.Id;
4187 ChangeParams = TRUE;
4188 break;
4189 default:
4190 break;
4191 }
4192
4193 NextImage += ImageHdr.BlockSize;
4194 }
4195
4196 return (ChangeParams);
4197
4198 } /* emlxs_build_parms() */
4199
4200
4201 static uint32_t
emlxs_update_wakeup_parms(emlxs_hba_t * hba,PWAKE_UP_PARMS AbsWakeUpParms,PWAKE_UP_PARMS WakeUpParms)4202 emlxs_update_wakeup_parms(emlxs_hba_t *hba,
4203 PWAKE_UP_PARMS AbsWakeUpParms, PWAKE_UP_PARMS WakeUpParms)
4204 {
4205 emlxs_port_t *port = &PPORT;
4206 MAILBOX *mb;
4207 MAILBOXQ *mbox;
4208 uint32_t rval = 0;
4209
4210 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
4211 KM_NOSLEEP)) == NULL) {
4212 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
4213 "Unable to allocate mailbox buffer.");
4214
4215 return (1);
4216 }
4217
4218 mb = (MAILBOX *)mbox;
4219
4220 WakeUpParms->prog_id = AbsWakeUpParms->prog_id;
4221 WakeUpParms->u0.boot_bios_id = AbsWakeUpParms->u0.boot_bios_id;
4222 WakeUpParms->sli1_prog_id = AbsWakeUpParms->sli1_prog_id;
4223 WakeUpParms->sli2_prog_id = AbsWakeUpParms->sli2_prog_id;
4224 WakeUpParms->sli3_prog_id = AbsWakeUpParms->sli3_prog_id;
4225 WakeUpParms->sli4_prog_id = AbsWakeUpParms->sli4_prog_id;
4226
4227 emlxs_format_update_parms(mbox, WakeUpParms);
4228
4229 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) {
4230 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
4231 "Unable to update wakeup parameters: Mailbox cmd=%x "
4232 "status=%x", mb->mbxCommand, mb->mbxStatus);
4233
4234 rval = 1;
4235 }
4236
4237 if (mbox) {
4238 kmem_free(mbox, sizeof (MAILBOXQ));
4239 }
4240
4241 return (rval);
4242
4243 } /* emlxs_update_wakeup_parms() */
4244
4245
4246 static uint32_t
emlxs_validate_version(emlxs_hba_t * hba,emlxs_fw_file_t * file,uint32_t id,uint32_t type,char * file_type)4247 emlxs_validate_version(emlxs_hba_t *hba, emlxs_fw_file_t *file, uint32_t id,
4248 uint32_t type, char *file_type)
4249 {
4250 emlxs_port_t *port = &PPORT;
4251
4252 /* Create the version label */
4253 emlxs_decode_version(file->version, file->label, sizeof (file->label));
4254
4255 /* Process the DWC type */
4256 switch (type) {
4257 case TEST_PROGRAM:
4258
4259 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
4260 "%s: TEST: offset=%08x version=%08x, %s", file_type,
4261 file->offset, file->version, file->label);
4262
4263 break;
4264
4265 case BOOT_BIOS:
4266
4267 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
4268 "%s: BOOT: offset=%08x version=%08x, %s", file_type,
4269 file->offset, file->version, file->label);
4270
4271 if (!emlxs_bios_check(hba, id)) {
4272 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
4273 "BOOT Check: Image not compatible with %s. id=%02x",
4274 hba->model_info.model, id);
4275
4276 return (EMLXS_IMAGE_INCOMPATIBLE);
4277 }
4278
4279 break;
4280
4281 case FUNC_FIRMWARE: /* Stub */
4282
4283 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
4284 "%s: STUB: offset=%08x version=%08x, %s", file_type,
4285 file->offset, file->version, file->label);
4286
4287 if (!emlxs_stub_check(hba, id)) {
4288 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
4289 "STUB Check: Image not compatible with %s. id=%02x",
4290 hba->model_info.model, id);
4291
4292 return (EMLXS_IMAGE_INCOMPATIBLE);
4293 }
4294
4295 break;
4296
4297 case SLI1_OVERLAY:
4298
4299 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
4300 "%s: SLI1: offset=%08x version=%08x, %s", file_type,
4301 file->offset, file->version, file->label);
4302
4303 if (!emlxs_sli1_check(hba, id)) {
4304 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
4305 "SLI1 Check: Image not compatible with %s. id=%02x",
4306 hba->model_info.model, id);
4307
4308 return (EMLXS_IMAGE_INCOMPATIBLE);
4309 }
4310
4311 break;
4312
4313 case SLI2_OVERLAY:
4314
4315 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
4316 "%s: SLI2: offset=%08x version=%08x, %s", file_type,
4317 file->offset, file->version, file->label);
4318
4319 if (!emlxs_sli2_check(hba, id)) {
4320 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
4321 "SLI2 Check: Image not compatible with %s. id=%02x",
4322 hba->model_info.model, id);
4323
4324 return (EMLXS_IMAGE_INCOMPATIBLE);
4325 }
4326
4327 break;
4328
4329 case SLI3_OVERLAY:
4330
4331 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
4332 "%s: SLI3: offset=%08x version=%08x, %s", file_type,
4333 file->offset, file->version, file->label);
4334
4335 if (!emlxs_sli3_check(hba, id)) {
4336 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
4337 "SLI3 Check: Image not compatible with %s. id=%02x",
4338 hba->model_info.model, id);
4339
4340 return (EMLXS_IMAGE_INCOMPATIBLE);
4341 }
4342
4343 break;
4344
4345 case SLI4_OVERLAY:
4346
4347 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
4348 "%s: SLI4: offset=%08x version=%08x, %s", file_type,
4349 file->offset, file->version, file->label);
4350
4351 if (!emlxs_sli4_check(hba, id)) {
4352 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
4353 "SLI4 Check: Image not compatible with %s. id=%02x",
4354 hba->model_info.model, id);
4355
4356 return (EMLXS_IMAGE_INCOMPATIBLE);
4357 }
4358
4359 break;
4360
4361 case SBUS_FCODE:
4362
4363 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
4364 "%s: SBUS FCODE: offset=%08x version=%08x, %s",
4365 file_type, file->offset, file->version, file->label);
4366
4367 if (!emlxs_sbus_fcode_check(hba, id)) {
4368 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
4369 "SBUS FCODE Check: Image not compatible with %s. "
4370 "id=%02x", hba->model_info.model, id);
4371
4372 return (EMLXS_IMAGE_INCOMPATIBLE);
4373 }
4374
4375 break;
4376
4377 case KERNEL_CODE:
4378
4379 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
4380 "%s: KERN: offset=%08x version=%08x, %s", file_type,
4381 file->offset, file->version, file->label);
4382
4383 if (!emlxs_kern_check(hba, id)) {
4384 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_incompat_msg,
4385 "KERN Check: Image not compatible with %s. id=%02x",
4386 hba->model_info.model, id);
4387
4388 return (EMLXS_IMAGE_INCOMPATIBLE);
4389 }
4390
4391 break;
4392
4393 default:
4394 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
4395 "%s: Image type not supported. type=%x", file_type, type);
4396
4397 return (EMLXS_IMAGE_BAD);
4398 }
4399
4400 return (0);
4401
4402 } /* emlxs_validate_version() */
4403
4404
4405 static void
emlxs_verify_image(emlxs_hba_t * hba,emlxs_fw_image_t * fw_image)4406 emlxs_verify_image(emlxs_hba_t *hba, emlxs_fw_image_t *fw_image)
4407 {
4408 emlxs_port_t *port = &PPORT;
4409 emlxs_vpd_t *vpd = &VPD;
4410 uint32_t i;
4411 uint32_t count;
4412
4413 /* Check for AWC file */
4414 if (fw_image->awc.version) {
4415 if (fw_image->awc.version == vpd->postKernRev) {
4416 fw_image->awc.version = 0;
4417 }
4418
4419 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
4420 "AWC file: KERN: old=%s new=%s %s.",
4421 vpd->postKernName,
4422 fw_image->awc.label,
4423 (fw_image->awc.version)? "Update":"Skip");
4424 }
4425
4426 /* Check for BWC file */
4427 if (fw_image->bwc.version) {
4428 if (strcmp(vpd->fcode_version, fw_image->bwc.label) == 0) {
4429 fw_image->bwc.version = 0;
4430 }
4431
4432 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
4433 "BWC file: BOOT: old=%s new=%s %s.",
4434 vpd->fcode_version,
4435 fw_image->bwc.label,
4436 (fw_image->bwc.version)? "Update":"Skip");
4437 }
4438
4439 /* Check for DWC file */
4440 if (fw_image->dwc.version) {
4441 /* Check for program files */
4442 count = 0;
4443 for (i = 0; i < MAX_PROG_TYPES; i++) {
4444 if (!fw_image->prog[i].version) {
4445 continue;
4446 }
4447
4448 /* Skip components that don't need updating */
4449 switch (i) {
4450 case TEST_PROGRAM:
4451 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
4452 "DWC file: TEST: new=%s "
4453 "Update.",
4454 fw_image->prog[i].label);
4455 break;
4456
4457 case BOOT_BIOS:
4458 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
4459 "DWC file: BOOT: new=%s "
4460 "Update.",
4461 fw_image->prog[i].label);
4462 break;
4463
4464 case FUNC_FIRMWARE:
4465 if (vpd->opFwRev &&
4466 (fw_image->prog[i].version ==
4467 vpd->opFwRev)) {
4468 fw_image->prog[i].version = 0;
4469 }
4470
4471 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
4472 "DWC file: STUB: old=%s new=%s %s.",
4473 vpd->opFwName,
4474 fw_image->prog[i].label,
4475 (fw_image->prog[i].version)?
4476 "Update":"Skip");
4477 break;
4478
4479 case SLI1_OVERLAY:
4480 if (vpd->sli1FwRev &&
4481 (fw_image->prog[i].version ==
4482 vpd->sli1FwRev)) {
4483 fw_image->prog[i].version = 0;
4484 }
4485
4486 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
4487 "DWC file: SLI1: old=%s new=%s %s.",
4488 vpd->sli1FwName,
4489 fw_image->prog[i].label,
4490 (fw_image->prog[i].version)?
4491 "Update":"Skip");
4492 break;
4493
4494 case SLI2_OVERLAY:
4495 if (vpd->sli2FwRev &&
4496 (fw_image->prog[i].version ==
4497 vpd->sli2FwRev)) {
4498 fw_image->prog[i].version = 0;
4499 }
4500
4501 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
4502 "DWC file: SLI2: old=%s new=%s %s.",
4503 vpd->sli2FwName,
4504 fw_image->prog[i].label,
4505 (fw_image->prog[i].version)?
4506 "Update":"Skip");
4507 break;
4508
4509 case SLI3_OVERLAY:
4510 if (vpd->sli3FwRev &&
4511 (fw_image->prog[i].version ==
4512 vpd->sli3FwRev)) {
4513 fw_image->prog[i].version = 0;
4514 }
4515
4516 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
4517 "DWC file: SLI3: old=%s new=%s %s.",
4518 vpd->sli3FwName,
4519 fw_image->prog[i].label,
4520 (fw_image->prog[i].version)?
4521 "Update":"Skip");
4522 break;
4523
4524 case SLI4_OVERLAY:
4525 if (vpd->sli4FwRev &&
4526 (fw_image->prog[i].version ==
4527 vpd->sli4FwRev)) {
4528 fw_image->prog[i].version = 0;
4529 }
4530
4531 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
4532 "DWC file: SLI4: old=%s new=%s %s.",
4533 vpd->sli4FwRev,
4534 fw_image->prog[i].label,
4535 (fw_image->prog[i].version)?
4536 "Update":"Skip");
4537 break;
4538
4539 default:
4540 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
4541 "DWC file: type=%x version=%x label=%s "
4542 "Update.",
4543 i,
4544 fw_image->prog[i].version,
4545 fw_image->prog[i].label);
4546 }
4547
4548 if (fw_image->prog[i].version) {
4549 count++;
4550 }
4551 }
4552
4553 if (!count) {
4554 fw_image->dwc.version = 0;
4555 }
4556 }
4557
4558 return;
4559
4560 } /* emlxs_verify_image() */
4561
4562
4563 static uint32_t
emlxs_validate_image(emlxs_hba_t * hba,caddr_t Buffer,uint32_t Size,emlxs_fw_image_t * image)4564 emlxs_validate_image(emlxs_hba_t *hba, caddr_t Buffer, uint32_t Size,
4565 emlxs_fw_image_t *image)
4566 {
4567 emlxs_port_t *port = &PPORT;
4568 uint32_t ImageType;
4569 AIF_HDR AifHdr;
4570 IMAGE_HDR ImageHdr;
4571 uint32_t NextImage;
4572 uint32_t count;
4573 uint32_t FileType;
4574 uint32_t FileLen = 0;
4575 uint32_t TotalLen = 0;
4576 uint32_t *CkSumEnd;
4577 uint32_t id;
4578 uint32_t type;
4579 uint32_t ver;
4580 uint32_t ImageLength;
4581 uint32_t BufferSize;
4582 uint32_t rval = 0;
4583 caddr_t bptr;
4584 emlxs_vpd_t *vpd;
4585
4586 vpd = &VPD;
4587
4588 /* Get image type */
4589 ImageType = *((uint32_t *)Buffer);
4590
4591 /* Pegasus and beyond adapters */
4592 if ((ImageType == NOP_IMAGE_TYPE) &&
4593 !(hba->model_info.chip &
4594 (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) {
4595 bptr = Buffer;
4596 TotalLen = sizeof (uint32_t);
4597
4598 while (TotalLen < Size) {
4599 if (Size < sizeof (AIF_HDR)) {
4600 EMLXS_MSGF(EMLXS_CONTEXT,
4601 &emlxs_image_bad_msg,
4602 "Invalid image header length: 0x%x < 0x%x",
4603 Size, sizeof (AIF_HDR));
4604
4605 return (EMLXS_IMAGE_BAD);
4606 }
4607
4608 bcopy(bptr, &AifHdr, sizeof (AIF_HDR));
4609 emlxs_disp_aif_header(hba, &AifHdr);
4610
4611 ImageLength = AifHdr.RoSize;
4612
4613 /* Validate checksum */
4614 CkSumEnd =
4615 (uint32_t *)(bptr + ImageLength +
4616 sizeof (AIF_HDR));
4617 if (emlxs_valid_cksum((uint32_t *)bptr, CkSumEnd)) {
4618 EMLXS_MSGF(EMLXS_CONTEXT,
4619 &emlxs_image_bad_msg,
4620 "Invalid checksum found.");
4621
4622 return (EMLXS_IMAGE_BAD);
4623 }
4624
4625 FileType = AifHdr.ZinitBr;
4626 switch (FileType) {
4627 case FILE_TYPE_AWC:
4628 image->awc.offset =
4629 (uint32_t)((uintptr_t)bptr -
4630 (uintptr_t)Buffer);
4631 image->awc.version = AifHdr.AVersion;
4632 image->awc.revcomp = 0;
4633
4634 id = (AifHdr.AVersion & 0x00ff0000) >> 16;
4635 type = emlxs_type_check(
4636 (AifHdr.AVersion & 0xff000000) >> 24);
4637
4638 /* Validate the file version */
4639 if ((rval = emlxs_validate_version(hba,
4640 &image->awc, id, type, "AWC file"))) {
4641 return (rval);
4642 }
4643
4644 break;
4645
4646 case FILE_TYPE_BWC:
4647 image->bwc.offset =
4648 (uint32_t)((uintptr_t)bptr -
4649 (uintptr_t)Buffer);
4650 image->bwc.version = AifHdr.AVersion;
4651 image->bwc.revcomp = 0;
4652
4653 id = (AifHdr.AVersion & 0x00ff0000) >> 16;
4654 type = emlxs_type_check(
4655 (AifHdr.AVersion & 0xff000000) >> 24);
4656
4657 /* Validate the file version */
4658 if ((rval = emlxs_validate_version(hba,
4659 &image->bwc, id, type, "BWC file"))) {
4660 return (rval);
4661 }
4662
4663 break;
4664
4665 case FILE_TYPE_DWC:
4666 image->dwc.offset =
4667 (uint32_t)((uintptr_t)bptr -
4668 (uintptr_t)Buffer);
4669 image->dwc.version = AifHdr.AVersion;
4670 image->dwc.revcomp = 0;
4671
4672 id = (AifHdr.AVersion & 0x00ff0000) >> 16;
4673 type = emlxs_type_check(
4674 (AifHdr.AVersion & 0xff000000) >> 24);
4675
4676 /* Validate the file version */
4677 if ((rval = emlxs_validate_version(hba,
4678 &image->dwc, id, type, "DWC file"))) {
4679 return (rval);
4680 }
4681
4682 /* Scan for program types */
4683 NextImage = sizeof (AIF_HDR) + 4;
4684 BufferSize = AifHdr.RoSize + AifHdr.RwSize;
4685
4686 count = 0;
4687 while (BufferSize > NextImage) {
4688 bcopy(&bptr[NextImage], &ImageHdr,
4689 sizeof (IMAGE_HDR));
4690 emlxs_dump_image_header(hba,
4691 &ImageHdr);
4692
4693 /* Validate block size */
4694 if (ImageHdr.BlockSize == 0xffffffff) {
4695 break;
4696 }
4697
4698 type = emlxs_type_check(
4699 ImageHdr.Id.Type);
4700
4701 /* Calculate the program offset */
4702 image->prog[type].offset =
4703 (uint32_t)((uintptr_t)
4704 &bptr[NextImage] -
4705 (uintptr_t)Buffer);
4706
4707 /* Acquire the versions */
4708 image->prog[type].version =
4709 (ImageHdr.Id.Type << 24) |
4710 (ImageHdr.Id.Id << 16) |
4711 (ImageHdr.Id.Ver << 8) |
4712 ImageHdr.Id.Rev;
4713
4714 image->prog[type].revcomp =
4715 ImageHdr.Id.un.revcomp;
4716
4717 /* Validate the file version */
4718 if ((rval = emlxs_validate_version(hba,
4719 &image->prog[type], ImageHdr.Id.Id,
4720 type, "DWC prog"))) {
4721 return (rval);
4722 }
4723
4724 count++;
4725 NextImage += ImageHdr.BlockSize;
4726
4727 } /* while () */
4728
4729 if (count == 0) {
4730 EMLXS_MSGF(EMLXS_CONTEXT,
4731 &emlxs_image_bad_msg,
4732 "DWC file has no PRG images.");
4733
4734 return (EMLXS_IMAGE_BAD);
4735 }
4736
4737 break;
4738 }
4739
4740 FileLen =
4741 sizeof (AIF_HDR) + ImageLength +
4742 sizeof (uint32_t);
4743 TotalLen += FileLen;
4744 bptr += FileLen;
4745 }
4746 }
4747
4748 /* Pre-pegasus adapters */
4749
4750 else if (ImageType == NOP_IMAGE_TYPE) {
4751 if (Size < sizeof (AIF_HDR)) {
4752 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
4753 "Invalid image header length: 0x%x < 0x%x", Size,
4754 sizeof (AIF_HDR));
4755
4756 return (EMLXS_IMAGE_BAD);
4757 }
4758
4759 bcopy(Buffer, &AifHdr, sizeof (AIF_HDR));
4760 emlxs_disp_aif_header(hba, &AifHdr);
4761
4762 ImageLength = AifHdr.RoSize + AifHdr.RwSize;
4763
4764 if (Size != (sizeof (AIF_HDR) + ImageLength + sizeof (int))) {
4765 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
4766 "Image length incorrect: 0x%x != 0x%x", Size,
4767 sizeof (AIF_HDR) + ImageLength +
4768 sizeof (uint32_t));
4769
4770 return (EMLXS_IMAGE_BAD);
4771 }
4772
4773 if (AifHdr.ImageBase && AifHdr.ImageBase != 0x20000) {
4774 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
4775 "Invalid imageBase value %x != 0x20000",
4776 AifHdr.ImageBase);
4777
4778 return (EMLXS_IMAGE_BAD);
4779 }
4780
4781 CkSumEnd =
4782 (uint32_t *)(Buffer + ImageLength + sizeof (AIF_HDR));
4783 if (emlxs_valid_cksum((uint32_t *)Buffer, CkSumEnd)) {
4784 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
4785 "Invalid checksum found.");
4786
4787 return (EMLXS_IMAGE_BAD);
4788 }
4789
4790 image->dwc.offset = 0;
4791 image->dwc.version = AifHdr.AVersion;
4792 image->dwc.revcomp = 0;
4793
4794 id = (AifHdr.AVersion & 0x00ff0000) >> 16;
4795 type = emlxs_type_check((AifHdr.AVersion & 0xff000000) >> 24);
4796
4797 /* Validate the file version */
4798 if ((rval = emlxs_validate_version(hba, &image->dwc, id, type,
4799 "DWC file"))) {
4800 return (rval);
4801 }
4802
4803 NextImage = SLI_IMAGE_START - AifHdr.ImageBase;
4804 while (Size > NextImage) {
4805 bcopy(&Buffer[NextImage], &ImageHdr,
4806 sizeof (IMAGE_HDR));
4807 emlxs_dump_image_header(hba, &ImageHdr);
4808
4809 /* Validate block size */
4810 if (ImageHdr.BlockSize == 0xffffffff) {
4811 break;
4812 }
4813
4814 type = emlxs_type_check(ImageHdr.Id.Type);
4815
4816 /* Calculate the program offset */
4817 image->prog[type].offset = NextImage;
4818
4819 /* Acquire the versions */
4820 image->prog[type].version =
4821 (ImageHdr.Id.Type << 24) |
4822 (ImageHdr.Id.Id << 16) |
4823 (ImageHdr.Id.Ver << 8) |
4824 ImageHdr.Id.Rev;
4825
4826 image->prog[type].revcomp = ImageHdr.Id.un.revcomp;
4827
4828 /* Validate the file version */
4829 if ((rval = emlxs_validate_version(hba,
4830 &image->prog[type], ImageHdr.Id.Id, type,
4831 "DWC prog"))) {
4832 return (rval);
4833 }
4834
4835 NextImage += ImageHdr.BlockSize;
4836 }
4837
4838 } else { /* PRG File */
4839
4840 /* Precheck image size */
4841 if (Size < sizeof (IMAGE_HDR)) {
4842 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
4843 "Invalid image header length: 0x%x < 0x%x", Size,
4844 sizeof (IMAGE_HDR));
4845
4846 return (EMLXS_IMAGE_BAD);
4847 }
4848
4849 bcopy(Buffer, &ImageHdr, sizeof (IMAGE_HDR));
4850 emlxs_dump_image_header(hba, &ImageHdr);
4851
4852 /* Validate block size */
4853 if (ImageHdr.BlockSize == 0xffffffff) {
4854 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
4855 "Invalid block size.");
4856
4857 return (EMLXS_IMAGE_BAD);
4858 }
4859
4860 ImageLength = ImageHdr.BlockSize;
4861
4862 /* Validate image length */
4863 if (Size != ImageLength) {
4864 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
4865 "Invalid image length: 0x%x != 0x%x", Size,
4866 ImageLength);
4867
4868 return (EMLXS_IMAGE_BAD);
4869 }
4870
4871 /* Validate Checksum */
4872 CkSumEnd =
4873 (uint32_t *)Buffer + (ImageLength / sizeof (uint32_t)) -
4874 1;
4875 if (emlxs_valid_cksum((uint32_t *)Buffer, CkSumEnd)) {
4876 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
4877 "Invalid checksum found.");
4878
4879 return (EMLXS_IMAGE_BAD);
4880 }
4881
4882 type = emlxs_type_check(ImageHdr.Id.Type);
4883
4884 /* Calculate the program offset */
4885 image->prog[type].offset = 0;
4886
4887 /* Acquire the versions */
4888 image->prog[type].version =
4889 (ImageHdr.Id.Type << 24) |
4890 (ImageHdr.Id.Id << 16) |
4891 (ImageHdr.Id.Ver << 8) |
4892 ImageHdr.Id.Rev;
4893
4894 image->prog[type].revcomp = ImageHdr.Id.un.revcomp;
4895
4896 /* Validate the file version */
4897 if ((rval = emlxs_validate_version(hba, &image->prog[type],
4898 ImageHdr.Id.Id, type, "DWC file"))) {
4899 return (rval);
4900 }
4901 }
4902
4903 /*
4904 * This checks if a DragonFly (pre-V2 ASIC) SLI2
4905 * image file is < version 3.8
4906 */
4907 if (FC_JEDEC_ID(vpd->biuRev) == DRAGONFLY_JEDEC_ID) {
4908 ver = (image->prog[SLI2_OVERLAY].version &
4909 0x0000ff00) >> 8;
4910
4911 if (ver >= 0x38) {
4912 EMLXS_MSGF(EMLXS_CONTEXT,
4913 &emlxs_image_incompat_msg,
4914 "ASIC Check: Image requires DragonFly "
4915 "V2 ASIC");
4916
4917 return (EMLXS_IMAGE_INCOMPATIBLE);
4918 }
4919 }
4920
4921 return (0);
4922
4923 } /* emlxs_validate_image() */
4924
4925
4926 static uint32_t
emlxs_update_exp_rom(emlxs_hba_t * hba,PWAKE_UP_PARMS WakeUpParms)4927 emlxs_update_exp_rom(emlxs_hba_t *hba, PWAKE_UP_PARMS WakeUpParms)
4928 {
4929 emlxs_port_t *port = &PPORT;
4930 MAILBOXQ *mbox;
4931 MAILBOX *mb;
4932 uint32_t next_address;
4933 uint32_t rval = 0;
4934
4935 if (WakeUpParms->u1.EROM_prog_wd[0] == 0) {
4936 return (1);
4937 }
4938
4939 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
4940 KM_NOSLEEP)) == NULL) {
4941 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
4942 "Unable to allocate mailbox buffer.");
4943
4944 return (1);
4945 }
4946
4947 bzero(mbox, sizeof (MAILBOXQ));
4948
4949 mb = (MAILBOX *)mbox;
4950 mb->mbxCommand = MBX_LOAD_EXP_ROM;
4951 mb->un.varLdExpRom.step = EROM_CMD_FIND_IMAGE;
4952 mb->un.varLdExpRom.progress = 0;
4953 mb->un.varLdExpRom.un.prog_id = WakeUpParms->u1.EROM_prog_id;
4954 mbox->mbox_cmpl = NULL;
4955
4956 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) {
4957 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
4958 "Unable to load exp ROM. Mailbox cmd=%x status=%x",
4959 mb->mbxCommand, mb->mbxStatus);
4960
4961 rval = 1;
4962
4963 goto SLI_DOWNLOAD_EXIT;
4964 }
4965
4966 if (mb->un.varLdExpRom.progress == EROM_RSP_COPY_DONE) {
4967 (void) emlxs_update_wakeup_parms(hba, WakeUpParms, WakeUpParms);
4968
4969 rval = 1;
4970 goto SLI_DOWNLOAD_EXIT;
4971 }
4972
4973 if (mb->un.varLdExpRom.progress != EROM_RSP_ERASE_STARTED) {
4974 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
4975 "Invalid exp ROM progress. progress=%x",
4976 mb->un.varLdExpRom.progress);
4977
4978 rval = 1;
4979
4980 goto SLI_DOWNLOAD_EXIT;
4981 }
4982
4983 /*
4984 * continue Erase
4985 */
4986 while (mb->un.varLdExpRom.progress != EROM_RSP_ERASE_COMPLETE) {
4987
4988 next_address = mb->un.varLdExpRom.dl_to_adr;
4989
4990 bzero((void *)mb, MAILBOX_CMD_BSIZE);
4991
4992 mb->mbxCommand = MBX_LOAD_EXP_ROM;
4993 mb->un.varLdExpRom.step = EROM_CMD_CONTINUE_ERASE;
4994 mb->un.varLdExpRom.dl_to_adr = next_address;
4995 mb->un.varLdExpRom.progress = 0;
4996 mb->un.varLdExpRom.un.prog_id = WakeUpParms->u1.EROM_prog_id;
4997 mbox->mbox_cmpl = NULL;
4998
4999 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) !=
5000 MBX_SUCCESS) {
5001 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
5002 "Unable to load exp ROM. Mailbox cmd=%x status=%x",
5003 mb->mbxCommand, mb->mbxStatus);
5004
5005 rval = 1;
5006 goto SLI_DOWNLOAD_EXIT;
5007 }
5008
5009 }
5010
5011 while (mb->un.varLdExpRom.progress != EROM_RSP_COPY_DONE) {
5012 next_address = mb->un.varLdExpRom.dl_to_adr;
5013
5014 bzero((void *)mb, MAILBOX_CMD_BSIZE);
5015
5016 mb->mbxCommand = MBX_LOAD_EXP_ROM;
5017 mb->un.varLdExpRom.step = EROM_CMD_COPY;
5018 mb->un.varLdExpRom.dl_to_adr = next_address;
5019 mb->un.varLdExpRom.progress = 0;
5020 mb->un.varLdExpRom.un.prog_id = WakeUpParms->u1.EROM_prog_id;
5021 mbox->mbox_cmpl = NULL;
5022
5023 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) !=
5024 MBX_SUCCESS) {
5025 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
5026 "Unable to load exp ROM. Mailbox cmd=%x status=%x",
5027 mb->mbxCommand, mb->mbxStatus);
5028
5029 rval = 1;
5030
5031 goto SLI_DOWNLOAD_EXIT;
5032 }
5033 }
5034
5035 rval = emlxs_update_wakeup_parms(hba, WakeUpParms, WakeUpParms);
5036
5037 SLI_DOWNLOAD_EXIT:
5038
5039 if (mbox) {
5040 kmem_free(mbox, sizeof (MAILBOXQ));
5041 }
5042
5043 return (rval);
5044
5045 } /* emlxs_update_exp_rom() */
5046
5047
5048 /*
5049 *
5050 * FUNCTION NAME: emlxs_start_abs_download_2mb
5051 *
5052 * DESCRIPTION: Perform absolute download for 2 MB flash. A incoming
5053 * buffer may consist of more than 1 file. This function
5054 * will parse the buffer to find all the files.
5055 *
5056 *
5057 * PARAMETERS:
5058 *
5059 *
5060 * RETURNS:
5061 *
5062 */
5063 /* ARGSUSED */
5064 static uint32_t
emlxs_start_abs_download_2mb(emlxs_hba_t * hba,caddr_t buffer,uint32_t len,uint32_t offline,emlxs_fw_image_t * fw_image)5065 emlxs_start_abs_download_2mb(emlxs_hba_t *hba, caddr_t buffer, uint32_t len,
5066 uint32_t offline, emlxs_fw_image_t *fw_image)
5067 {
5068 emlxs_port_t *port = &PPORT;
5069 uint32_t rval = 0;
5070
5071 /* If nothing to download then quit now */
5072 if (!fw_image->awc.version &&
5073 !fw_image->dwc.version &&
5074 !fw_image->bwc.version) {
5075 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
5076 "Nothing new to update. Exiting.");
5077 return (0);
5078 }
5079
5080 /*
5081 * Everything checks out, now to just do it
5082 */
5083 if (offline) {
5084 if (emlxs_offline(hba, 0) != FC_SUCCESS) {
5085 return (EMLXS_OFFLINE_FAILED);
5086 }
5087
5088 if (EMLXS_SLI_HBA_RESET(hba, 1, 1, 0) != FC_SUCCESS) {
5089 return (EMLXS_OFFLINE_FAILED);
5090 }
5091 }
5092
5093 if (fw_image->awc.version) {
5094 rval = emlxs_proc_abs_2mb(hba,
5095 (buffer + fw_image->awc.offset),
5096 FILE_TYPE_AWC, 0);
5097
5098 if (rval) {
5099 goto SLI_DOWNLOAD_2MB_EXIT;
5100 }
5101 }
5102
5103 if (fw_image->bwc.version) {
5104 rval = emlxs_proc_abs_2mb(hba,
5105 (buffer + fw_image->bwc.offset),
5106 FILE_TYPE_BWC,
5107 (fw_image->dwc.version)? ALLext:BWCext);
5108
5109 if (rval) {
5110 goto SLI_DOWNLOAD_2MB_EXIT;
5111 }
5112 }
5113
5114 if (fw_image->dwc.version) {
5115 rval = emlxs_proc_rel_2mb(hba, buffer, fw_image);
5116
5117 if (rval) {
5118 goto SLI_DOWNLOAD_2MB_EXIT;
5119 }
5120 }
5121
5122 SLI_DOWNLOAD_2MB_EXIT:
5123
5124 if (offline) {
5125 (void) emlxs_online(hba);
5126 }
5127
5128 return (rval);
5129
5130 } /* emlxs_start_abs_download_2mb() */
5131
5132
5133 /*
5134 *
5135 * FUNCTION NAME: emlxs_proc_abs_2mb
5136 *
5137 * DESCRIPTION: Given one of the 3 file types(awc/bwc/dwc), it will reset
5138 * the port and download the file with sliIssueMbCommand()
5139 *
5140 *
5141 * PARAMETERS:
5142 *
5143 *
5144 * RETURNS:
5145 *
5146 */
5147 static uint32_t
emlxs_proc_abs_2mb(emlxs_hba_t * hba,caddr_t EntireBuffer,uint32_t FileType,uint32_t extType)5148 emlxs_proc_abs_2mb(emlxs_hba_t *hba, caddr_t EntireBuffer,
5149 uint32_t FileType, uint32_t extType)
5150 {
5151 emlxs_port_t *port = &PPORT;
5152 PAIF_HDR AifHdr;
5153 caddr_t Buffer = NULL;
5154 caddr_t DataBuffer = NULL;
5155 uint32_t *Src;
5156 uint32_t *Dst;
5157 MAILBOXQ *mbox;
5158 MAILBOX *mb;
5159 uint32_t DlByteCount;
5160 uint32_t rval = 0;
5161 uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT;
5162 uint32_t DlToAddr;
5163 uint32_t DlCount;
5164 WAKE_UP_PARMS AbsWakeUpParms;
5165 uint32_t i;
5166 uint32_t NextAddr;
5167 uint32_t EraseByteCount;
5168 uint32_t AreaId;
5169 uint32_t RspProgress = 0;
5170 uint32_t ParamsChg;
5171
5172 AifHdr = (PAIF_HDR)EntireBuffer;
5173 DlByteCount = AifHdr->RoSize + AifHdr->RwSize;
5174 DlToAddr = AifHdr->ImageBase;
5175
5176 if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT,
5177 KM_NOSLEEP)) == NULL) {
5178 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
5179 "%x: Unable to allocate data buffer.", FileType);
5180
5181 return (EMLXS_IMAGE_FAILED);
5182 }
5183
5184 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
5185 KM_NOSLEEP)) == NULL) {
5186 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
5187 "%x: Unable to allocate mailbox buffer.", FileType);
5188
5189 kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT);
5190
5191 return (EMLXS_IMAGE_FAILED);
5192 }
5193
5194 mb = (MAILBOX *)mbox;
5195
5196 Buffer = EntireBuffer + sizeof (AIF_HDR);
5197
5198 switch (FileType) {
5199 case FILE_TYPE_AWC:
5200 ParamsChg = 0;
5201 break;
5202
5203 case FILE_TYPE_BWC:
5204 rval = emlxs_build_parms_2mb_bwc(hba,
5205 AifHdr, extType, &AbsWakeUpParms);
5206
5207 if (rval == FALSE) {
5208 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
5209 "BWC build parms failed.");
5210
5211 rval = EMLXS_IMAGE_FAILED;
5212
5213 goto EXIT_ABS_DOWNLOAD;
5214 }
5215 ParamsChg = 1;
5216 break;
5217
5218 default:
5219 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
5220 "Invalid file type: %x", FileType);
5221
5222 rval = EMLXS_IMAGE_BAD;
5223
5224 goto EXIT_ABS_DOWNLOAD;
5225 }
5226
5227 EraseByteCount = AifHdr->Area_Size;
5228 AreaId = AifHdr->Area_ID;
5229
5230 emlxs_format_load_area_cmd(mbox,
5231 DlToAddr,
5232 EraseByteCount,
5233 ERASE_FLASH,
5234 0, DL_FROM_SLIM_OFFSET, AreaId, MBX_LOAD_AREA, CMD_START_ERASE);
5235
5236 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) {
5237 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
5238 "%x: Could not erase 2MB Flash: Mailbox cmd=%x status=%x",
5239 FileType, mb->mbxCommand, mb->mbxStatus);
5240
5241 rval = EMLXS_IMAGE_FAILED;
5242
5243 goto EXIT_ABS_DOWNLOAD;
5244 }
5245
5246 while (mb->un.varLdArea.progress != RSP_ERASE_COMPLETE) {
5247 NextAddr = mb->un.varLdArea.dl_to_adr;
5248
5249 emlxs_format_load_area_cmd(mbox,
5250 NextAddr,
5251 EraseByteCount,
5252 ERASE_FLASH,
5253 0,
5254 DL_FROM_SLIM_OFFSET,
5255 AreaId, MBX_LOAD_AREA, CMD_CONTINUE_ERASE);
5256
5257 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) !=
5258 MBX_SUCCESS) {
5259 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
5260 "%x: Could not erase 2MB Flash2: Mailbox cmd=%x "
5261 "status=%x", FileType, mb->mbxCommand,
5262 mb->mbxStatus);
5263
5264 rval = EMLXS_IMAGE_FAILED;
5265
5266 goto EXIT_ABS_DOWNLOAD;
5267 }
5268 }
5269
5270 while (DlByteCount) {
5271 if (DlByteCount >= SegSize)
5272 DlCount = SegSize;
5273 else
5274 DlCount = DlByteCount;
5275
5276 DlByteCount -= DlCount;
5277
5278 Dst = (uint32_t *)DataBuffer;
5279 Src = (uint32_t *)Buffer;
5280
5281 for (i = 0; i < (DlCount / 4); i++) {
5282 *Dst = *Src;
5283 Dst++;
5284 Src++;
5285 }
5286
5287 WRITE_SLIM_COPY(hba, (uint32_t *)DataBuffer,
5288 (volatile uint32_t *)((volatile char *)
5289 hba->sli.sli3.slim_addr + sizeof (MAILBOX)),
5290 (DlCount / sizeof (uint32_t)));
5291
5292 if ((RspProgress == RSP_DOWNLOAD_MORE) || (RspProgress == 0)) {
5293 emlxs_format_load_area_cmd(mbox,
5294 DlToAddr,
5295 DlCount,
5296 PROGRAM_FLASH,
5297 (DlByteCount) ? 0 : 1,
5298 DL_FROM_SLIM_OFFSET,
5299 AreaId,
5300 MBX_LOAD_AREA,
5301 (DlByteCount) ? CMD_DOWNLOAD : CMD_END_DOWNLOAD);
5302
5303 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) !=
5304 MBX_SUCCESS) {
5305 EMLXS_MSGF(EMLXS_CONTEXT,
5306 &emlxs_download_failed_msg,
5307 "%x: Could not program 2MB Flash: Mailbox "
5308 "cmd=%x status=%x", FileType,
5309 mb->mbxCommand, mb->mbxStatus);
5310
5311 rval = EMLXS_IMAGE_FAILED;
5312
5313 goto EXIT_ABS_DOWNLOAD;
5314 }
5315 }
5316
5317 RspProgress = mb->un.varLdArea.progress;
5318
5319 Buffer += DlCount;
5320 DlToAddr += DlCount;
5321 }
5322
5323 #ifdef FMA_SUPPORT
5324 if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle)
5325 != DDI_FM_OK) {
5326 EMLXS_MSGF(EMLXS_CONTEXT,
5327 &emlxs_invalid_access_handle_msg, NULL);
5328
5329 rval = EMLXS_IMAGE_FAILED;
5330
5331 goto EXIT_ABS_DOWNLOAD;
5332 }
5333 #endif /* FMA_SUPPORT */
5334
5335 if (RspProgress != RSP_DOWNLOAD_DONE) {
5336 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
5337 "%x: Failed download response received. %x", FileType,
5338 RspProgress);
5339
5340 rval = EMLXS_IMAGE_FAILED;
5341
5342 goto EXIT_ABS_DOWNLOAD;
5343 }
5344
5345 if (ParamsChg) {
5346 if (emlxs_update_wakeup_parms(hba, &AbsWakeUpParms,
5347 &AbsWakeUpParms)) {
5348 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
5349 "%x: Unable to update parms.", FileType);
5350
5351 rval = EMLXS_IMAGE_FAILED;
5352 }
5353 }
5354
5355 EXIT_ABS_DOWNLOAD:
5356
5357 if (DataBuffer) {
5358 kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT);
5359 }
5360
5361 if (mbox) {
5362 kmem_free(mbox, sizeof (MAILBOXQ));
5363 }
5364
5365 return (rval);
5366
5367 } /* emlxs_proc_abs_2mb() */
5368
5369
5370 static void
emlxs_format_load_area_cmd(MAILBOXQ * mbq,uint32_t Base,uint32_t DlByteCount,uint32_t Function,uint32_t Complete,uint32_t DataOffset,uint32_t AreaId,uint8_t MbxCmd,uint32_t StepCmd)5371 emlxs_format_load_area_cmd(MAILBOXQ * mbq,
5372 uint32_t Base,
5373 uint32_t DlByteCount,
5374 uint32_t Function,
5375 uint32_t Complete,
5376 uint32_t DataOffset, uint32_t AreaId, uint8_t MbxCmd, uint32_t StepCmd)
5377 {
5378 MAILBOX *mb = (MAILBOX *)mbq;
5379
5380 bzero((void *)mb, MAILBOX_CMD_BSIZE);
5381
5382 mb->mbxCommand = MbxCmd;
5383 mb->mbxOwner = OWN_HOST;
5384 mb->un.varLdArea.update_flash = 1;
5385 mb->un.varLdArea.erase_or_prog = Function;
5386 mb->un.varLdArea.dl_to_adr = Base;
5387 mb->un.varLdArea.dl_len = DlByteCount;
5388 mb->un.varLdArea.load_cmplt = Complete;
5389 mb->un.varLdArea.method = DL_FROM_SLIM;
5390 mb->un.varLdArea.area_id = AreaId;
5391 mb->un.varLdArea.step = StepCmd;
5392 mb->un.varLdArea.un.dl_from_slim_offset = DataOffset;
5393 mbq->mbox_cmpl = NULL;
5394
5395 } /* emlxs_format_load_area_cmd() */
5396
5397
5398 /* ARGSUSED */
5399 static uint32_t
emlxs_build_parms_2mb_bwc(emlxs_hba_t * hba,PAIF_HDR AifHdr,uint32_t extType,PWAKE_UP_PARMS AbsWakeUpParms)5400 emlxs_build_parms_2mb_bwc(emlxs_hba_t *hba,
5401 PAIF_HDR AifHdr, uint32_t extType, PWAKE_UP_PARMS AbsWakeUpParms)
5402 {
5403 emlxs_port_t *port = &PPORT;
5404 uint32_t pId[2];
5405 uint32_t returnStat;
5406
5407 /* Read wakeup paramters */
5408 if (emlxs_read_wakeup_parms(hba, AbsWakeUpParms, 0) ==
5409 (uint32_t)CFG_DATA_NO_REGION) {
5410 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
5411 "Unable to get BWC parameters.");
5412 return (FALSE);
5413 }
5414
5415 pId[0] = AifHdr->AVersion;
5416 pId[1] = 0;
5417
5418 if (extType == BWCext) {
5419 AbsWakeUpParms->u0.boot_bios_wd[0] = pId[0];
5420 AbsWakeUpParms->u0.boot_bios_wd[1] = pId[1];
5421 AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0];
5422 AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1];
5423 }
5424
5425 else if (extType == ALLext) {
5426 if (!AbsWakeUpParms->u0.boot_bios_wd[0]) {
5427 /* case of EROM inactive */
5428 AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1];
5429 AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0];
5430 } else {
5431 /* case of EROM active */
5432 if (AbsWakeUpParms->u0.boot_bios_wd[0] == pId[0]) {
5433 /* same ID */
5434 AbsWakeUpParms->u0.boot_bios_wd[0] = pId[0];
5435 AbsWakeUpParms->u0.boot_bios_wd[1] = pId[1];
5436 AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0];
5437 AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1];
5438 } else {
5439 /* different ID */
5440 AbsWakeUpParms->u1.EROM_prog_wd[0] = pId[0];
5441 AbsWakeUpParms->u1.EROM_prog_wd[1] = pId[1];
5442
5443 returnStat =
5444 emlxs_update_exp_rom(hba, AbsWakeUpParms);
5445
5446 if (returnStat) {
5447 AbsWakeUpParms->u0.boot_bios_wd[0] =
5448 pId[0];
5449 AbsWakeUpParms->u0.boot_bios_wd[1] =
5450 pId[1];
5451 }
5452 }
5453 }
5454 }
5455
5456 return (TRUE);
5457
5458 } /* emlxs_build_parms_2mb_bwc() */
5459
5460
5461 extern uint32_t
emlxs_get_max_sram(emlxs_hba_t * hba,uint32_t * MaxRbusSize,uint32_t * MaxIbusSize)5462 emlxs_get_max_sram(emlxs_hba_t *hba, uint32_t *MaxRbusSize,
5463 uint32_t *MaxIbusSize)
5464 {
5465 emlxs_port_t *port = &PPORT;
5466 MAILBOXQ *mbox;
5467 MAILBOX *mb;
5468 uint32_t *Uptr;
5469 uint32_t rval = 0;
5470
5471 if (MaxRbusSize) {
5472 *MaxRbusSize = 0;
5473 }
5474
5475 if (MaxIbusSize) {
5476 *MaxIbusSize = 0;
5477 }
5478
5479 if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
5480 KM_NOSLEEP)) == NULL) {
5481 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
5482 "Unable to allocate mailbox buffer.");
5483
5484 return (1);
5485 }
5486
5487 mb = (MAILBOX *)mbox;
5488
5489 emlxs_format_dump(hba, mbox, DMP_MEM_REG, 0, 2, MAX_RBUS_SRAM_SIZE_ADR);
5490
5491 if ((rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0)) !=
5492 MBX_SUCCESS) {
5493 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
5494 "Unable to get SRAM size: Mailbox cmd=%x status=%x",
5495 mb->mbxCommand, mb->mbxStatus);
5496
5497 rval = 1;
5498
5499 goto Exit_Function;
5500 }
5501
5502 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
5503 EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle, 0,
5504 hba->sli.sli4.dump_region.size, DDI_DMA_SYNC_FORKERNEL);
5505 Uptr = (uint32_t *)hba->sli.sli4.dump_region.virt;
5506 } else {
5507 Uptr = (uint32_t *)&mb->un.varDmp.resp_offset;
5508 }
5509
5510 if (MaxRbusSize) {
5511 *MaxRbusSize = Uptr[0];
5512 }
5513
5514 if (MaxIbusSize) {
5515 *MaxIbusSize = Uptr[1];
5516 }
5517
5518 Exit_Function:
5519
5520 if (mbox) {
5521 kmem_free(mbox, sizeof (MAILBOXQ));
5522 }
5523
5524 #ifdef FMA_SUPPORT
5525 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
5526 if (emlxs_fm_check_dma_handle(hba,
5527 hba->sli.sli4.dump_region.dma_handle) != DDI_FM_OK) {
5528 EMLXS_MSGF(EMLXS_CONTEXT,
5529 &emlxs_invalid_dma_handle_msg,
5530 "get_max_sram: hdl=%p",
5531 hba->sli.sli4.dump_region.dma_handle);
5532 rval = 1;
5533 }
5534 }
5535 #endif /* FMA_SUPPORT */
5536
5537 return (rval);
5538
5539 } /* emlxs_get_max_sram() */
5540
5541
5542 static uint32_t
emlxs_kern_check(emlxs_hba_t * hba,uint32_t version)5543 emlxs_kern_check(emlxs_hba_t *hba, uint32_t version)
5544 {
5545 uint8_t *ptr;
5546 uint8_t ver;
5547
5548 ver = version & 0xff;
5549 ptr = hba->model_info.pt_FF;
5550
5551 while (*ptr) {
5552 if (*ptr++ == ver) {
5553 return (1);
5554 }
5555 }
5556
5557 return (0);
5558
5559 } /* emlxs_kern_check() */
5560
5561 static uint32_t
emlxs_stub_check(emlxs_hba_t * hba,uint32_t version)5562 emlxs_stub_check(emlxs_hba_t *hba, uint32_t version)
5563 {
5564 uint8_t *ptr;
5565 uint8_t ver;
5566
5567 ver = version & 0xff;
5568 ptr = hba->model_info.pt_2;
5569
5570 while (*ptr) {
5571 if (*ptr++ == ver) {
5572 return (1);
5573 }
5574 }
5575
5576 return (0);
5577
5578 } /* emlxs_stub_check() */
5579
5580 static uint32_t
emlxs_bios_check(emlxs_hba_t * hba,uint32_t version)5581 emlxs_bios_check(emlxs_hba_t *hba, uint32_t version)
5582 {
5583 uint8_t *ptr;
5584 uint8_t ver;
5585
5586 ver = version & 0xff;
5587 ptr = hba->model_info.pt_3;
5588
5589 while (*ptr) {
5590 if (*ptr++ == ver) {
5591 return (1);
5592 }
5593 }
5594
5595 return (0);
5596
5597 } /* emlxs_bios_check() */
5598
5599 static uint32_t
emlxs_sli1_check(emlxs_hba_t * hba,uint32_t version)5600 emlxs_sli1_check(emlxs_hba_t *hba, uint32_t version)
5601 {
5602 uint8_t *ptr;
5603 uint8_t ver;
5604
5605 ver = version & 0xff;
5606 ptr = hba->model_info.pt_6;
5607
5608 while (*ptr) {
5609 if (*ptr++ == ver) {
5610 return (1);
5611 }
5612 }
5613
5614 return (0);
5615
5616 } /* emlxs_sli1_check() */
5617
5618 static uint32_t
emlxs_sli2_check(emlxs_hba_t * hba,uint32_t version)5619 emlxs_sli2_check(emlxs_hba_t *hba, uint32_t version)
5620 {
5621 uint8_t *ptr;
5622 uint8_t ver;
5623
5624 ver = version & 0xff;
5625 ptr = hba->model_info.pt_7;
5626
5627 while (*ptr) {
5628 if (*ptr++ == ver) {
5629 return (1);
5630 }
5631 }
5632
5633 return (0);
5634
5635 } /* emlxs_sli2_check() */
5636
5637 static uint32_t
emlxs_sli3_check(emlxs_hba_t * hba,uint32_t version)5638 emlxs_sli3_check(emlxs_hba_t *hba, uint32_t version)
5639 {
5640 uint8_t *ptr;
5641 uint8_t ver;
5642
5643 ver = version & 0xff;
5644 ptr = hba->model_info.pt_B;
5645
5646 while (*ptr) {
5647 if (*ptr++ == ver) {
5648 return (1);
5649 }
5650 }
5651
5652 return (0);
5653
5654 } /* emlxs_sli3_check() */
5655
5656
5657 static uint32_t
emlxs_sli4_check(emlxs_hba_t * hba,uint32_t version)5658 emlxs_sli4_check(emlxs_hba_t *hba, uint32_t version)
5659 {
5660 uint8_t *ptr;
5661 uint8_t ver;
5662
5663 ver = version & 0xff;
5664 ptr = hba->model_info.pt_E;
5665
5666 while (*ptr) {
5667 if (*ptr++ == ver) {
5668 return (1);
5669 }
5670 }
5671
5672 return (0);
5673
5674 } /* emlxs_sli4_check() */
5675
5676
5677 static uint32_t
emlxs_sbus_fcode_check(emlxs_hba_t * hba,uint32_t version)5678 emlxs_sbus_fcode_check(emlxs_hba_t *hba, uint32_t version)
5679 {
5680 uint8_t *ptr;
5681 uint8_t ver;
5682
5683 ver = version & 0xff;
5684 ptr = hba->model_info.pt_A;
5685
5686 while (*ptr) {
5687 if (*ptr++ == ver) {
5688 return (1);
5689 }
5690 }
5691
5692 return (0);
5693
5694 } /* emlxs_sbus_fcode_check() */
5695
5696
5697 static uint32_t
emlxs_type_check(uint32_t type)5698 emlxs_type_check(uint32_t type)
5699 {
5700 if (type == 0xff) {
5701 return (KERNEL_CODE);
5702 }
5703
5704 if (type >= MAX_PROG_TYPES) {
5705 return (RESERVED_D);
5706 }
5707
5708 return (type);
5709
5710 } /* emlxs_type_check() */
5711
5712
5713 extern int32_t
emlxs_boot_code_disable(emlxs_hba_t * hba)5714 emlxs_boot_code_disable(emlxs_hba_t *hba)
5715 {
5716 emlxs_port_t *port = &PPORT;
5717 PROG_ID Id;
5718 emlxs_vpd_t *vpd;
5719 uint8_t boot_state = 0;
5720
5721 vpd = &VPD;
5722
5723 if (hba->model_info.chip & EMLXS_BE_CHIPS) {
5724 return (EMLXS_OP_NOT_SUP);
5725 }
5726
5727 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
5728 /* Read Boot Config */
5729 if (emlxs_get_boot_config(hba, &boot_state)) {
5730 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
5731 "boot_code_enable: Unable to get boot config.");
5732
5733 return (FC_FAILURE);
5734 }
5735
5736 /* Check if boot code is already disabled */
5737 if (! boot_state) {
5738 return (FC_SUCCESS);
5739 }
5740
5741 /* Disable boot code */
5742 boot_state = 0;
5743 if (emlxs_set_boot_config(hba, boot_state)) {
5744 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
5745 "boot_code_enable: Unable to set boot config.");
5746
5747 return (FC_FAILURE);
5748 }
5749
5750 /* Now read the boot config again to verify */
5751 if (emlxs_get_boot_config(hba, &boot_state)) {
5752 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
5753 "boot_code_enable: Unable to get boot config.");
5754
5755 return (FC_FAILURE);
5756 }
5757
5758 /* return the result */
5759 return ((boot_state == 0) ? FC_SUCCESS : FC_FAILURE);
5760 } else {
5761 if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 0)) {
5762 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
5763 "boot_code_disable: Unable to read wake up parms.");
5764
5765 return (FC_FAILURE);
5766 }
5767
5768 /* Check if boot code is already disabled */
5769 if (hba->wakeup_parms.u0.boot_bios_wd[0] == 0) {
5770 return (FC_SUCCESS);
5771 }
5772
5773 /* Make sure EROM entry has copy of boot bios entry */
5774 if (!(hba->model_info.chip &
5775 (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP)) &&
5776 (hba->wakeup_parms.u0.boot_bios_wd[0] !=
5777 hba->wakeup_parms.u1.EROM_prog_wd[0]) &&
5778 (hba->wakeup_parms.u0.boot_bios_wd[1] !=
5779 hba->wakeup_parms.u1.EROM_prog_wd[1])) {
5780 (void) emlxs_update_boot_wakeup_parms(hba,
5781 &hba->wakeup_parms,
5782 &hba->wakeup_parms.u0.boot_bios_id, 1);
5783 }
5784
5785 /* Update the bios id with a zero id */
5786 /* Don't load the EROM this time */
5787 bzero(&Id, sizeof (PROG_ID));
5788 (void) emlxs_update_boot_wakeup_parms(hba,
5789 &hba->wakeup_parms, &Id, 0);
5790
5791 /* Now read the parms again to verify */
5792 (void) emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1);
5793 emlxs_decode_version(hba->wakeup_parms.u0.boot_bios_wd[0],
5794 vpd->boot_version, sizeof (vpd->boot_version));
5795 /* (void) strcpy(vpd->fcode_version, vpd->boot_version); */
5796
5797 /* Return the result */
5798 return ((hba->wakeup_parms.u0.boot_bios_wd[0] == 0) ?
5799 FC_SUCCESS : FC_FAILURE);
5800 }
5801
5802 } /* emlxs_boot_code_disable() */
5803
5804
5805 extern int32_t
emlxs_boot_code_enable(emlxs_hba_t * hba)5806 emlxs_boot_code_enable(emlxs_hba_t *hba)
5807 {
5808 emlxs_port_t *port = &PPORT;
5809 emlxs_vpd_t *vpd;
5810 PROG_ID load_list[MAX_LOAD_ENTRY];
5811 uint32_t i;
5812 uint32_t count;
5813 uint8_t boot_state = 0;
5814
5815 vpd = &VPD;
5816
5817 if (hba->model_info.chip & EMLXS_BE_CHIPS) {
5818 return (FC_SUCCESS);
5819 }
5820
5821 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
5822 /* Read Boot Config */
5823 if (emlxs_get_boot_config(hba, &boot_state)) {
5824 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
5825 "boot_code_enable: Unable to get boot config.");
5826
5827 return (FC_FAILURE);
5828 }
5829
5830 /* Check if boot code is already enabled */
5831 if (boot_state) {
5832 return (FC_SUCCESS);
5833 }
5834
5835 /* Enable boot code */
5836 boot_state = 1;
5837 if (emlxs_set_boot_config(hba, boot_state)) {
5838 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
5839 "boot_code_enable: Unable to set boot config.");
5840
5841 return (FC_FAILURE);
5842 }
5843
5844 /* Now read the boot config again to verify */
5845 if (emlxs_get_boot_config(hba, &boot_state)) {
5846 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
5847 "boot_code_enable: Unable to get boot config.");
5848
5849 return (FC_FAILURE);
5850 }
5851
5852 /* return the result */
5853 return ((boot_state != 0) ? FC_SUCCESS : FC_FAILURE);
5854 } else {
5855 /* Read the wakeup parms */
5856 if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 0)) {
5857 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
5858 "boot_code_enable: Unable to read wake up parms.");
5859
5860 return (FC_FAILURE);
5861 }
5862
5863 /* Check if boot code is already enabled */
5864 if (hba->wakeup_parms.u0.boot_bios_id.Type == BOOT_BIOS) {
5865 return (FC_SUCCESS);
5866 }
5867
5868 if (!(hba->model_info.chip &
5869 (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) {
5870 if (hba->wakeup_parms.u1.EROM_prog_id.Type
5871 != BOOT_BIOS) {
5872 return (EMLXS_NO_BOOT_CODE);
5873 }
5874
5875 /* Update the parms with the boot image id */
5876 /* Don't load the EROM this time */
5877 (void) emlxs_update_boot_wakeup_parms(hba,
5878 &hba->wakeup_parms,
5879 &hba->wakeup_parms.u1.EROM_prog_id, 0);
5880 } else { /* (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP) */
5881
5882 count = emlxs_get_load_list(hba, load_list);
5883
5884 if (!count) {
5885 return (FC_FAILURE);
5886 }
5887
5888 /* Scan load list for a boot image */
5889 for (i = 0; i < count; i++) {
5890 if (load_list[i].Type == BOOT_BIOS) {
5891 /*
5892 * Update the parms with boot image id
5893 * Don't load the EROM this time
5894 */
5895 (void) emlxs_update_boot_wakeup_parms(
5896 hba, &hba->wakeup_parms,
5897 &load_list[i], 0);
5898
5899 break;
5900 }
5901 }
5902
5903 if (i == count) {
5904 return (EMLXS_NO_BOOT_CODE);
5905 }
5906 }
5907
5908 /* Now read the parms again to verify */
5909 (void) emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1);
5910 emlxs_decode_version(hba->wakeup_parms.u0.boot_bios_wd[0],
5911 vpd->boot_version, sizeof (vpd->boot_version));
5912 /* (void) strcpy(vpd->fcode_version, vpd->boot_version); */
5913
5914 /* return the result */
5915 return ((hba->wakeup_parms.u0.boot_bios_wd[0] != 0) ?
5916 FC_SUCCESS : FC_FAILURE);
5917 }
5918
5919 } /* emlxs_boot_code_enable() */
5920
5921
5922
5923 extern int32_t
emlxs_boot_code_state(emlxs_hba_t * hba)5924 emlxs_boot_code_state(emlxs_hba_t *hba)
5925 {
5926 emlxs_port_t *port = &PPORT;
5927 uint8_t boot_state = 0;
5928
5929 if (hba->model_info.chip & EMLXS_BE_CHIPS) {
5930 return (FC_SUCCESS);
5931 }
5932
5933 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
5934 /* Read Boot Config */
5935 if (emlxs_get_boot_config(hba, &boot_state)) {
5936 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
5937 "boot_code_state: Unable to read boot config.");
5938
5939 return (FC_FAILURE);
5940 }
5941
5942 return ((boot_state != 0) ? FC_SUCCESS : FC_FAILURE);
5943 } else {
5944 /* Read the wakeup parms */
5945 if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1)) {
5946 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
5947 "boot_code_state: Unable to read wake up parms.");
5948
5949 return (FC_FAILURE);
5950 }
5951
5952 /* return the result */
5953 return ((hba->wakeup_parms.u0.boot_bios_wd[0] != 0) ?
5954 FC_SUCCESS : FC_FAILURE);
5955 }
5956
5957 } /* emlxs_boot_code_state() */
5958