19517SBill.Taylor@Sun.COM /*
29517SBill.Taylor@Sun.COM * CDDL HEADER START
39517SBill.Taylor@Sun.COM *
49517SBill.Taylor@Sun.COM * The contents of this file are subject to the terms of the
59517SBill.Taylor@Sun.COM * Common Development and Distribution License (the "License").
69517SBill.Taylor@Sun.COM * You may not use this file except in compliance with the License.
79517SBill.Taylor@Sun.COM *
89517SBill.Taylor@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99517SBill.Taylor@Sun.COM * or http://www.opensolaris.org/os/licensing.
109517SBill.Taylor@Sun.COM * See the License for the specific language governing permissions
119517SBill.Taylor@Sun.COM * and limitations under the License.
129517SBill.Taylor@Sun.COM *
139517SBill.Taylor@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
149517SBill.Taylor@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159517SBill.Taylor@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
169517SBill.Taylor@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
179517SBill.Taylor@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
189517SBill.Taylor@Sun.COM *
199517SBill.Taylor@Sun.COM * CDDL HEADER END
209517SBill.Taylor@Sun.COM */
219517SBill.Taylor@Sun.COM
229517SBill.Taylor@Sun.COM /*
23*12472SShantkumar.Hiremath@Sun.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
249517SBill.Taylor@Sun.COM */
259517SBill.Taylor@Sun.COM
269517SBill.Taylor@Sun.COM /*
279517SBill.Taylor@Sun.COM * The reference for the functions in this file is the
289517SBill.Taylor@Sun.COM *
299517SBill.Taylor@Sun.COM * Mellanox HCA Flash Programming Application Note
309517SBill.Taylor@Sun.COM * (Mellanox document number 2205AN) rev 1.45, 2007.
319517SBill.Taylor@Sun.COM * Chapter 4 in particular.
329517SBill.Taylor@Sun.COM */
339517SBill.Taylor@Sun.COM
349517SBill.Taylor@Sun.COM #include <stdio.h>
359517SBill.Taylor@Sun.COM #include <stdlib.h>
369517SBill.Taylor@Sun.COM #include <unistd.h>
379517SBill.Taylor@Sun.COM #include <sys/types.h>
389517SBill.Taylor@Sun.COM #include <sys/stat.h>
399517SBill.Taylor@Sun.COM #include <sys/sysmacros.h>
409517SBill.Taylor@Sun.COM #include <sys/queue.h>
419517SBill.Taylor@Sun.COM #include <fcntl.h>
429517SBill.Taylor@Sun.COM #include <ctype.h>
439517SBill.Taylor@Sun.COM #include <string.h>
449517SBill.Taylor@Sun.COM #include <strings.h>
459517SBill.Taylor@Sun.COM
469517SBill.Taylor@Sun.COM #include <sys/byteorder.h>
479517SBill.Taylor@Sun.COM
489517SBill.Taylor@Sun.COM #include <libintl.h> /* for gettext(3c) */
499517SBill.Taylor@Sun.COM
509517SBill.Taylor@Sun.COM #include <fwflash/fwflash.h>
519517SBill.Taylor@Sun.COM #include "../../hdrs/hermon_ib.h"
529517SBill.Taylor@Sun.COM
539517SBill.Taylor@Sun.COM char *devprefix = "/devices";
549517SBill.Taylor@Sun.COM char drivername[] = "hermon\0";
559517SBill.Taylor@Sun.COM char *devsuffix = ":devctl";
569517SBill.Taylor@Sun.COM
579517SBill.Taylor@Sun.COM extern di_node_t rootnode;
589517SBill.Taylor@Sun.COM extern int errno;
599517SBill.Taylor@Sun.COM extern struct fw_plugin *self;
609517SBill.Taylor@Sun.COM extern struct vrfyplugin *verifier;
619517SBill.Taylor@Sun.COM extern int fwflash_debug;
629517SBill.Taylor@Sun.COM
639517SBill.Taylor@Sun.COM /* required functions for this plugin */
649517SBill.Taylor@Sun.COM int fw_readfw(struct devicelist *device, char *filename);
659517SBill.Taylor@Sun.COM int fw_writefw(struct devicelist *device);
669517SBill.Taylor@Sun.COM int fw_identify(int start);
679517SBill.Taylor@Sun.COM int fw_devinfo();
689517SBill.Taylor@Sun.COM
699517SBill.Taylor@Sun.COM
709517SBill.Taylor@Sun.COM /* helper functions */
719517SBill.Taylor@Sun.COM static int cnx_identify(struct devicelist *thisdev);
729517SBill.Taylor@Sun.COM static int cnx_get_guids(ib_cnx_encap_ident_t *handle);
739517SBill.Taylor@Sun.COM static int cnx_close(struct devicelist *flashdev);
749517SBill.Taylor@Sun.COM static int cnx_check_for_magic_pattern(ib_cnx_encap_ident_t *hdl, uint32_t adr);
759517SBill.Taylor@Sun.COM static uint32_t cnx_get_log2_chunk_size_f_hdl(ib_cnx_encap_ident_t *handle,
769517SBill.Taylor@Sun.COM int type);
779517SBill.Taylor@Sun.COM static uint32_t cnx_get_log2_chunk_size(uint32_t chunk_size_word);
789517SBill.Taylor@Sun.COM static uint32_t cnx_cont2phys(uint32_t log2_chunk_sz, uint32_t cont_addr,
799517SBill.Taylor@Sun.COM int type);
809517SBill.Taylor@Sun.COM static uint32_t cnx_get_image_size_f_hdl(ib_cnx_encap_ident_t *hdl, int type);
819517SBill.Taylor@Sun.COM static void cnx_local_set_guid_crc_img(uint32_t offset, uint32_t guid_crc_size,
829517SBill.Taylor@Sun.COM uint32_t guid_crc_offset);
839517SBill.Taylor@Sun.COM static int cnx_read_image(ib_cnx_encap_ident_t *handle);
849517SBill.Taylor@Sun.COM static int cnx_write_file(ib_cnx_encap_ident_t *handle, const char *filename);
859517SBill.Taylor@Sun.COM static int cnx_verify_image(ib_cnx_encap_ident_t *handle, int type);
869517SBill.Taylor@Sun.COM static int cnx_read_guids(ib_cnx_encap_ident_t *handle, int type);
879517SBill.Taylor@Sun.COM static int cnx_set_guids(ib_cnx_encap_ident_t *handle, void *arg);
889517SBill.Taylor@Sun.COM static int cnx_write_image(ib_cnx_encap_ident_t *handle, int type);
899517SBill.Taylor@Sun.COM static int cnx_read_ioctl(ib_cnx_encap_ident_t *hdl,
909517SBill.Taylor@Sun.COM hermon_flash_ioctl_t *info);
919517SBill.Taylor@Sun.COM static int cnx_write_ioctl(ib_cnx_encap_ident_t *hdl,
929517SBill.Taylor@Sun.COM hermon_flash_ioctl_t *info);
939517SBill.Taylor@Sun.COM static int cnx_erase_sector_ioctl(ib_cnx_encap_ident_t *hdl,
949517SBill.Taylor@Sun.COM hermon_flash_ioctl_t *info);
959517SBill.Taylor@Sun.COM static int cnx_find_magic_n_chnk_sz(ib_cnx_encap_ident_t *handle, int type);
969517SBill.Taylor@Sun.COM static int cnx_get_image_info(ib_cnx_encap_ident_t *handle);
979517SBill.Taylor@Sun.COM
989517SBill.Taylor@Sun.COM
999517SBill.Taylor@Sun.COM int
fw_readfw(struct devicelist * flashdev,char * filename)1009517SBill.Taylor@Sun.COM fw_readfw(struct devicelist *flashdev, char *filename)
1019517SBill.Taylor@Sun.COM {
1029517SBill.Taylor@Sun.COM ib_cnx_encap_ident_t *manuf;
1039517SBill.Taylor@Sun.COM int rv = FWFLASH_SUCCESS;
1049517SBill.Taylor@Sun.COM
1059517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: fw_readfw: filename %s\n", filename);
1069517SBill.Taylor@Sun.COM
1079517SBill.Taylor@Sun.COM manuf = (ib_cnx_encap_ident_t *)flashdev->ident->encap_ident;
1089517SBill.Taylor@Sun.COM if (CNX_I_CHECK_HANDLE(manuf)) {
1099517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Invalid Handle for "
1109517SBill.Taylor@Sun.COM "device %s! \n"), flashdev->access_devname);
1119517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
1129517SBill.Taylor@Sun.COM }
1139517SBill.Taylor@Sun.COM
1149517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: fw_identify should have read the image. "
1159517SBill.Taylor@Sun.COM "state 0x%x\n", manuf->state);
1169517SBill.Taylor@Sun.COM
1179517SBill.Taylor@Sun.COM rv = cnx_read_image(manuf);
1189517SBill.Taylor@Sun.COM if (rv != FWFLASH_SUCCESS) {
1199517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Failed to read any valid "
1209517SBill.Taylor@Sun.COM "image on device (%s)\n"), flashdev->access_devname);
1219517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("Aborting read.\n"));
1229517SBill.Taylor@Sun.COM } else {
1239517SBill.Taylor@Sun.COM rv = cnx_write_file(manuf, filename);
1249517SBill.Taylor@Sun.COM }
1259517SBill.Taylor@Sun.COM
1269517SBill.Taylor@Sun.COM cnx_close(flashdev);
1279517SBill.Taylor@Sun.COM return (rv);
1289517SBill.Taylor@Sun.COM }
1299517SBill.Taylor@Sun.COM
1309517SBill.Taylor@Sun.COM
1319517SBill.Taylor@Sun.COM /*
1329517SBill.Taylor@Sun.COM * If we're invoking fw_writefw, then flashdev is a valid,
1339517SBill.Taylor@Sun.COM * flashable device as determined by fw_identify().
1349517SBill.Taylor@Sun.COM *
1359517SBill.Taylor@Sun.COM * If verifier is null, then we haven't been called following a firmware
1369517SBill.Taylor@Sun.COM * image verification load operation.
1379517SBill.Taylor@Sun.COM */
1389517SBill.Taylor@Sun.COM int
fw_writefw(struct devicelist * flashdev)1399517SBill.Taylor@Sun.COM fw_writefw(struct devicelist *flashdev)
1409517SBill.Taylor@Sun.COM {
1419517SBill.Taylor@Sun.COM ib_cnx_encap_ident_t *manuf;
1429517SBill.Taylor@Sun.COM int i, j, k;
1439517SBill.Taylor@Sun.COM
1449517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: fw_writefw\n");
1459517SBill.Taylor@Sun.COM
1469517SBill.Taylor@Sun.COM manuf = (ib_cnx_encap_ident_t *)flashdev->ident->encap_ident;
1479517SBill.Taylor@Sun.COM
1489517SBill.Taylor@Sun.COM if (CNX_I_CHECK_HANDLE(manuf)) {
1499517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Invalid Handle for "
1509517SBill.Taylor@Sun.COM "device %s! \n"), flashdev->access_devname);
1519517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
1529517SBill.Taylor@Sun.COM }
1539517SBill.Taylor@Sun.COM
1549517SBill.Taylor@Sun.COM /*
1559517SBill.Taylor@Sun.COM * Try the primary first, then the secondary.
1569517SBill.Taylor@Sun.COM * If we get here, then the verifier has _already_ checked that
1579517SBill.Taylor@Sun.COM * the part number in the firmware image matches that in the HCA,
1589517SBill.Taylor@Sun.COM * so we only need this check if there's no hardware info available
1599517SBill.Taylor@Sun.COM * already after running through fw_identify().
1609517SBill.Taylor@Sun.COM */
1619517SBill.Taylor@Sun.COM if (manuf->pn_len == 0) {
1629517SBill.Taylor@Sun.COM int resp;
1639517SBill.Taylor@Sun.COM
1649517SBill.Taylor@Sun.COM (void) fprintf(stderr, gettext("Unable to completely verify "
1659517SBill.Taylor@Sun.COM "that this firmware image (%s) is compatible with your "
1669517SBill.Taylor@Sun.COM "HCA %s"), verifier->imgfile, flashdev->access_devname);
1679517SBill.Taylor@Sun.COM (void) fprintf(stderr, gettext("Do you really want to "
1689517SBill.Taylor@Sun.COM "continue? (Y/N): "));
1699517SBill.Taylor@Sun.COM (void) fflush(stdin);
1709517SBill.Taylor@Sun.COM resp = getchar();
1719517SBill.Taylor@Sun.COM if (resp != 'Y' && resp != 'y') {
1729517SBill.Taylor@Sun.COM (void) fprintf(stderr, gettext("Not proceeding with "
1739517SBill.Taylor@Sun.COM "flash operation of %s on %s"),
1749517SBill.Taylor@Sun.COM verifier->imgfile, flashdev->access_devname);
1759517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
1769517SBill.Taylor@Sun.COM }
1779517SBill.Taylor@Sun.COM }
1789517SBill.Taylor@Sun.COM
1799517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: fw_writefw: Using Existing GUIDs.\n");
1809517SBill.Taylor@Sun.COM manuf->state |=
1819517SBill.Taylor@Sun.COM FWFLASH_IB_STATE_GUIDN |
1829517SBill.Taylor@Sun.COM FWFLASH_IB_STATE_GUID1 |
1839517SBill.Taylor@Sun.COM FWFLASH_IB_STATE_GUID2 |
1849517SBill.Taylor@Sun.COM FWFLASH_IB_STATE_GUIDS;
1859517SBill.Taylor@Sun.COM if (cnx_set_guids(manuf, manuf->ibguids) != FWFLASH_SUCCESS) {
1869517SBill.Taylor@Sun.COM logmsg(MSG_WARN, gettext("hermon: Failed to set GUIDs"));
1879517SBill.Taylor@Sun.COM }
1889517SBill.Taylor@Sun.COM
1899517SBill.Taylor@Sun.COM /*
1909517SBill.Taylor@Sun.COM * Update both Primary and Secondary images
1919517SBill.Taylor@Sun.COM *
1929517SBill.Taylor@Sun.COM * For Failsafe firmware image update, if the current image (i.e.
1939517SBill.Taylor@Sun.COM * containing a magic pattern) on the Flash is stored on the Primary
1949517SBill.Taylor@Sun.COM * location, burn the new image to the Secondary location first,
1959517SBill.Taylor@Sun.COM * or vice versa.
1969517SBill.Taylor@Sun.COM */
1979517SBill.Taylor@Sun.COM
1989517SBill.Taylor@Sun.COM /* Note Current Image location. */
1999517SBill.Taylor@Sun.COM j = manuf->state &
2009517SBill.Taylor@Sun.COM (FWFLASH_IB_STATE_IMAGE_PRI | FWFLASH_IB_STATE_IMAGE_SEC);
2019517SBill.Taylor@Sun.COM
2029517SBill.Taylor@Sun.COM /*
2039517SBill.Taylor@Sun.COM * If we find that current image location is not found, no worries
2049517SBill.Taylor@Sun.COM * we shall default to PRIMARY, and proceed with burning anyway.
2059517SBill.Taylor@Sun.COM */
2069517SBill.Taylor@Sun.COM if (j == 0)
2079517SBill.Taylor@Sun.COM j = FWFLASH_IB_STATE_IMAGE_PRI;
2089517SBill.Taylor@Sun.COM
2099517SBill.Taylor@Sun.COM for (i = FWFLASH_FLASH_IMAGES; i > 0; i--) {
2109517SBill.Taylor@Sun.COM char *type;
2119517SBill.Taylor@Sun.COM
2129517SBill.Taylor@Sun.COM if (i == 2) {
2139517SBill.Taylor@Sun.COM if (j == 2)
2149517SBill.Taylor@Sun.COM k = 1; /* Burn PRI First */
2159517SBill.Taylor@Sun.COM else
2169517SBill.Taylor@Sun.COM k = 2; /* Burn SEC First */
2179517SBill.Taylor@Sun.COM } else {
2189517SBill.Taylor@Sun.COM if (k == 2)
2199517SBill.Taylor@Sun.COM k = 1; /* Burn PRI next */
2209517SBill.Taylor@Sun.COM else
2219517SBill.Taylor@Sun.COM k = 2; /* Burn SEC next */
2229517SBill.Taylor@Sun.COM }
2239517SBill.Taylor@Sun.COM type = ((k == 1) ? "Primary" : "Secondary");
2249517SBill.Taylor@Sun.COM
2259517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: fw_write: UPDATING %s image\n", type);
2269517SBill.Taylor@Sun.COM
2279517SBill.Taylor@Sun.COM if (cnx_write_image(manuf, k) != FWFLASH_SUCCESS) {
2289517SBill.Taylor@Sun.COM (void) fprintf(stderr,
2299517SBill.Taylor@Sun.COM gettext("Failed to update %s image on device %s"),
2309517SBill.Taylor@Sun.COM type, flashdev->access_devname);
2319517SBill.Taylor@Sun.COM goto out;
2329517SBill.Taylor@Sun.COM }
2339517SBill.Taylor@Sun.COM
2349517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: fw_write: Verify %s image..\n", type);
2359517SBill.Taylor@Sun.COM if (cnx_verify_image(manuf, k) != FWFLASH_SUCCESS) {
2369517SBill.Taylor@Sun.COM (void) fprintf(stderr,
2379517SBill.Taylor@Sun.COM gettext("Failed to verify %s image for device %s"),
2389517SBill.Taylor@Sun.COM type, flashdev->access_devname);
2399517SBill.Taylor@Sun.COM goto out;
2409517SBill.Taylor@Sun.COM }
2419517SBill.Taylor@Sun.COM }
2429517SBill.Taylor@Sun.COM out:
2439517SBill.Taylor@Sun.COM /* final update marker to the user */
2449517SBill.Taylor@Sun.COM (void) printf(" +\n");
2459517SBill.Taylor@Sun.COM return (cnx_close(flashdev));
2469517SBill.Taylor@Sun.COM }
2479517SBill.Taylor@Sun.COM
2489517SBill.Taylor@Sun.COM
2499517SBill.Taylor@Sun.COM /*
2509517SBill.Taylor@Sun.COM * The fw_identify() function walks the device tree trying to find
2519517SBill.Taylor@Sun.COM * devices which this plugin can work with.
2529517SBill.Taylor@Sun.COM *
2539517SBill.Taylor@Sun.COM * The parameter "start" gives us the starting index number
2549517SBill.Taylor@Sun.COM * to give the device when we add it to the fw_devices list.
2559517SBill.Taylor@Sun.COM *
2569517SBill.Taylor@Sun.COM * firstdev is allocated by us and we add space as necessary
2579517SBill.Taylor@Sun.COM */
2589517SBill.Taylor@Sun.COM int
fw_identify(int start)2599517SBill.Taylor@Sun.COM fw_identify(int start)
2609517SBill.Taylor@Sun.COM {
2619517SBill.Taylor@Sun.COM int rv = FWFLASH_FAILURE;
2629517SBill.Taylor@Sun.COM di_node_t thisnode;
2639517SBill.Taylor@Sun.COM struct devicelist *newdev;
2649517SBill.Taylor@Sun.COM char *devpath;
2659517SBill.Taylor@Sun.COM int idx = start;
2669517SBill.Taylor@Sun.COM int devlength = 0;
2679517SBill.Taylor@Sun.COM
2689517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: fw_identify\n");
2699517SBill.Taylor@Sun.COM thisnode = di_drv_first_node(drivername, rootnode);
2709517SBill.Taylor@Sun.COM
2719517SBill.Taylor@Sun.COM if (thisnode == DI_NODE_NIL) {
2729517SBill.Taylor@Sun.COM logmsg(MSG_INFO, gettext("No %s nodes in this system\n"),
2739517SBill.Taylor@Sun.COM drivername);
2749517SBill.Taylor@Sun.COM return (rv);
2759517SBill.Taylor@Sun.COM }
2769517SBill.Taylor@Sun.COM
2779517SBill.Taylor@Sun.COM /* we've found one, at least */
2789517SBill.Taylor@Sun.COM for (; thisnode != DI_NODE_NIL; thisnode = di_drv_next_node(thisnode)) {
2799517SBill.Taylor@Sun.COM
2809517SBill.Taylor@Sun.COM devpath = di_devfs_path(thisnode);
2819517SBill.Taylor@Sun.COM
2829517SBill.Taylor@Sun.COM if ((newdev = calloc(1, sizeof (struct devicelist))) == NULL) {
2839517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Unable to allocate "
2849517SBill.Taylor@Sun.COM "space for device entry\n"));
2859517SBill.Taylor@Sun.COM di_devfs_path_free(devpath);
2869517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
2879517SBill.Taylor@Sun.COM }
2889517SBill.Taylor@Sun.COM
2899517SBill.Taylor@Sun.COM /* calloc enough for /devices + devpath + ":devctl" + '\0' */
2909517SBill.Taylor@Sun.COM devlength = strlen(devpath) + strlen(devprefix) +
2919517SBill.Taylor@Sun.COM strlen(devsuffix) + 2;
2929517SBill.Taylor@Sun.COM
2939517SBill.Taylor@Sun.COM if ((newdev->access_devname = calloc(1, devlength)) == NULL) {
2949517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Unable to allocate "
2959517SBill.Taylor@Sun.COM "space for a devfs name\n"));
2969517SBill.Taylor@Sun.COM (void) free(newdev);
2979517SBill.Taylor@Sun.COM di_devfs_path_free(devpath);
2989517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
2999517SBill.Taylor@Sun.COM }
3009517SBill.Taylor@Sun.COM snprintf(newdev->access_devname, devlength,
3019517SBill.Taylor@Sun.COM "%s%s%s", devprefix, devpath, devsuffix);
3029517SBill.Taylor@Sun.COM
3039517SBill.Taylor@Sun.COM if ((newdev->ident = calloc(1, sizeof (struct vpr))) == NULL) {
3049517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Unable to allocate "
3059517SBill.Taylor@Sun.COM "space for a device identification record\n"));
3069517SBill.Taylor@Sun.COM (void) free(newdev->access_devname);
3079517SBill.Taylor@Sun.COM (void) free(newdev);
3089517SBill.Taylor@Sun.COM di_devfs_path_free(devpath);
3099517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
3109517SBill.Taylor@Sun.COM }
3119517SBill.Taylor@Sun.COM
3129517SBill.Taylor@Sun.COM /* CHECK VARIOUS IB THINGS HERE */
3139517SBill.Taylor@Sun.COM rv = cnx_identify(newdev);
3149517SBill.Taylor@Sun.COM if (rv == FWFLASH_FAILURE) {
3159517SBill.Taylor@Sun.COM (void) free(newdev->ident);
3169517SBill.Taylor@Sun.COM (void) free(newdev->access_devname);
3179517SBill.Taylor@Sun.COM (void) free(newdev);
3189517SBill.Taylor@Sun.COM di_devfs_path_free(devpath);
3199517SBill.Taylor@Sun.COM continue;
3209517SBill.Taylor@Sun.COM }
3219517SBill.Taylor@Sun.COM
3229517SBill.Taylor@Sun.COM if ((newdev->drvname = calloc(1, strlen(drivername) + 1))
3239517SBill.Taylor@Sun.COM == NULL) {
3249517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Unable to allocate"
3259517SBill.Taylor@Sun.COM " space for a driver name\n"));
3269517SBill.Taylor@Sun.COM (void) free(newdev->ident);
3279517SBill.Taylor@Sun.COM (void) free(newdev->access_devname);
3289517SBill.Taylor@Sun.COM (void) free(newdev);
3299517SBill.Taylor@Sun.COM di_devfs_path_free(devpath);
3309517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
3319517SBill.Taylor@Sun.COM }
3329517SBill.Taylor@Sun.COM
3339517SBill.Taylor@Sun.COM (void) strlcpy(newdev->drvname, drivername,
3349517SBill.Taylor@Sun.COM strlen(drivername) + 1);
3359517SBill.Taylor@Sun.COM
3369517SBill.Taylor@Sun.COM /* this next bit is backwards compatibility - "IB\0" */
3379517SBill.Taylor@Sun.COM if ((newdev->classname = calloc(1, 3)) == NULL) {
3389517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Unable to allocate "
3399517SBill.Taylor@Sun.COM "space for a class name\n"));
3409517SBill.Taylor@Sun.COM (void) free(newdev->drvname);
3419517SBill.Taylor@Sun.COM (void) free(newdev->ident);
3429517SBill.Taylor@Sun.COM (void) free(newdev->access_devname);
3439517SBill.Taylor@Sun.COM (void) free(newdev);
3449517SBill.Taylor@Sun.COM di_devfs_path_free(devpath);
3459517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
3469517SBill.Taylor@Sun.COM }
3479517SBill.Taylor@Sun.COM (void) strlcpy(newdev->classname, "IB", 3);
3489517SBill.Taylor@Sun.COM
3499517SBill.Taylor@Sun.COM newdev->index = idx;
3509517SBill.Taylor@Sun.COM ++idx;
3519517SBill.Taylor@Sun.COM newdev->plugin = self;
3529517SBill.Taylor@Sun.COM
3539517SBill.Taylor@Sun.COM di_devfs_path_free(devpath);
3549517SBill.Taylor@Sun.COM
3559517SBill.Taylor@Sun.COM TAILQ_INSERT_TAIL(fw_devices, newdev, nextdev);
3569517SBill.Taylor@Sun.COM }
3579517SBill.Taylor@Sun.COM
3589517SBill.Taylor@Sun.COM if (fwflash_debug != 0) {
3599517SBill.Taylor@Sun.COM struct devicelist *tempdev;
3609517SBill.Taylor@Sun.COM
3619517SBill.Taylor@Sun.COM TAILQ_FOREACH(tempdev, fw_devices, nextdev) {
3629517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "fw_identify: hermon:\n");
3639517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "\ttempdev @ 0x%lx\n"
3649517SBill.Taylor@Sun.COM "\t\taccess_devname: %s\n"
3659517SBill.Taylor@Sun.COM "\t\tdrvname: %s\tclassname: %s\n"
3669517SBill.Taylor@Sun.COM "\t\tident->vid: %s\n"
3679517SBill.Taylor@Sun.COM "\t\tident->pid: %s\n"
3689517SBill.Taylor@Sun.COM "\t\tident->revid: %s\n"
3699517SBill.Taylor@Sun.COM "\t\tindex: %d\n"
3709517SBill.Taylor@Sun.COM "\t\tguid0: %s\n"
3719517SBill.Taylor@Sun.COM "\t\tguid1: %s\n"
3729517SBill.Taylor@Sun.COM "\t\tguid2: %s\n"
3739517SBill.Taylor@Sun.COM "\t\tguid3: %s\n"
3749517SBill.Taylor@Sun.COM "\t\tplugin @ 0x%lx\n\n",
3759517SBill.Taylor@Sun.COM &tempdev,
3769517SBill.Taylor@Sun.COM tempdev->access_devname,
3779517SBill.Taylor@Sun.COM tempdev->drvname, newdev->classname,
3789517SBill.Taylor@Sun.COM tempdev->ident->vid,
3799517SBill.Taylor@Sun.COM tempdev->ident->pid,
3809517SBill.Taylor@Sun.COM tempdev->ident->revid,
3819517SBill.Taylor@Sun.COM tempdev->index,
382*12472SShantkumar.Hiremath@Sun.COM (tempdev->addresses[0] ? tempdev->addresses[0] :
383*12472SShantkumar.Hiremath@Sun.COM "(not supported)"),
384*12472SShantkumar.Hiremath@Sun.COM (tempdev->addresses[1] ? tempdev->addresses[1] :
385*12472SShantkumar.Hiremath@Sun.COM "(not supported)"),
386*12472SShantkumar.Hiremath@Sun.COM (tempdev->addresses[2] ? tempdev->addresses[2] :
387*12472SShantkumar.Hiremath@Sun.COM "(not supported)"),
388*12472SShantkumar.Hiremath@Sun.COM (tempdev->addresses[3] ? tempdev->addresses[3] :
389*12472SShantkumar.Hiremath@Sun.COM "(not supported)"),
3909517SBill.Taylor@Sun.COM tempdev->plugin);
3919517SBill.Taylor@Sun.COM }
3929517SBill.Taylor@Sun.COM }
3939517SBill.Taylor@Sun.COM
3949517SBill.Taylor@Sun.COM return (FWFLASH_SUCCESS);
3959517SBill.Taylor@Sun.COM }
3969517SBill.Taylor@Sun.COM
3979517SBill.Taylor@Sun.COM
3989517SBill.Taylor@Sun.COM int
fw_devinfo(struct devicelist * thisdev)3999517SBill.Taylor@Sun.COM fw_devinfo(struct devicelist *thisdev)
4009517SBill.Taylor@Sun.COM {
4019517SBill.Taylor@Sun.COM ib_cnx_encap_ident_t *encap;
4029517SBill.Taylor@Sun.COM
4039517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: fw_devinfo\n");
4049517SBill.Taylor@Sun.COM
4059517SBill.Taylor@Sun.COM encap = (ib_cnx_encap_ident_t *)thisdev->ident->encap_ident;
4069517SBill.Taylor@Sun.COM if (CNX_I_CHECK_HANDLE(encap)) {
4079517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: fw_devinfo: Invalid handle "
4089517SBill.Taylor@Sun.COM "for device %s! \n"), thisdev->access_devname);
4099517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
4109517SBill.Taylor@Sun.COM }
4119517SBill.Taylor@Sun.COM
4129517SBill.Taylor@Sun.COM /* Try the primary first, then the secondary */
4139517SBill.Taylor@Sun.COM fprintf(stdout, gettext("Device[%d] %s\n"),
4149517SBill.Taylor@Sun.COM thisdev->index, thisdev->access_devname);
4159517SBill.Taylor@Sun.COM fprintf(stdout, gettext("Class [%s]\n"), thisdev->classname);
4169517SBill.Taylor@Sun.COM
4179517SBill.Taylor@Sun.COM fprintf(stdout, "\t");
4189517SBill.Taylor@Sun.COM
4199517SBill.Taylor@Sun.COM /* Mellanox HCA Flash app note, p40, #4.2.3 table 9 */
4209517SBill.Taylor@Sun.COM fprintf(stdout, gettext("GUID: System Image - %s\n"),
4219517SBill.Taylor@Sun.COM thisdev->addresses[3]);
4229517SBill.Taylor@Sun.COM fprintf(stdout, gettext("\t\tNode Image - %s\n"),
4239517SBill.Taylor@Sun.COM thisdev->addresses[0]);
4249517SBill.Taylor@Sun.COM fprintf(stdout, gettext("\t\tPort 1\t - %s\n"),
4259517SBill.Taylor@Sun.COM thisdev->addresses[1]);
4269517SBill.Taylor@Sun.COM fprintf(stdout, gettext("\t\tPort 2\t - %s\n"),
4279517SBill.Taylor@Sun.COM thisdev->addresses[2]);
4289517SBill.Taylor@Sun.COM
4299517SBill.Taylor@Sun.COM fprintf(stdout, gettext("\tFirmware revision : %s\n"),
4309517SBill.Taylor@Sun.COM thisdev->ident->revid);
4319517SBill.Taylor@Sun.COM
4329517SBill.Taylor@Sun.COM if (encap->pn_len != 0) {
4339517SBill.Taylor@Sun.COM if (strlen(encap->info.mlx_id))
434*12472SShantkumar.Hiremath@Sun.COM fprintf(stdout, gettext("\tProduct\t\t : "
435*12472SShantkumar.Hiremath@Sun.COM "%s %X (%s)\n"), encap->info.mlx_pn,
436*12472SShantkumar.Hiremath@Sun.COM encap->hwrev, encap->info.mlx_id);
4379517SBill.Taylor@Sun.COM else
438*12472SShantkumar.Hiremath@Sun.COM fprintf(stdout, gettext("\tProduct\t\t : %s %X\n"),
439*12472SShantkumar.Hiremath@Sun.COM encap->info.mlx_pn, encap->hwrev);
4409517SBill.Taylor@Sun.COM
4419517SBill.Taylor@Sun.COM if (strlen(encap->info.mlx_psid))
4429517SBill.Taylor@Sun.COM fprintf(stdout, gettext("\tPSID\t\t : %s\n"),
4439517SBill.Taylor@Sun.COM encap->info.mlx_psid);
4449517SBill.Taylor@Sun.COM else if (strlen(thisdev->ident->pid))
4459517SBill.Taylor@Sun.COM fprintf(stdout, gettext("\t%s\n"), thisdev->ident->pid);
4469517SBill.Taylor@Sun.COM } else {
4479517SBill.Taylor@Sun.COM fprintf(stdout, gettext("\t%s\n"), thisdev->ident->pid);
4489517SBill.Taylor@Sun.COM }
4499517SBill.Taylor@Sun.COM fprintf(stdout, "\n\n");
4509517SBill.Taylor@Sun.COM
4519517SBill.Taylor@Sun.COM return (cnx_close(thisdev));
4529517SBill.Taylor@Sun.COM }
4539517SBill.Taylor@Sun.COM
4549517SBill.Taylor@Sun.COM
4559517SBill.Taylor@Sun.COM /*
4569517SBill.Taylor@Sun.COM * Helper functions lurk beneath this point
4579517SBill.Taylor@Sun.COM */
4589517SBill.Taylor@Sun.COM
4599517SBill.Taylor@Sun.COM
4609517SBill.Taylor@Sun.COM /*
4619517SBill.Taylor@Sun.COM * Notes:
4629517SBill.Taylor@Sun.COM * 1. flash read is done in 32 bit quantities, and the driver returns
4639517SBill.Taylor@Sun.COM * data in host byteorder form.
4649517SBill.Taylor@Sun.COM * 2. flash write is done in 8 bit quantities by the driver.
4659517SBill.Taylor@Sun.COM * 3. data in the flash should be in network byteorder.
4669517SBill.Taylor@Sun.COM * 4. data in image files is in network byteorder form.
4679517SBill.Taylor@Sun.COM * 5. data in image structures in memory is kept in network byteorder.
4689517SBill.Taylor@Sun.COM * 6. the functions in this file deal with data in host byteorder form.
4699517SBill.Taylor@Sun.COM */
4709517SBill.Taylor@Sun.COM
4719517SBill.Taylor@Sun.COM static int
cnx_read_image(ib_cnx_encap_ident_t * handle)4729517SBill.Taylor@Sun.COM cnx_read_image(ib_cnx_encap_ident_t *handle)
4739517SBill.Taylor@Sun.COM {
4749517SBill.Taylor@Sun.COM hermon_flash_ioctl_t ioctl_info;
4759517SBill.Taylor@Sun.COM uint32_t phys_addr;
4769517SBill.Taylor@Sun.COM int ret, i;
4779517SBill.Taylor@Sun.COM int image_size;
4789517SBill.Taylor@Sun.COM int type;
4799517SBill.Taylor@Sun.COM
4809517SBill.Taylor@Sun.COM type = handle->state &
4819517SBill.Taylor@Sun.COM (FWFLASH_IB_STATE_IMAGE_PRI | FWFLASH_IB_STATE_IMAGE_SEC);
4829517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_read_image: type %lx\n", type);
4839517SBill.Taylor@Sun.COM
4849517SBill.Taylor@Sun.COM if (type == 0) {
4859517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("cnx_read_image: Must read in "
4869517SBill.Taylor@Sun.COM "image first\n"));
4879517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
4889517SBill.Taylor@Sun.COM }
4899517SBill.Taylor@Sun.COM
4909517SBill.Taylor@Sun.COM image_size = handle->fw_sz;
4919517SBill.Taylor@Sun.COM if (image_size <= 0) {
4929517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("cnx_read_image: Invalid image size "
4939517SBill.Taylor@Sun.COM "0x%x for %s image\n"),
4949517SBill.Taylor@Sun.COM image_size, (type == 0x1 ? "Primary" : "Secondary"));
4959517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
4969517SBill.Taylor@Sun.COM }
4979517SBill.Taylor@Sun.COM
4989517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: fw_size: 0x%x\n", image_size);
4999517SBill.Taylor@Sun.COM
5009517SBill.Taylor@Sun.COM handle->fw = (uint32_t *)calloc(1, image_size);
5019517SBill.Taylor@Sun.COM if (handle->fw == NULL) {
5029517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("cnx_read_image: Unable to allocate "
5039517SBill.Taylor@Sun.COM "memory for fw_img : (%s)\n"), strerror(errno));
5049517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
5059517SBill.Taylor@Sun.COM }
5069517SBill.Taylor@Sun.COM
5079517SBill.Taylor@Sun.COM ioctl_info.af_type = HERMON_FLASH_READ_QUADLET;
5089517SBill.Taylor@Sun.COM for (i = 0; i < image_size; i += 4) {
5099517SBill.Taylor@Sun.COM phys_addr = cnx_cont2phys(handle->log2_chunk_sz, i, type);
5109517SBill.Taylor@Sun.COM ioctl_info.af_addr = phys_addr;
5119517SBill.Taylor@Sun.COM
5129517SBill.Taylor@Sun.COM ret = cnx_read_ioctl(handle, &ioctl_info);
5139517SBill.Taylor@Sun.COM if (ret != 0) {
5149517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("cnx_read_image: Failed to "
5159517SBill.Taylor@Sun.COM "read sector %d\n"), i);
5169517SBill.Taylor@Sun.COM free(handle->fw);
5179517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
5189517SBill.Taylor@Sun.COM }
5199517SBill.Taylor@Sun.COM handle->fw[i / 4] = htonl(ioctl_info.af_quadlet);
5209517SBill.Taylor@Sun.COM }
5219517SBill.Taylor@Sun.COM
5229517SBill.Taylor@Sun.COM for (i = 0; i < image_size; i += 4) {
5239517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_read_image: addr[0x%x] = 0x%08x\n", i,
5249517SBill.Taylor@Sun.COM ntohl(handle->fw[i / 4]));
5259517SBill.Taylor@Sun.COM }
5269517SBill.Taylor@Sun.COM
5279517SBill.Taylor@Sun.COM return (FWFLASH_SUCCESS);
5289517SBill.Taylor@Sun.COM }
5299517SBill.Taylor@Sun.COM
5309517SBill.Taylor@Sun.COM static int
cnx_write_file(ib_cnx_encap_ident_t * handle,const char * filename)5319517SBill.Taylor@Sun.COM cnx_write_file(ib_cnx_encap_ident_t *handle, const char *filename)
5329517SBill.Taylor@Sun.COM {
5339517SBill.Taylor@Sun.COM FILE *fp;
5349517SBill.Taylor@Sun.COM int fd;
5359517SBill.Taylor@Sun.COM mode_t mode = S_IRUSR | S_IWUSR;
5369517SBill.Taylor@Sun.COM int len;
5379517SBill.Taylor@Sun.COM
5389517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_write_file\n");
5399517SBill.Taylor@Sun.COM
5409517SBill.Taylor@Sun.COM errno = 0;
5419517SBill.Taylor@Sun.COM if ((fd = open(filename, O_RDWR|O_CREAT|O_DSYNC, mode)) < 0) {
5429517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Unable to open specified "
5439517SBill.Taylor@Sun.COM "file (%s) for writing: %s\n"), filename, strerror(errno));
5449517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
5459517SBill.Taylor@Sun.COM }
5469517SBill.Taylor@Sun.COM
5479517SBill.Taylor@Sun.COM errno = 0;
5489517SBill.Taylor@Sun.COM fp = fdopen(fd, "w");
5499517SBill.Taylor@Sun.COM if (fp == NULL) {
5509517SBill.Taylor@Sun.COM (void) fprintf(stderr, gettext("hermon: Unknown filename %s : "
5519517SBill.Taylor@Sun.COM "%s\n"), filename, strerror(errno));
5529517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
5539517SBill.Taylor@Sun.COM }
5549517SBill.Taylor@Sun.COM
5559517SBill.Taylor@Sun.COM len = ntohl(handle->fw[CNX_IMG_SIZE_OFFSET / 4]);
5569517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_write_file: Writing to file. Length 0x%x\n", len);
5579517SBill.Taylor@Sun.COM
5589517SBill.Taylor@Sun.COM if (fwrite(&handle->fw[0], len, 1, fp) == 0) {
5599517SBill.Taylor@Sun.COM (void) fprintf(stderr, gettext("hermon: fwrite failed"));
5609517SBill.Taylor@Sun.COM perror("fwrite");
5619517SBill.Taylor@Sun.COM (void) fclose(fp);
5629517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
5639517SBill.Taylor@Sun.COM }
5649517SBill.Taylor@Sun.COM (void) fclose(fp);
5659517SBill.Taylor@Sun.COM return (FWFLASH_SUCCESS);
5669517SBill.Taylor@Sun.COM }
5679517SBill.Taylor@Sun.COM
5689517SBill.Taylor@Sun.COM static int
cnx_verify_image(ib_cnx_encap_ident_t * handle,int type)5699517SBill.Taylor@Sun.COM cnx_verify_image(ib_cnx_encap_ident_t *handle, int type)
5709517SBill.Taylor@Sun.COM {
5719517SBill.Taylor@Sun.COM uint32_t new_start_addr;
5729517SBill.Taylor@Sun.COM
5739517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: cnx_verify_image\n");
5749517SBill.Taylor@Sun.COM
5759517SBill.Taylor@Sun.COM new_start_addr = cnx_cont2phys(handle->log2_chunk_sz, 0, type);
5769517SBill.Taylor@Sun.COM
5779517SBill.Taylor@Sun.COM return (cnx_check_for_magic_pattern(handle, new_start_addr));
5789517SBill.Taylor@Sun.COM }
5799517SBill.Taylor@Sun.COM
5809517SBill.Taylor@Sun.COM static int
cnx_set_guids(ib_cnx_encap_ident_t * handle,void * arg)5819517SBill.Taylor@Sun.COM cnx_set_guids(ib_cnx_encap_ident_t *handle, void *arg)
5829517SBill.Taylor@Sun.COM {
5839517SBill.Taylor@Sun.COM uint32_t addr;
5849517SBill.Taylor@Sun.COM uint32_t *guids;
5859517SBill.Taylor@Sun.COM
5869517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: cnx_set_guids\n");
5879517SBill.Taylor@Sun.COM
5889517SBill.Taylor@Sun.COM guids = (uint32_t *)arg;
5899517SBill.Taylor@Sun.COM addr = ntohl(verifier->fwimage[CNX_NGUIDPTR_OFFSET / 4]) / 4;
5909517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_set_guids: guid_start_addr: 0x%x\n", addr * 4);
5919517SBill.Taylor@Sun.COM
5929517SBill.Taylor@Sun.COM /*
5939517SBill.Taylor@Sun.COM * guids are supplied by callers as 64 bit values in host byteorder.
5949517SBill.Taylor@Sun.COM * Storage is in network byteorder.
5959517SBill.Taylor@Sun.COM */
5969517SBill.Taylor@Sun.COM #ifdef _BIG_ENDIAN
5979517SBill.Taylor@Sun.COM if (handle->state & FWFLASH_IB_STATE_GUIDN) {
5989517SBill.Taylor@Sun.COM verifier->fwimage[addr] = guids[0];
5999517SBill.Taylor@Sun.COM verifier->fwimage[addr + 1] = guids[1];
6009517SBill.Taylor@Sun.COM }
6019517SBill.Taylor@Sun.COM
6029517SBill.Taylor@Sun.COM if (handle->state & FWFLASH_IB_STATE_GUID1) {
6039517SBill.Taylor@Sun.COM verifier->fwimage[addr + 2] = guids[2];
6049517SBill.Taylor@Sun.COM verifier->fwimage[addr + 3] = guids[3];
6059517SBill.Taylor@Sun.COM }
6069517SBill.Taylor@Sun.COM
6079517SBill.Taylor@Sun.COM if (handle->state & FWFLASH_IB_STATE_GUID2) {
6089517SBill.Taylor@Sun.COM verifier->fwimage[addr + 4] = guids[4];
6099517SBill.Taylor@Sun.COM verifier->fwimage[addr + 5] = guids[5];
6109517SBill.Taylor@Sun.COM }
6119517SBill.Taylor@Sun.COM
6129517SBill.Taylor@Sun.COM if (handle->state & FWFLASH_IB_STATE_GUIDS) {
6139517SBill.Taylor@Sun.COM verifier->fwimage[addr + 6] = guids[6];
6149517SBill.Taylor@Sun.COM verifier->fwimage[addr + 7] = guids[7];
6159517SBill.Taylor@Sun.COM }
6169517SBill.Taylor@Sun.COM #else
6179517SBill.Taylor@Sun.COM if (handle->state & FWFLASH_IB_STATE_GUIDN) {
6189517SBill.Taylor@Sun.COM verifier->fwimage[addr] = htonl(guids[1]);
6199517SBill.Taylor@Sun.COM verifier->fwimage[addr + 1] = htonl(guids[0]);
6209517SBill.Taylor@Sun.COM }
6219517SBill.Taylor@Sun.COM
6229517SBill.Taylor@Sun.COM if (handle->state & FWFLASH_IB_STATE_GUID1) {
6239517SBill.Taylor@Sun.COM verifier->fwimage[addr + 2] = htonl(guids[3]);
6249517SBill.Taylor@Sun.COM verifier->fwimage[addr + 3] = htonl(guids[2]);
6259517SBill.Taylor@Sun.COM }
6269517SBill.Taylor@Sun.COM
6279517SBill.Taylor@Sun.COM if (handle->state & FWFLASH_IB_STATE_GUID2) {
6289517SBill.Taylor@Sun.COM verifier->fwimage[addr + 4] = htonl(guids[5]);
6299517SBill.Taylor@Sun.COM verifier->fwimage[addr + 5] = htonl(guids[4]);
6309517SBill.Taylor@Sun.COM }
6319517SBill.Taylor@Sun.COM
6329517SBill.Taylor@Sun.COM if (handle->state & FWFLASH_IB_STATE_GUIDS) {
6339517SBill.Taylor@Sun.COM verifier->fwimage[addr + 6] = htonl(guids[7]);
6349517SBill.Taylor@Sun.COM verifier->fwimage[addr + 7] = htonl(guids[6]);
6359517SBill.Taylor@Sun.COM }
6369517SBill.Taylor@Sun.COM #endif
6379517SBill.Taylor@Sun.COM
6389517SBill.Taylor@Sun.COM cnx_local_set_guid_crc_img((addr * 4) - 0x10, CNX_GUID_CRC16_SIZE,
6399517SBill.Taylor@Sun.COM CNX_GUID_CRC16_OFFSET);
6409517SBill.Taylor@Sun.COM
6419517SBill.Taylor@Sun.COM return (FWFLASH_SUCCESS);
6429517SBill.Taylor@Sun.COM }
6439517SBill.Taylor@Sun.COM
6449517SBill.Taylor@Sun.COM /*
6459517SBill.Taylor@Sun.COM * Notes: Burn the image
6469517SBill.Taylor@Sun.COM *
6479517SBill.Taylor@Sun.COM * 1. Erase the entire sector where the new image is to be burned.
6489517SBill.Taylor@Sun.COM * 2. Burn the image WITHOUT the magic pattern. This marks the new image
6499517SBill.Taylor@Sun.COM * as invalid during the burn process. If the current image (i.e
6509517SBill.Taylor@Sun.COM * containing a magic pattern) on the Flash is stored on the even
6519517SBill.Taylor@Sun.COM * chunks (PRIMARY), burn the new image to the odd chunks (SECONDARY),
6529517SBill.Taylor@Sun.COM * or vice versa.
6539517SBill.Taylor@Sun.COM * 3. Burn the magic pattern at the beginning of the new image on the Flash.
6549517SBill.Taylor@Sun.COM * This will validate the new image.
6559517SBill.Taylor@Sun.COM * 4. Set the BootAddress register to its new location.
6569517SBill.Taylor@Sun.COM */
6579517SBill.Taylor@Sun.COM static int
cnx_write_image(ib_cnx_encap_ident_t * handle,int type)6589517SBill.Taylor@Sun.COM cnx_write_image(ib_cnx_encap_ident_t *handle, int type)
6599517SBill.Taylor@Sun.COM {
6609517SBill.Taylor@Sun.COM hermon_flash_ioctl_t ioctl_info;
6619517SBill.Taylor@Sun.COM int sector_size;
6629517SBill.Taylor@Sun.COM int size;
6639517SBill.Taylor@Sun.COM int i;
6649517SBill.Taylor@Sun.COM uint32_t new_start_addr;
6659517SBill.Taylor@Sun.COM uint32_t log2_chunk_sz;
6669517SBill.Taylor@Sun.COM uint8_t *fw;
6679517SBill.Taylor@Sun.COM
6689517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: cnx_write_image\n");
6699517SBill.Taylor@Sun.COM
6709517SBill.Taylor@Sun.COM if (type == 0) {
6719517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("cnx_write_image: Must inform us "
6729517SBill.Taylor@Sun.COM " where to write.\n"));
6739517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
6749517SBill.Taylor@Sun.COM }
6759517SBill.Taylor@Sun.COM
6769517SBill.Taylor@Sun.COM log2_chunk_sz = cnx_get_log2_chunk_size(
6779517SBill.Taylor@Sun.COM ntohl(verifier->fwimage[CNX_CHUNK_SIZE_OFFSET / 4]));
6789517SBill.Taylor@Sun.COM
6799517SBill.Taylor@Sun.COM sector_size = handle->sector_sz;
6809517SBill.Taylor@Sun.COM new_start_addr = ((type - 1) << handle->log2_chunk_sz);
6819517SBill.Taylor@Sun.COM
6829517SBill.Taylor@Sun.COM /* Read Image Size */
6839517SBill.Taylor@Sun.COM size = ntohl(verifier->fwimage[CNX_IMG_SIZE_OFFSET / 4]);
6849517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_write_image: fw image size: 0x%x\n", size);
6859517SBill.Taylor@Sun.COM
6869517SBill.Taylor@Sun.COM /* Sectors must be erased before they can be written to. */
6879517SBill.Taylor@Sun.COM ioctl_info.af_type = HERMON_FLASH_ERASE_SECTOR;
6889517SBill.Taylor@Sun.COM for (i = 0; i < size; i += sector_size) {
6899517SBill.Taylor@Sun.COM ioctl_info.af_sector_num =
6909517SBill.Taylor@Sun.COM cnx_cont2phys(log2_chunk_sz, i, type) / sector_size;
6919517SBill.Taylor@Sun.COM if (cnx_erase_sector_ioctl(handle, &ioctl_info) != 0) {
6929517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("cnx_write_image: Failed to "
6939517SBill.Taylor@Sun.COM "erase sector 0x%x\n"), ioctl_info.af_sector_num);
6949517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
6959517SBill.Taylor@Sun.COM }
6969517SBill.Taylor@Sun.COM }
6979517SBill.Taylor@Sun.COM
6989517SBill.Taylor@Sun.COM fw = (uint8_t *)verifier->fwimage;
6999517SBill.Taylor@Sun.COM ioctl_info.af_type = HERMON_FLASH_WRITE_BYTE;
7009517SBill.Taylor@Sun.COM
7019517SBill.Taylor@Sun.COM /* Write the new image without the magic pattern */
7029517SBill.Taylor@Sun.COM for (i = 16; i < size; i++) {
7039517SBill.Taylor@Sun.COM ioctl_info.af_byte = fw[i];
7049517SBill.Taylor@Sun.COM ioctl_info.af_addr = cnx_cont2phys(log2_chunk_sz, i, type);
7059517SBill.Taylor@Sun.COM if (cnx_write_ioctl(handle, &ioctl_info) != 0) {
7069517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("cnx_write_image: Failed to "
7079517SBill.Taylor@Sun.COM "write byte 0x%x\n"), ioctl_info.af_byte);
7089517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
7099517SBill.Taylor@Sun.COM }
7109517SBill.Taylor@Sun.COM
7119517SBill.Taylor@Sun.COM if (i && !(i % handle->sector_sz)) {
7129517SBill.Taylor@Sun.COM (void) printf(" .");
7139517SBill.Taylor@Sun.COM (void) fflush((void *)NULL);
7149517SBill.Taylor@Sun.COM }
7159517SBill.Taylor@Sun.COM }
7169517SBill.Taylor@Sun.COM
7179517SBill.Taylor@Sun.COM /* Validate the new image -- Write the magic pattern. */
7189517SBill.Taylor@Sun.COM for (i = 0; i < 16; i++) {
7199517SBill.Taylor@Sun.COM ioctl_info.af_byte = fw[i];
7209517SBill.Taylor@Sun.COM ioctl_info.af_addr = cnx_cont2phys(log2_chunk_sz, i, type);
7219517SBill.Taylor@Sun.COM if (cnx_write_ioctl(handle, &ioctl_info) != 0) {
7229517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("cnx_write_image: Failed to "
7239517SBill.Taylor@Sun.COM "write magic pattern byte 0x%x\n"),
7249517SBill.Taylor@Sun.COM ioctl_info.af_byte);
7259517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
7269517SBill.Taylor@Sun.COM }
7279517SBill.Taylor@Sun.COM }
7289517SBill.Taylor@Sun.COM
7299517SBill.Taylor@Sun.COM /* Write new image start address to CR space */
7309517SBill.Taylor@Sun.COM errno = 0;
7319517SBill.Taylor@Sun.COM ioctl_info.af_addr = new_start_addr;
7329517SBill.Taylor@Sun.COM if (ioctl(handle->fd, HERMON_IOCTL_WRITE_BOOT_ADDR, &ioctl_info) != 0) {
7339517SBill.Taylor@Sun.COM logmsg(MSG_WARN, gettext("cnx_write_image: Failed to "
7349517SBill.Taylor@Sun.COM "update boot address register: %s\n"), strerror(errno));
7359517SBill.Taylor@Sun.COM }
7369517SBill.Taylor@Sun.COM
7379517SBill.Taylor@Sun.COM return (FWFLASH_SUCCESS);
7389517SBill.Taylor@Sun.COM }
7399517SBill.Taylor@Sun.COM
7409517SBill.Taylor@Sun.COM
7419517SBill.Taylor@Sun.COM /*
7429517SBill.Taylor@Sun.COM * cnx_identify performs the following actions:
7439517SBill.Taylor@Sun.COM *
7449517SBill.Taylor@Sun.COM * allocates and assigns thisdev->vpr
7459517SBill.Taylor@Sun.COM *
7469517SBill.Taylor@Sun.COM * allocates space for the 4 GUIDs which each IB device must have
7479517SBill.Taylor@Sun.COM * queries the hermon driver for this device's GUIDs
7489517SBill.Taylor@Sun.COM *
7499517SBill.Taylor@Sun.COM * determines the hardware vendor, so that thisdev->vpr->vid
7509517SBill.Taylor@Sun.COM * can be set correctly
7519517SBill.Taylor@Sun.COM */
7529517SBill.Taylor@Sun.COM static int
cnx_identify(struct devicelist * thisdev)7539517SBill.Taylor@Sun.COM cnx_identify(struct devicelist *thisdev)
7549517SBill.Taylor@Sun.COM {
7559517SBill.Taylor@Sun.COM int fd, ret, i;
7569517SBill.Taylor@Sun.COM hermon_flash_init_ioctl_t init_ioctl;
7579517SBill.Taylor@Sun.COM ib_cnx_encap_ident_t *manuf;
7589517SBill.Taylor@Sun.COM cfi_t cfi;
7599517SBill.Taylor@Sun.COM int hw_psid_found = 0;
7609517SBill.Taylor@Sun.COM
7619517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: cnx_identify\n");
7629517SBill.Taylor@Sun.COM /* open the device */
7639517SBill.Taylor@Sun.COM /* hook thisdev->ident->encap_ident to ib_cnx_encap_ident_t */
7649517SBill.Taylor@Sun.COM /* check that all the bits are sane */
7659517SBill.Taylor@Sun.COM /* return success, if warranted */
7669517SBill.Taylor@Sun.COM
7679517SBill.Taylor@Sun.COM errno = 0;
7689517SBill.Taylor@Sun.COM if ((fd = open(thisdev->access_devname, O_RDONLY)) < 0) {
7699517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Unable to open a %s-"
7709517SBill.Taylor@Sun.COM "attached device node: %s: %s\n"), drivername,
7719517SBill.Taylor@Sun.COM thisdev->access_devname, strerror(errno));
7729517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
7739517SBill.Taylor@Sun.COM }
7749517SBill.Taylor@Sun.COM
7759517SBill.Taylor@Sun.COM if ((manuf = calloc(1, sizeof (ib_cnx_encap_ident_t))) == NULL) {
7769517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Unable to allocate space "
7779517SBill.Taylor@Sun.COM "for a %s-attached handle structure\n"), drivername);
7789517SBill.Taylor@Sun.COM close(fd);
7799517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
7809517SBill.Taylor@Sun.COM }
7819517SBill.Taylor@Sun.COM manuf->magic = FWFLASH_IB_MAGIC_NUMBER;
7829517SBill.Taylor@Sun.COM manuf->state = FWFLASH_IB_STATE_NONE;
7839517SBill.Taylor@Sun.COM manuf->fd = fd;
7849517SBill.Taylor@Sun.COM manuf->log2_chunk_sz = 0;
7859517SBill.Taylor@Sun.COM
7869517SBill.Taylor@Sun.COM thisdev->ident->encap_ident = manuf;
7879517SBill.Taylor@Sun.COM
7889517SBill.Taylor@Sun.COM /*
7899517SBill.Taylor@Sun.COM * Inform driver that this command supports the Intel Extended
7909517SBill.Taylor@Sun.COM * CFI command set.
7919517SBill.Taylor@Sun.COM */
7929517SBill.Taylor@Sun.COM cfi.cfi_char[0x10] = 'M';
7939517SBill.Taylor@Sun.COM cfi.cfi_char[0x11] = 'X';
7949517SBill.Taylor@Sun.COM cfi.cfi_char[0x12] = '2';
7959517SBill.Taylor@Sun.COM init_ioctl.af_cfi_info[0x4] = ntohl(cfi.cfi_int[0x4]);
7969517SBill.Taylor@Sun.COM
7979517SBill.Taylor@Sun.COM errno = 0;
7989517SBill.Taylor@Sun.COM ret = ioctl(fd, HERMON_IOCTL_FLASH_INIT, &init_ioctl);
7999517SBill.Taylor@Sun.COM if (ret < 0) {
8009517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: HERMON_IOCTL_FLASH_INIT "
8019517SBill.Taylor@Sun.COM "failed: %s\n"), strerror(errno));
8029517SBill.Taylor@Sun.COM close(fd);
8039517SBill.Taylor@Sun.COM free(manuf);
8049517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
8059517SBill.Taylor@Sun.COM }
8069517SBill.Taylor@Sun.COM
8079517SBill.Taylor@Sun.COM manuf->hwrev = init_ioctl.af_hwrev;
8089517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: init_ioctl: hwrev: %x, fwver: %d.%d.%04d, "
8099517SBill.Taylor@Sun.COM "PN# Len %d\n", init_ioctl.af_hwrev, init_ioctl.af_fwrev.afi_maj,
8109517SBill.Taylor@Sun.COM init_ioctl.af_fwrev.afi_min, init_ioctl.af_fwrev.afi_sub,
8119517SBill.Taylor@Sun.COM init_ioctl.af_pn_len);
8129517SBill.Taylor@Sun.COM
8139517SBill.Taylor@Sun.COM /*
8149517SBill.Taylor@Sun.COM * Determine whether the attached driver supports the Intel or
8159517SBill.Taylor@Sun.COM * AMD Extended CFI command sets. If it doesn't support either,
8169517SBill.Taylor@Sun.COM * then we're hosed, so error out.
8179517SBill.Taylor@Sun.COM */
8189517SBill.Taylor@Sun.COM for (i = 0; i < HERMON_FLASH_CFI_SIZE_QUADLET; i++) {
8199517SBill.Taylor@Sun.COM cfi.cfi_int[i] = ntohl(init_ioctl.af_cfi_info[i]);
8209517SBill.Taylor@Sun.COM }
8219517SBill.Taylor@Sun.COM manuf->cmd_set = cfi.cfi_char[0x13];
8229517SBill.Taylor@Sun.COM
8239517SBill.Taylor@Sun.COM if (cfi.cfi_char[0x10] == 'Q' &&
8249517SBill.Taylor@Sun.COM cfi.cfi_char[0x11] == 'R' &&
8259517SBill.Taylor@Sun.COM cfi.cfi_char[0x12] == 'Y') {
8269517SBill.Taylor@Sun.COM /* make sure the cmd set is SPI */
8279517SBill.Taylor@Sun.COM if (manuf->cmd_set != HERMON_FLASH_SPI_CMDSET) {
8289517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Unsupported flash "
8299517SBill.Taylor@Sun.COM "device command set\n"));
8309517SBill.Taylor@Sun.COM goto identify_end;
8319517SBill.Taylor@Sun.COM }
8329517SBill.Taylor@Sun.COM /* set some defaults */
8339517SBill.Taylor@Sun.COM manuf->sector_sz = HERMON_FLASH_SECTOR_SZ_DEFAULT;
8349517SBill.Taylor@Sun.COM manuf->device_sz = HERMON_FLASH_DEVICE_SZ_DEFAULT;
8359517SBill.Taylor@Sun.COM } else if (manuf->cmd_set == HERMON_FLASH_SPI_CMDSET) {
8369517SBill.Taylor@Sun.COM manuf->sector_sz = HERMON_FLASH_SPI_SECTOR_SIZE;
8379517SBill.Taylor@Sun.COM manuf->device_sz = HERMON_FLASH_SPI_DEVICE_SIZE;
8389517SBill.Taylor@Sun.COM } else {
8399517SBill.Taylor@Sun.COM if (manuf->cmd_set != HERMON_FLASH_AMD_CMDSET &&
8409517SBill.Taylor@Sun.COM manuf->cmd_set != HERMON_FLASH_INTEL_CMDSET) {
8419517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Unknown flash "
8429517SBill.Taylor@Sun.COM "device command set %lx\n"), manuf->cmd_set);
8439517SBill.Taylor@Sun.COM goto identify_end;
8449517SBill.Taylor@Sun.COM }
8459517SBill.Taylor@Sun.COM /* read from the CFI data */
8469517SBill.Taylor@Sun.COM manuf->sector_sz = ((cfi.cfi_char[0x30] << 8) |
8479517SBill.Taylor@Sun.COM cfi.cfi_char[0x2F]) << 8;
8489517SBill.Taylor@Sun.COM manuf->device_sz = 0x1 << cfi.cfi_char[0x27];
8499517SBill.Taylor@Sun.COM }
8509517SBill.Taylor@Sun.COM
8519517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: sector_sz: 0x%08x device_sz: 0x%08x\n",
8529517SBill.Taylor@Sun.COM manuf->sector_sz, manuf->device_sz);
8539517SBill.Taylor@Sun.COM
8549517SBill.Taylor@Sun.COM /* set firmware revision */
8559517SBill.Taylor@Sun.COM manuf->hwfw_img_info.fw_rev.major = init_ioctl.af_fwrev.afi_maj;
8569517SBill.Taylor@Sun.COM manuf->hwfw_img_info.fw_rev.minor = init_ioctl.af_fwrev.afi_min;
8579517SBill.Taylor@Sun.COM manuf->hwfw_img_info.fw_rev.subminor = init_ioctl.af_fwrev.afi_sub;
8589517SBill.Taylor@Sun.COM
8599517SBill.Taylor@Sun.COM if (((thisdev->ident->vid = calloc(1, MLX_VPR_VIDLEN + 1)) == NULL) ||
8609517SBill.Taylor@Sun.COM ((thisdev->ident->revid = calloc(1, MLX_VPR_REVLEN + 1)) == NULL)) {
8619517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Unable to allocate space "
8629517SBill.Taylor@Sun.COM "for a VPR record.\n"));
8639517SBill.Taylor@Sun.COM goto identify_end;
8649517SBill.Taylor@Sun.COM }
8659517SBill.Taylor@Sun.COM (void) strlcpy(thisdev->ident->vid, "MELLANOX", MLX_VPR_VIDLEN);
8669517SBill.Taylor@Sun.COM
8679517SBill.Taylor@Sun.COM /*
8689517SBill.Taylor@Sun.COM * We actually want the hwrev field from the ioctl above.
8699517SBill.Taylor@Sun.COM * Until we find out otherwise, add it onto the end of the
8709517SBill.Taylor@Sun.COM * firmware version details.
8719517SBill.Taylor@Sun.COM */
87210618SShantkumar.Hiremath@Sun.COM snprintf(thisdev->ident->revid, MLX_VPR_REVLEN, "%d.%d.%03d",
8739517SBill.Taylor@Sun.COM manuf->hwfw_img_info.fw_rev.major,
8749517SBill.Taylor@Sun.COM manuf->hwfw_img_info.fw_rev.minor,
8759517SBill.Taylor@Sun.COM manuf->hwfw_img_info.fw_rev.subminor);
8769517SBill.Taylor@Sun.COM
8779517SBill.Taylor@Sun.COM if ((ret = cnx_get_guids(manuf)) != FWFLASH_SUCCESS) {
8789517SBill.Taylor@Sun.COM logmsg(MSG_WARN, gettext("hermon: No GUIDs found for "
8799517SBill.Taylor@Sun.COM "device %s!\n"), thisdev->access_devname);
8809517SBill.Taylor@Sun.COM }
8819517SBill.Taylor@Sun.COM
8829517SBill.Taylor@Sun.COM /* set hw part number, psid, and name in handle */
8839517SBill.Taylor@Sun.COM /* now walk the magic decoder ring table */
8849517SBill.Taylor@Sun.COM manuf->info.mlx_pn = NULL;
8859517SBill.Taylor@Sun.COM manuf->info.mlx_psid = NULL;
8869517SBill.Taylor@Sun.COM manuf->info.mlx_id = NULL;
8879517SBill.Taylor@Sun.COM
8889517SBill.Taylor@Sun.COM if (cnx_get_image_info(manuf) != FWFLASH_SUCCESS) {
8899517SBill.Taylor@Sun.COM logmsg(MSG_WARN, gettext("hermon: Failed to read Image Info "
8909517SBill.Taylor@Sun.COM "for PSID\n"));
8919517SBill.Taylor@Sun.COM hw_psid_found = 0;
8929517SBill.Taylor@Sun.COM } else {
8939517SBill.Taylor@Sun.COM hw_psid_found = 1;
8949517SBill.Taylor@Sun.COM }
8959517SBill.Taylor@Sun.COM
8969517SBill.Taylor@Sun.COM if (init_ioctl.af_pn_len != 0) {
8979517SBill.Taylor@Sun.COM /* part number length */
8989517SBill.Taylor@Sun.COM for (i = 0; i < init_ioctl.af_pn_len; i++) {
8999517SBill.Taylor@Sun.COM if (init_ioctl.af_hwpn[i] == ' ') {
9009517SBill.Taylor@Sun.COM manuf->pn_len = i;
9019517SBill.Taylor@Sun.COM break;
9029517SBill.Taylor@Sun.COM }
9039517SBill.Taylor@Sun.COM }
9049517SBill.Taylor@Sun.COM if (i == init_ioctl.af_pn_len) {
9059517SBill.Taylor@Sun.COM manuf->pn_len = init_ioctl.af_pn_len;
9069517SBill.Taylor@Sun.COM }
9079517SBill.Taylor@Sun.COM } else {
9089517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: Failed to get Part# from hermon "
9099517SBill.Taylor@Sun.COM "driver \n");
9109517SBill.Taylor@Sun.COM manuf->pn_len = 0;
9119517SBill.Taylor@Sun.COM }
9129517SBill.Taylor@Sun.COM
9139517SBill.Taylor@Sun.COM if (manuf->pn_len != 0) {
9149517SBill.Taylor@Sun.COM errno = 0;
9159517SBill.Taylor@Sun.COM manuf->info.mlx_pn = calloc(1, manuf->pn_len);
9169517SBill.Taylor@Sun.COM if (manuf->info.mlx_pn == NULL) {
9179517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: no space available "
9189517SBill.Taylor@Sun.COM "for the HCA PN record (%s)\n"), strerror(errno));
9199517SBill.Taylor@Sun.COM goto identify_end;
9209517SBill.Taylor@Sun.COM }
9219517SBill.Taylor@Sun.COM (void) memcpy(manuf->info.mlx_pn, init_ioctl.af_hwpn,
9229517SBill.Taylor@Sun.COM manuf->pn_len);
9239517SBill.Taylor@Sun.COM manuf->info.mlx_pn[manuf->pn_len] = 0;
9249517SBill.Taylor@Sun.COM
9259517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: HCA PN (%s) PN-Len %d\n",
9269517SBill.Taylor@Sun.COM manuf->info.mlx_pn, manuf->pn_len);
9279517SBill.Taylor@Sun.COM
9289517SBill.Taylor@Sun.COM errno = 0;
9299517SBill.Taylor@Sun.COM manuf->info.mlx_psid = calloc(1, MLX_PSID_SZ);
9309517SBill.Taylor@Sun.COM if (manuf->info.mlx_psid == NULL) {
9319517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: PSID calloc "
9329517SBill.Taylor@Sun.COM "failed :%s\n"), strerror(errno));
9339517SBill.Taylor@Sun.COM goto identify_end;
9349517SBill.Taylor@Sun.COM }
9359517SBill.Taylor@Sun.COM
9369517SBill.Taylor@Sun.COM errno = 0;
9379517SBill.Taylor@Sun.COM if ((manuf->info.mlx_id = calloc(1, MLX_STR_ID_SZ)) == NULL) {
9389517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: "
9399517SBill.Taylor@Sun.COM "ID calloc failed (%s)\n"),
9409517SBill.Taylor@Sun.COM strerror(errno));
9419517SBill.Taylor@Sun.COM goto identify_end;
9429517SBill.Taylor@Sun.COM }
9439517SBill.Taylor@Sun.COM
9449517SBill.Taylor@Sun.COM /* Find part number, set the rest */
9459517SBill.Taylor@Sun.COM for (i = 0; i < MLX_MAX_ID; i++) {
9469517SBill.Taylor@Sun.COM if (strncmp((const char *)init_ioctl.af_hwpn,
9479517SBill.Taylor@Sun.COM mlx_mdr[i].mlx_pn, manuf->pn_len) == 0) {
9489517SBill.Taylor@Sun.COM
9499517SBill.Taylor@Sun.COM if (hw_psid_found) {
9509517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "HW-PSID: %s "
9519517SBill.Taylor@Sun.COM "MLX_MDR[%d]: %s\n",
9529517SBill.Taylor@Sun.COM manuf->hwfw_img_info.psid, i,
9539517SBill.Taylor@Sun.COM mlx_mdr[i].mlx_psid);
9549517SBill.Taylor@Sun.COM if (strncmp((const char *)
9559517SBill.Taylor@Sun.COM manuf->hwfw_img_info.psid,
9569517SBill.Taylor@Sun.COM mlx_mdr[i].mlx_psid,
9579517SBill.Taylor@Sun.COM MLX_PSID_SZ) != 0)
9589517SBill.Taylor@Sun.COM continue;
9599517SBill.Taylor@Sun.COM }
9609517SBill.Taylor@Sun.COM /* Set PSID */
9619517SBill.Taylor@Sun.COM (void) memcpy(manuf->info.mlx_psid,
9629517SBill.Taylor@Sun.COM mlx_mdr[i].mlx_psid, MLX_PSID_SZ);
9639517SBill.Taylor@Sun.COM manuf->info.mlx_psid[MLX_PSID_SZ - 1] = 0;
9649517SBill.Taylor@Sun.COM
9659517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: HCA PSID (%s)\n",
9669517SBill.Taylor@Sun.COM manuf->info.mlx_psid);
9679517SBill.Taylor@Sun.COM
9689517SBill.Taylor@Sun.COM (void) strlcpy(manuf->info.mlx_id,
9699517SBill.Taylor@Sun.COM mlx_mdr[i].mlx_id,
9709517SBill.Taylor@Sun.COM strlen(mlx_mdr[i].mlx_id) + 1);
9719517SBill.Taylor@Sun.COM
9729517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: HCA Name (%s)\n",
9739517SBill.Taylor@Sun.COM manuf->info.mlx_id);
9749517SBill.Taylor@Sun.COM
9759517SBill.Taylor@Sun.COM break;
9769517SBill.Taylor@Sun.COM }
9779517SBill.Taylor@Sun.COM }
9789517SBill.Taylor@Sun.COM }
9799517SBill.Taylor@Sun.COM
9809517SBill.Taylor@Sun.COM if ((manuf->pn_len == 0) || (i == MLX_MAX_ID)) {
9819517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: No hardware part number "
9829517SBill.Taylor@Sun.COM "information available for this HCA\n");
9839517SBill.Taylor@Sun.COM
9849517SBill.Taylor@Sun.COM i = strlen("No hardware information available for this device");
9859517SBill.Taylor@Sun.COM
9869517SBill.Taylor@Sun.COM thisdev->ident->pid = calloc(1, i + 2);
9879517SBill.Taylor@Sun.COM sprintf(thisdev->ident->pid, "No additional hardware info "
9889517SBill.Taylor@Sun.COM "available for this device");
9899517SBill.Taylor@Sun.COM } else {
9909517SBill.Taylor@Sun.COM errno = 0;
9919517SBill.Taylor@Sun.COM if ((thisdev->ident->pid = calloc(1,
9929517SBill.Taylor@Sun.COM strlen(manuf->info.mlx_psid) + 1)) != NULL) {
9939517SBill.Taylor@Sun.COM (void) strlcpy(thisdev->ident->pid,
9949517SBill.Taylor@Sun.COM manuf->info.mlx_psid,
9959517SBill.Taylor@Sun.COM strlen(manuf->info.mlx_psid) + 1);
9969517SBill.Taylor@Sun.COM } else {
9979517SBill.Taylor@Sun.COM logmsg(MSG_ERROR,
9989517SBill.Taylor@Sun.COM gettext("hermon: Unable to allocate space for a "
9999517SBill.Taylor@Sun.COM "hardware identifier: %s\n"), strerror(errno));
10009517SBill.Taylor@Sun.COM goto identify_end;
10019517SBill.Taylor@Sun.COM }
10029517SBill.Taylor@Sun.COM }
10039517SBill.Taylor@Sun.COM
10049517SBill.Taylor@Sun.COM for (i = 0; i < 4; i++) {
10059517SBill.Taylor@Sun.COM errno = 0;
10069517SBill.Taylor@Sun.COM if ((thisdev->addresses[i] = calloc(1,
10079517SBill.Taylor@Sun.COM (2 * sizeof (uint64_t)) + 1)) == NULL) {
10089517SBill.Taylor@Sun.COM logmsg(MSG_ERROR,
10099517SBill.Taylor@Sun.COM gettext("hermon: Unable to allocate space for a "
10109517SBill.Taylor@Sun.COM "human-readable HCA guid: %s\n"), strerror(errno));
10119517SBill.Taylor@Sun.COM goto identify_end;
10129517SBill.Taylor@Sun.COM }
10139517SBill.Taylor@Sun.COM (void) sprintf(thisdev->addresses[i], "%016llx",
10149517SBill.Taylor@Sun.COM manuf->ibguids[i]);
10159517SBill.Taylor@Sun.COM }
10169517SBill.Taylor@Sun.COM
10179517SBill.Taylor@Sun.COM /*
10189517SBill.Taylor@Sun.COM * We do NOT close the fd here, since we can close it
10199517SBill.Taylor@Sun.COM * at the end of the fw_readfw() or fw_writefw() functions
10209517SBill.Taylor@Sun.COM * instead and not get the poor dear confused about whether
10219517SBill.Taylor@Sun.COM * it's been inited already.
10229517SBill.Taylor@Sun.COM */
10239517SBill.Taylor@Sun.COM
10249517SBill.Taylor@Sun.COM return (FWFLASH_SUCCESS);
10259517SBill.Taylor@Sun.COM
10269517SBill.Taylor@Sun.COM /* cleanup */
10279517SBill.Taylor@Sun.COM identify_end:
10289517SBill.Taylor@Sun.COM cnx_close(thisdev);
10299517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
10309517SBill.Taylor@Sun.COM }
10319517SBill.Taylor@Sun.COM
10329517SBill.Taylor@Sun.COM static int
cnx_get_guids(ib_cnx_encap_ident_t * handle)10339517SBill.Taylor@Sun.COM cnx_get_guids(ib_cnx_encap_ident_t *handle)
10349517SBill.Taylor@Sun.COM {
10359517SBill.Taylor@Sun.COM int i, rv;
10369517SBill.Taylor@Sun.COM
10379517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_get_guids\n");
10389517SBill.Taylor@Sun.COM
10399517SBill.Taylor@Sun.COM /* make sure we've got our fallback position organised */
10409517SBill.Taylor@Sun.COM for (i = 0; i < 4; i++) {
10419517SBill.Taylor@Sun.COM handle->ibguids[i] = 0x00000000;
10429517SBill.Taylor@Sun.COM }
10439517SBill.Taylor@Sun.COM
10449517SBill.Taylor@Sun.COM rv = cnx_find_magic_n_chnk_sz(handle, FWFLASH_IB_STATE_IMAGE_PRI);
10459517SBill.Taylor@Sun.COM if (rv != FWFLASH_SUCCESS) {
10469517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: Failed to get Primary magic number. "
10479517SBill.Taylor@Sun.COM "Trying Secondary... \n");
10489517SBill.Taylor@Sun.COM rv = cnx_find_magic_n_chnk_sz(handle,
10499517SBill.Taylor@Sun.COM FWFLASH_IB_STATE_IMAGE_SEC);
10509517SBill.Taylor@Sun.COM if (rv != FWFLASH_SUCCESS) {
10519517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Failed to get "
10529517SBill.Taylor@Sun.COM "Secondary magic number.\n"));
10539517SBill.Taylor@Sun.COM logmsg(MSG_ERROR,
10549517SBill.Taylor@Sun.COM gettext("Warning: HCA Firmware corrupt.\n"));
10559517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
10569517SBill.Taylor@Sun.COM }
10579517SBill.Taylor@Sun.COM rv = cnx_read_guids(handle, FWFLASH_IB_STATE_IMAGE_SEC);
10589517SBill.Taylor@Sun.COM if (rv != FWFLASH_SUCCESS) {
10599517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Failed to read "
10609517SBill.Taylor@Sun.COM "secondary guids.\n"));
10619517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
10629517SBill.Taylor@Sun.COM }
10639517SBill.Taylor@Sun.COM } else {
10649517SBill.Taylor@Sun.COM rv = cnx_read_guids(handle, FWFLASH_IB_STATE_IMAGE_PRI);
10659517SBill.Taylor@Sun.COM if (rv != FWFLASH_SUCCESS) {
10669517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Failed to read "
10679517SBill.Taylor@Sun.COM "primary guids.\n"));
10689517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
10699517SBill.Taylor@Sun.COM }
10709517SBill.Taylor@Sun.COM }
10719517SBill.Taylor@Sun.COM for (i = 0; i < 4; i++) {
10729517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: ibguids[%d] 0x%016llx\n", i,
10739517SBill.Taylor@Sun.COM handle->ibguids[i]);
10749517SBill.Taylor@Sun.COM }
10759517SBill.Taylor@Sun.COM for (i = 0; i < 2; i++) {
10769517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: ib_portmac[%d] 0x%016llx\n", i,
10779517SBill.Taylor@Sun.COM handle->ib_mac[i]);
10789517SBill.Taylor@Sun.COM }
10799517SBill.Taylor@Sun.COM
10809517SBill.Taylor@Sun.COM return (FWFLASH_SUCCESS);
10819517SBill.Taylor@Sun.COM }
10829517SBill.Taylor@Sun.COM
10839517SBill.Taylor@Sun.COM static int
cnx_close(struct devicelist * flashdev)10849517SBill.Taylor@Sun.COM cnx_close(struct devicelist *flashdev)
10859517SBill.Taylor@Sun.COM {
10869517SBill.Taylor@Sun.COM ib_cnx_encap_ident_t *handle;
10879517SBill.Taylor@Sun.COM
10889517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_close\n");
10899517SBill.Taylor@Sun.COM
10909517SBill.Taylor@Sun.COM handle = (ib_cnx_encap_ident_t *)flashdev->ident->encap_ident;
10919517SBill.Taylor@Sun.COM
10929517SBill.Taylor@Sun.COM if (CNX_I_CHECK_HANDLE(handle)) {
10939517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Invalid Handle to close "
10949517SBill.Taylor@Sun.COM "device %s! \n"), flashdev->access_devname);
10959517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
10969517SBill.Taylor@Sun.COM }
10979517SBill.Taylor@Sun.COM
10989517SBill.Taylor@Sun.COM if (handle->fd > 0) {
10999517SBill.Taylor@Sun.COM errno = 0;
11009517SBill.Taylor@Sun.COM (void) ioctl(handle->fd, HERMON_IOCTL_FLASH_FINI);
11019517SBill.Taylor@Sun.COM if (close(handle->fd) != 0) {
11029517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("hermon: Unable to properly "
11039517SBill.Taylor@Sun.COM "close device %s! (%s)\n"),
11049517SBill.Taylor@Sun.COM flashdev->access_devname, strerror(errno));
11059517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
11069517SBill.Taylor@Sun.COM }
11079517SBill.Taylor@Sun.COM }
11089517SBill.Taylor@Sun.COM
11099517SBill.Taylor@Sun.COM if (handle != NULL) {
11109517SBill.Taylor@Sun.COM if (handle->info.mlx_id != NULL)
11119517SBill.Taylor@Sun.COM free(handle->info.mlx_id);
11129517SBill.Taylor@Sun.COM
11139517SBill.Taylor@Sun.COM if (handle->info.mlx_psid != NULL)
11149517SBill.Taylor@Sun.COM free(handle->info.mlx_psid);
11159517SBill.Taylor@Sun.COM
11169517SBill.Taylor@Sun.COM if (handle->fw != NULL)
11179517SBill.Taylor@Sun.COM free(handle->fw);
11189517SBill.Taylor@Sun.COM free(handle);
11199517SBill.Taylor@Sun.COM }
11209517SBill.Taylor@Sun.COM
11219517SBill.Taylor@Sun.COM if (flashdev->ident->vid != NULL)
11229517SBill.Taylor@Sun.COM free(flashdev->ident->vid);
11239517SBill.Taylor@Sun.COM
11249517SBill.Taylor@Sun.COM if (flashdev->ident->revid != NULL)
11259517SBill.Taylor@Sun.COM free(flashdev->ident->revid);
11269517SBill.Taylor@Sun.COM
11279517SBill.Taylor@Sun.COM return (FWFLASH_SUCCESS);
11289517SBill.Taylor@Sun.COM }
11299517SBill.Taylor@Sun.COM
11309517SBill.Taylor@Sun.COM
11319517SBill.Taylor@Sun.COM /*
11329517SBill.Taylor@Sun.COM * Driver read/write ioctl calls.
11339517SBill.Taylor@Sun.COM */
11349517SBill.Taylor@Sun.COM static int
cnx_read_ioctl(ib_cnx_encap_ident_t * hdl,hermon_flash_ioctl_t * info)11359517SBill.Taylor@Sun.COM cnx_read_ioctl(ib_cnx_encap_ident_t *hdl, hermon_flash_ioctl_t *info)
11369517SBill.Taylor@Sun.COM {
11379517SBill.Taylor@Sun.COM int ret;
11389517SBill.Taylor@Sun.COM
11399517SBill.Taylor@Sun.COM #ifdef CNX_DEBUG
11409517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_read_ioctl: fd %d af_type 0x%x af_addr 0x%x "
11419517SBill.Taylor@Sun.COM "af_sector_num(0x%x)\n", hdl->fd, info->af_type,
11429517SBill.Taylor@Sun.COM info->af_addr, info->af_sector_num);
11439517SBill.Taylor@Sun.COM #endif
11449517SBill.Taylor@Sun.COM
11459517SBill.Taylor@Sun.COM errno = 0;
11469517SBill.Taylor@Sun.COM ret = ioctl(hdl->fd, HERMON_IOCTL_FLASH_READ, info);
11479517SBill.Taylor@Sun.COM if (ret != 0) {
11489517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("HERMON_IOCTL_FLASH_READ failed "
11499517SBill.Taylor@Sun.COM "(%s)\n"), strerror(errno));
11509517SBill.Taylor@Sun.COM }
11519517SBill.Taylor@Sun.COM return (ret);
11529517SBill.Taylor@Sun.COM }
11539517SBill.Taylor@Sun.COM
11549517SBill.Taylor@Sun.COM static int
cnx_write_ioctl(ib_cnx_encap_ident_t * hdl,hermon_flash_ioctl_t * info)11559517SBill.Taylor@Sun.COM cnx_write_ioctl(ib_cnx_encap_ident_t *hdl, hermon_flash_ioctl_t *info)
11569517SBill.Taylor@Sun.COM {
11579517SBill.Taylor@Sun.COM int ret;
11589517SBill.Taylor@Sun.COM
11599517SBill.Taylor@Sun.COM #ifdef CNX_DEBUG
11609517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_write_ioctl: fd(%d) af_type(0x%x) "
11619517SBill.Taylor@Sun.COM "af_addr(0x%x) af_sector_num(0x%x) af_byte(0x%x)\n",
11629517SBill.Taylor@Sun.COM hdl->fd, info->af_type, info->af_addr, info->af_sector_num,
11639517SBill.Taylor@Sun.COM info->af_byte);
11649517SBill.Taylor@Sun.COM #endif
11659517SBill.Taylor@Sun.COM errno = 0;
11669517SBill.Taylor@Sun.COM ret = ioctl(hdl->fd, HERMON_IOCTL_FLASH_WRITE, info);
11679517SBill.Taylor@Sun.COM if (ret != 0) {
11689517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("HERMON_IOCTL_FLASH_WRITE "
11699517SBill.Taylor@Sun.COM "failed (%s)\n"), strerror(errno));
11709517SBill.Taylor@Sun.COM }
11719517SBill.Taylor@Sun.COM return (ret);
11729517SBill.Taylor@Sun.COM }
11739517SBill.Taylor@Sun.COM
11749517SBill.Taylor@Sun.COM static int
cnx_erase_sector_ioctl(ib_cnx_encap_ident_t * hdl,hermon_flash_ioctl_t * info)11759517SBill.Taylor@Sun.COM cnx_erase_sector_ioctl(ib_cnx_encap_ident_t *hdl, hermon_flash_ioctl_t *info)
11769517SBill.Taylor@Sun.COM {
11779517SBill.Taylor@Sun.COM int ret;
11789517SBill.Taylor@Sun.COM
11799517SBill.Taylor@Sun.COM #ifdef CNX_DEBUG
11809517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_erase_sector_ioctl: fd(%d) af_type(0x%x) "
11819517SBill.Taylor@Sun.COM "af_sector_num(0x%x)\n", hdl->fd, info->af_type,
11829517SBill.Taylor@Sun.COM info->af_sector_num);
11839517SBill.Taylor@Sun.COM #endif
11849517SBill.Taylor@Sun.COM errno = 0;
11859517SBill.Taylor@Sun.COM ret = ioctl(hdl->fd, HERMON_IOCTL_FLASH_ERASE, info);
11869517SBill.Taylor@Sun.COM if (ret != 0) {
11879517SBill.Taylor@Sun.COM logmsg(MSG_ERROR, gettext("HERMON_IOCTL_FLASH_ERASE "
11889517SBill.Taylor@Sun.COM "failed (%s)\n"), strerror(errno));
11899517SBill.Taylor@Sun.COM }
11909517SBill.Taylor@Sun.COM return (ret);
11919517SBill.Taylor@Sun.COM }
11929517SBill.Taylor@Sun.COM
11939517SBill.Taylor@Sun.COM /*
11949517SBill.Taylor@Sun.COM * cnx_crc16 - computes 16 bit crc of supplied buffer.
11959517SBill.Taylor@Sun.COM * image should be in network byteorder
11969517SBill.Taylor@Sun.COM * result is returned in host byteorder form
11979517SBill.Taylor@Sun.COM */
11989517SBill.Taylor@Sun.COM uint16_t
cnx_crc16(uint8_t * image,uint32_t size,int is_image)11999517SBill.Taylor@Sun.COM cnx_crc16(uint8_t *image, uint32_t size, int is_image)
12009517SBill.Taylor@Sun.COM {
12019517SBill.Taylor@Sun.COM const uint16_t poly = 0x100b;
12029517SBill.Taylor@Sun.COM uint32_t crc = 0xFFFF;
12039517SBill.Taylor@Sun.COM uint32_t word;
12049517SBill.Taylor@Sun.COM uint32_t i, j;
12059517SBill.Taylor@Sun.COM
12069517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: cnx_crc16\n");
12079517SBill.Taylor@Sun.COM
12089517SBill.Taylor@Sun.COM for (i = 0; i < size / 4; i++) {
12099517SBill.Taylor@Sun.COM word = (image[4 * i] << 24) |
12109517SBill.Taylor@Sun.COM (image[4 * i + 1] << 16) |
12119517SBill.Taylor@Sun.COM (image[4 * i + 2] << 8) |
12129517SBill.Taylor@Sun.COM (image[4 * i + 3]);
12139517SBill.Taylor@Sun.COM
12149517SBill.Taylor@Sun.COM if (is_image == CNX_HW_IMG)
12159517SBill.Taylor@Sun.COM word = MLXSWAPBITS32(word);
12169517SBill.Taylor@Sun.COM
12179517SBill.Taylor@Sun.COM for (j = 0; j < 32; j++) {
12189517SBill.Taylor@Sun.COM if (crc & 0x8000) {
12199517SBill.Taylor@Sun.COM crc = (((crc << 1) |
12209517SBill.Taylor@Sun.COM (word >> 31)) ^ poly) & 0xFFFF;
12219517SBill.Taylor@Sun.COM } else {
12229517SBill.Taylor@Sun.COM crc = ((crc << 1) | (word >> 31)) & 0xFFFF;
12239517SBill.Taylor@Sun.COM }
12249517SBill.Taylor@Sun.COM word = (word << 1) & 0xFFFFFFFF;
12259517SBill.Taylor@Sun.COM }
12269517SBill.Taylor@Sun.COM }
12279517SBill.Taylor@Sun.COM
12289517SBill.Taylor@Sun.COM for (i = 0; i < 16; i++) {
12299517SBill.Taylor@Sun.COM if (crc & 0x8000) {
12309517SBill.Taylor@Sun.COM crc = ((crc << 1) ^ poly) & 0xFFFF;
12319517SBill.Taylor@Sun.COM } else {
12329517SBill.Taylor@Sun.COM crc = (crc << 1) & 0xFFFF;
12339517SBill.Taylor@Sun.COM }
12349517SBill.Taylor@Sun.COM }
12359517SBill.Taylor@Sun.COM
12369517SBill.Taylor@Sun.COM crc = crc ^ 0xFFFF;
12379517SBill.Taylor@Sun.COM return (crc & 0xFFFF);
12389517SBill.Taylor@Sun.COM }
12399517SBill.Taylor@Sun.COM
12409517SBill.Taylor@Sun.COM static void
cnx_local_set_guid_crc_img(uint32_t offset,uint32_t guid_crc_size,uint32_t guid_crc_offset)12419517SBill.Taylor@Sun.COM cnx_local_set_guid_crc_img(uint32_t offset, uint32_t guid_crc_size,
12429517SBill.Taylor@Sun.COM uint32_t guid_crc_offset)
12439517SBill.Taylor@Sun.COM {
12449517SBill.Taylor@Sun.COM uint16_t crc;
12459517SBill.Taylor@Sun.COM uint8_t *fw_p = (uint8_t *)&verifier->fwimage[0];
12469517SBill.Taylor@Sun.COM
12479517SBill.Taylor@Sun.COM crc = htons(cnx_crc16((uint8_t *)&verifier->fwimage[offset / 4],
12489517SBill.Taylor@Sun.COM guid_crc_size, CNX_FILE_IMG));
12499517SBill.Taylor@Sun.COM
12509517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_local_set_guid_crc_img: new guid_sect crc: %x\n",
12519517SBill.Taylor@Sun.COM ntohs(crc));
12529517SBill.Taylor@Sun.COM (void) memcpy(&fw_p[offset + guid_crc_offset], &crc, 2);
12539517SBill.Taylor@Sun.COM }
12549517SBill.Taylor@Sun.COM
12559517SBill.Taylor@Sun.COM /*
12569517SBill.Taylor@Sun.COM * Address translation functions for ConnectX
12579517SBill.Taylor@Sun.COM * Variable definitions:
12589517SBill.Taylor@Sun.COM * - log2_chunk_size: log2 of a Flash chunk size
12599517SBill.Taylor@Sun.COM * - cont_addr: a contiguous image address to be translated
12609517SBill.Taylor@Sun.COM * - is_image_in_odd_chunk: When this bit is 1, it indicates the new image is
12619517SBill.Taylor@Sun.COM * stored in odd chunks of the Flash.
12629517SBill.Taylor@Sun.COM */
12639517SBill.Taylor@Sun.COM static uint32_t
cnx_cont2phys(uint32_t log2_chunk_size,uint32_t cont_addr,int type)12649517SBill.Taylor@Sun.COM cnx_cont2phys(uint32_t log2_chunk_size, uint32_t cont_addr, int type)
12659517SBill.Taylor@Sun.COM {
12669517SBill.Taylor@Sun.COM uint32_t result;
12679517SBill.Taylor@Sun.COM int is_image_in_odd_chunks;
12689517SBill.Taylor@Sun.COM
12699517SBill.Taylor@Sun.COM is_image_in_odd_chunks = type - 1;
12709517SBill.Taylor@Sun.COM
12719517SBill.Taylor@Sun.COM if (log2_chunk_size) {
12729517SBill.Taylor@Sun.COM result = cont_addr & (0xffffffff >> (32 - log2_chunk_size)) |
12739517SBill.Taylor@Sun.COM (is_image_in_odd_chunks << log2_chunk_size) |
12749517SBill.Taylor@Sun.COM (cont_addr << 1) & (0xffffffff << (log2_chunk_size + 1));
12759517SBill.Taylor@Sun.COM } else {
12769517SBill.Taylor@Sun.COM result = cont_addr;
12779517SBill.Taylor@Sun.COM }
12789517SBill.Taylor@Sun.COM
12799517SBill.Taylor@Sun.COM return (result);
12809517SBill.Taylor@Sun.COM }
12819517SBill.Taylor@Sun.COM
12829517SBill.Taylor@Sun.COM static int
cnx_read_guids(ib_cnx_encap_ident_t * handle,int type)12839517SBill.Taylor@Sun.COM cnx_read_guids(ib_cnx_encap_ident_t *handle, int type)
12849517SBill.Taylor@Sun.COM {
12859517SBill.Taylor@Sun.COM #ifdef _LITTLE_ENDIAN
12869517SBill.Taylor@Sun.COM uint32_t *ptr, tmp;
12879517SBill.Taylor@Sun.COM #endif
12889517SBill.Taylor@Sun.COM hermon_flash_ioctl_t ioctl_info;
12899517SBill.Taylor@Sun.COM uint32_t *guids;
12909517SBill.Taylor@Sun.COM uint32_t *ibmac;
12919517SBill.Taylor@Sun.COM int ret, i;
12929517SBill.Taylor@Sun.COM uint32_t nguidptr_addr;
12939517SBill.Taylor@Sun.COM union {
12949517SBill.Taylor@Sun.COM uint8_t bytes[4];
12959517SBill.Taylor@Sun.COM uint32_t dword;
12969517SBill.Taylor@Sun.COM } crc16_u;
12979517SBill.Taylor@Sun.COM uint32_t *guid_structure;
12989517SBill.Taylor@Sun.COM uint16_t crc;
12999517SBill.Taylor@Sun.COM
13009517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_read_guids\n");
13019517SBill.Taylor@Sun.COM
13029517SBill.Taylor@Sun.COM errno = 0;
13039517SBill.Taylor@Sun.COM guid_structure = (uint32_t *)calloc(1,
13049517SBill.Taylor@Sun.COM CNX_GUID_CRC16_SIZE / 4 * sizeof (uint32_t));
13059517SBill.Taylor@Sun.COM if (guid_structure == NULL) {
13069517SBill.Taylor@Sun.COM logmsg(MSG_WARN, gettext("hermon: Can't calloc guid_structure "
13079517SBill.Taylor@Sun.COM ": (%s)\n"), strerror(errno));
13089517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
13099517SBill.Taylor@Sun.COM }
13109517SBill.Taylor@Sun.COM
13119517SBill.Taylor@Sun.COM ioctl_info.af_type = HERMON_FLASH_READ_QUADLET;
13129517SBill.Taylor@Sun.COM ioctl_info.af_addr = cnx_cont2phys(handle->log2_chunk_sz,
13139517SBill.Taylor@Sun.COM CNX_NGUIDPTR_OFFSET, type);
13149517SBill.Taylor@Sun.COM
13159517SBill.Taylor@Sun.COM ret = cnx_read_ioctl(handle, &ioctl_info);
13169517SBill.Taylor@Sun.COM if (ret != 0) {
13179517SBill.Taylor@Sun.COM logmsg(MSG_WARN, gettext("hermon: Failed to read GUID Pointer "
13189517SBill.Taylor@Sun.COM "Address\n"));
13199517SBill.Taylor@Sun.COM goto out;
13209517SBill.Taylor@Sun.COM }
13219517SBill.Taylor@Sun.COM
13229517SBill.Taylor@Sun.COM guids = (uint32_t *)&handle->ibguids[0];
13239517SBill.Taylor@Sun.COM ibmac = (uint32_t *)&handle->ib_mac[0];
13249517SBill.Taylor@Sun.COM nguidptr_addr = cnx_cont2phys(handle->log2_chunk_sz,
13259517SBill.Taylor@Sun.COM ioctl_info.af_quadlet, type);
13269517SBill.Taylor@Sun.COM
13279517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "NGUIDPTR: 0x%08x \n", nguidptr_addr);
13289517SBill.Taylor@Sun.COM /* Read in the entire guid section in order to calculate the CRC */
13299517SBill.Taylor@Sun.COM ioctl_info.af_addr = nguidptr_addr - 0x10;
13309517SBill.Taylor@Sun.COM ioctl_info.af_type = HERMON_FLASH_READ_QUADLET;
13319517SBill.Taylor@Sun.COM
13329517SBill.Taylor@Sun.COM for (i = 0; i < CNX_GUID_CRC16_SIZE / 4; i++) {
13339517SBill.Taylor@Sun.COM ret = cnx_read_ioctl(handle, &ioctl_info);
13349517SBill.Taylor@Sun.COM if (ret != 0) {
13359517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "Failed to read guid_structure "
13369517SBill.Taylor@Sun.COM "(0x%x)\n", i);
13379517SBill.Taylor@Sun.COM goto out;
13389517SBill.Taylor@Sun.COM }
13399517SBill.Taylor@Sun.COM
13409517SBill.Taylor@Sun.COM if (i >= 4 && i < 12) {
13419517SBill.Taylor@Sun.COM guids[i - 4] = ioctl_info.af_quadlet;
13429517SBill.Taylor@Sun.COM }
13439517SBill.Taylor@Sun.COM if (i >= 12 && i < 16) {
13449517SBill.Taylor@Sun.COM ibmac[i - 12] = ioctl_info.af_quadlet;
13459517SBill.Taylor@Sun.COM }
13469517SBill.Taylor@Sun.COM
13479517SBill.Taylor@Sun.COM guid_structure[i] = ioctl_info.af_quadlet;
13489517SBill.Taylor@Sun.COM ioctl_info.af_addr += 4;
13499517SBill.Taylor@Sun.COM }
13509517SBill.Taylor@Sun.COM
13519517SBill.Taylor@Sun.COM for (i = 0; i < CNX_GUID_CRC16_SIZE / 4; i++) {
13529517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "guid_structure[%x] = 0x%08x\n", i,
13539517SBill.Taylor@Sun.COM guid_structure[i]);
13549517SBill.Taylor@Sun.COM }
13559517SBill.Taylor@Sun.COM
13569517SBill.Taylor@Sun.COM /*
13579517SBill.Taylor@Sun.COM * Check the CRC--make sure it computes.
13589517SBill.Taylor@Sun.COM */
13599517SBill.Taylor@Sun.COM
13609517SBill.Taylor@Sun.COM /* 0x12 subtracted: 0x2 for alignment, 0x10 to reach structure start */
13619517SBill.Taylor@Sun.COM ioctl_info.af_addr = nguidptr_addr + CNX_GUID_CRC16_OFFSET - 0x12;
13629517SBill.Taylor@Sun.COM ioctl_info.af_type = HERMON_FLASH_READ_QUADLET;
13639517SBill.Taylor@Sun.COM
13649517SBill.Taylor@Sun.COM ret = cnx_read_ioctl(handle, &ioctl_info);
13659517SBill.Taylor@Sun.COM if (ret != 0) {
13669517SBill.Taylor@Sun.COM logmsg(MSG_WARN, gettext("hermon: Failed to read guid crc "
13679517SBill.Taylor@Sun.COM "at 0x%x\n"), ioctl_info.af_addr);
13689517SBill.Taylor@Sun.COM goto out;
13699517SBill.Taylor@Sun.COM }
13709517SBill.Taylor@Sun.COM
13719517SBill.Taylor@Sun.COM crc16_u.dword = ioctl_info.af_quadlet;
13729517SBill.Taylor@Sun.COM crc = cnx_crc16((uint8_t *)guid_structure, CNX_GUID_CRC16_SIZE,
13739517SBill.Taylor@Sun.COM CNX_HW_IMG);
13749517SBill.Taylor@Sun.COM
13759517SBill.Taylor@Sun.COM if (crc != crc16_u.dword) {
13769517SBill.Taylor@Sun.COM logmsg(MSG_WARN, gettext("hermon: calculated crc16: 0x%x "
13779517SBill.Taylor@Sun.COM "differs from GUID section 0x%x\n"), crc, crc16_u.dword);
13789517SBill.Taylor@Sun.COM } else {
13799517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: calculated crc16: 0x%x MATCHES with "
13809517SBill.Taylor@Sun.COM "GUID section 0x%x\n", crc, crc16_u.dword);
13819517SBill.Taylor@Sun.COM }
13829517SBill.Taylor@Sun.COM
13839517SBill.Taylor@Sun.COM #ifdef _LITTLE_ENDIAN
13849517SBill.Taylor@Sun.COM /*
13859517SBill.Taylor@Sun.COM * guids are read as pairs of 32 bit host byteorder values and treated
13869517SBill.Taylor@Sun.COM * by callers as 64 bit values. So swap each pair of 32 bit values
13879517SBill.Taylor@Sun.COM * to make them correct
13889517SBill.Taylor@Sun.COM */
13899517SBill.Taylor@Sun.COM ptr = (uint32_t *)guids;
13909517SBill.Taylor@Sun.COM for (ret = 0; ret < 8; ret += 2) {
13919517SBill.Taylor@Sun.COM tmp = ptr[ret];
13929517SBill.Taylor@Sun.COM ptr[ret] = ptr[ret+1];
13939517SBill.Taylor@Sun.COM ptr[ret+1] = tmp;
13949517SBill.Taylor@Sun.COM }
13959517SBill.Taylor@Sun.COM ptr = (uint32_t *)&handle->ib_mac[0];
13969517SBill.Taylor@Sun.COM for (ret = 0; ret < 4; ret += 2) {
13979517SBill.Taylor@Sun.COM tmp = ptr[ret];
13989517SBill.Taylor@Sun.COM ptr[ret] = ptr[ret+1];
13999517SBill.Taylor@Sun.COM ptr[ret+1] = tmp;
14009517SBill.Taylor@Sun.COM }
14019517SBill.Taylor@Sun.COM #endif
14029517SBill.Taylor@Sun.COM ret = FWFLASH_SUCCESS;
14039517SBill.Taylor@Sun.COM
14049517SBill.Taylor@Sun.COM out:
14059517SBill.Taylor@Sun.COM free(guid_structure);
14069517SBill.Taylor@Sun.COM return (ret);
14079517SBill.Taylor@Sun.COM }
14089517SBill.Taylor@Sun.COM
14099517SBill.Taylor@Sun.COM static int
cnx_find_magic_n_chnk_sz(ib_cnx_encap_ident_t * handle,int type)14109517SBill.Taylor@Sun.COM cnx_find_magic_n_chnk_sz(ib_cnx_encap_ident_t *handle, int type)
14119517SBill.Taylor@Sun.COM {
14129517SBill.Taylor@Sun.COM int i, found = 0;
14139517SBill.Taylor@Sun.COM uint32_t addr;
14149517SBill.Taylor@Sun.COM uint32_t boot_addresses[] =
14159517SBill.Taylor@Sun.COM {0, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000};
14169517SBill.Taylor@Sun.COM
14179517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_find_magic_n_chnk_sz\n");
14189517SBill.Taylor@Sun.COM
14199517SBill.Taylor@Sun.COM switch (type) {
14209517SBill.Taylor@Sun.COM case FWFLASH_IB_STATE_IMAGE_PRI:
14219517SBill.Taylor@Sun.COM addr = 0;
14229517SBill.Taylor@Sun.COM if (cnx_check_for_magic_pattern(handle, addr) !=
14239517SBill.Taylor@Sun.COM FWFLASH_SUCCESS) {
14249517SBill.Taylor@Sun.COM goto err;
14259517SBill.Taylor@Sun.COM }
14269517SBill.Taylor@Sun.COM break;
14279517SBill.Taylor@Sun.COM
14289517SBill.Taylor@Sun.COM case FWFLASH_IB_STATE_IMAGE_SEC:
14299517SBill.Taylor@Sun.COM for (i = 1; i < 6; i++) {
14309517SBill.Taylor@Sun.COM addr = boot_addresses[i];
14319517SBill.Taylor@Sun.COM if (cnx_check_for_magic_pattern(handle, addr) ==
14329517SBill.Taylor@Sun.COM FWFLASH_SUCCESS) {
14339517SBill.Taylor@Sun.COM found = 1;
14349517SBill.Taylor@Sun.COM break;
14359517SBill.Taylor@Sun.COM }
14369517SBill.Taylor@Sun.COM }
14379517SBill.Taylor@Sun.COM if (!found) {
14389517SBill.Taylor@Sun.COM goto err;
14399517SBill.Taylor@Sun.COM }
14409517SBill.Taylor@Sun.COM break;
14419517SBill.Taylor@Sun.COM
14429517SBill.Taylor@Sun.COM default:
14439517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_find_magic_pattern: unknown type\n");
14449517SBill.Taylor@Sun.COM goto err;
14459517SBill.Taylor@Sun.COM }
14469517SBill.Taylor@Sun.COM
14479517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "magic_pattern found at addr %x\n", addr);
14489517SBill.Taylor@Sun.COM handle->img2_start_addr = addr;
14499517SBill.Taylor@Sun.COM
14509517SBill.Taylor@Sun.COM handle->log2_chunk_sz = cnx_get_log2_chunk_size_f_hdl(handle, type);
14519517SBill.Taylor@Sun.COM if (handle->log2_chunk_sz == 0) {
14529517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "no chunk size found for type %x. "
14539517SBill.Taylor@Sun.COM "Assuming non-failsafe burn\n", type);
14549517SBill.Taylor@Sun.COM }
14559517SBill.Taylor@Sun.COM
14569517SBill.Taylor@Sun.COM handle->fw_sz = cnx_get_image_size_f_hdl(handle, type);
14579517SBill.Taylor@Sun.COM if (handle->fw_sz == 0) {
14589517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "no fw size found for type %x. \n", type);
14599517SBill.Taylor@Sun.COM }
14609517SBill.Taylor@Sun.COM handle->state |= type;
14619517SBill.Taylor@Sun.COM
14629517SBill.Taylor@Sun.COM return (FWFLASH_SUCCESS);
14639517SBill.Taylor@Sun.COM err:
14649517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "no magic_pattern found for type %x\n", type);
14659517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
14669517SBill.Taylor@Sun.COM }
14679517SBill.Taylor@Sun.COM
14689517SBill.Taylor@Sun.COM static int
cnx_check_for_magic_pattern(ib_cnx_encap_ident_t * handle,uint32_t addr)14699517SBill.Taylor@Sun.COM cnx_check_for_magic_pattern(ib_cnx_encap_ident_t *handle, uint32_t addr)
14709517SBill.Taylor@Sun.COM {
14719517SBill.Taylor@Sun.COM int i;
14729517SBill.Taylor@Sun.COM hermon_flash_ioctl_t ioctl_info;
14739517SBill.Taylor@Sun.COM int magic_pattern_buf[4];
14749517SBill.Taylor@Sun.COM
14759517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_check_for_magic_pattern\n");
14769517SBill.Taylor@Sun.COM
14779517SBill.Taylor@Sun.COM ioctl_info.af_type = HERMON_FLASH_READ_QUADLET;
14789517SBill.Taylor@Sun.COM
14799517SBill.Taylor@Sun.COM for (i = 0; i < 4; i++) {
14809517SBill.Taylor@Sun.COM ioctl_info.af_addr = addr + (i * sizeof (uint32_t));
14819517SBill.Taylor@Sun.COM if (cnx_read_ioctl(handle, &ioctl_info) != 0) {
14829517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "\nFailed to read magic pattern\n");
14839517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
14849517SBill.Taylor@Sun.COM }
14859517SBill.Taylor@Sun.COM
14869517SBill.Taylor@Sun.COM magic_pattern_buf[i] = ioctl_info.af_quadlet;
14879517SBill.Taylor@Sun.COM }
14889517SBill.Taylor@Sun.COM
14899517SBill.Taylor@Sun.COM return (cnx_is_magic_pattern_present(magic_pattern_buf, CNX_HW_IMG));
14909517SBill.Taylor@Sun.COM
14919517SBill.Taylor@Sun.COM }
14929517SBill.Taylor@Sun.COM
14939517SBill.Taylor@Sun.COM int
cnx_is_magic_pattern_present(int * data,int is_image)14949517SBill.Taylor@Sun.COM cnx_is_magic_pattern_present(int *data, int is_image)
14959517SBill.Taylor@Sun.COM {
14969517SBill.Taylor@Sun.COM int i;
14979517SBill.Taylor@Sun.COM int dword;
14989517SBill.Taylor@Sun.COM
14999517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_is_magic_pattern_present\n");
15009517SBill.Taylor@Sun.COM
15019517SBill.Taylor@Sun.COM for (i = 0; i < 4; i++) {
15029517SBill.Taylor@Sun.COM if (is_image == CNX_FILE_IMG)
15039517SBill.Taylor@Sun.COM dword = MLXSWAPBITS32(data[i]);
15049517SBill.Taylor@Sun.COM else
15059517SBill.Taylor@Sun.COM dword = data[i];
15069517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "local_quadlet: %08x, magic pattern: %08x\n",
15079517SBill.Taylor@Sun.COM dword, cnx_magic_pattern[i]);
15089517SBill.Taylor@Sun.COM if (dword != cnx_magic_pattern[i]) {
15099517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
15109517SBill.Taylor@Sun.COM }
15119517SBill.Taylor@Sun.COM }
15129517SBill.Taylor@Sun.COM
15139517SBill.Taylor@Sun.COM return (FWFLASH_SUCCESS);
15149517SBill.Taylor@Sun.COM }
15159517SBill.Taylor@Sun.COM
15169517SBill.Taylor@Sun.COM static uint32_t
cnx_get_log2_chunk_size_f_hdl(ib_cnx_encap_ident_t * handle,int type)15179517SBill.Taylor@Sun.COM cnx_get_log2_chunk_size_f_hdl(ib_cnx_encap_ident_t *handle, int type)
15189517SBill.Taylor@Sun.COM {
15199517SBill.Taylor@Sun.COM hermon_flash_ioctl_t ioctl_info;
15209517SBill.Taylor@Sun.COM int ret;
15219517SBill.Taylor@Sun.COM
15229517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_get_log2_chunk_size_f_hdl\n");
15239517SBill.Taylor@Sun.COM
15249517SBill.Taylor@Sun.COM /* If chunk size is already set, just return it. */
15259517SBill.Taylor@Sun.COM if (handle->log2_chunk_sz) {
15269517SBill.Taylor@Sun.COM return (handle->log2_chunk_sz);
15279517SBill.Taylor@Sun.COM }
15289517SBill.Taylor@Sun.COM
15299517SBill.Taylor@Sun.COM switch (type) {
15309517SBill.Taylor@Sun.COM case FWFLASH_IB_STATE_IMAGE_PRI:
15319517SBill.Taylor@Sun.COM ioctl_info.af_addr = CNX_CHUNK_SIZE_OFFSET;
15329517SBill.Taylor@Sun.COM break;
15339517SBill.Taylor@Sun.COM case FWFLASH_IB_STATE_IMAGE_SEC:
15349517SBill.Taylor@Sun.COM ioctl_info.af_addr =
15359517SBill.Taylor@Sun.COM handle->img2_start_addr + CNX_CHUNK_SIZE_OFFSET;
15369517SBill.Taylor@Sun.COM break;
15379517SBill.Taylor@Sun.COM default:
15389517SBill.Taylor@Sun.COM logmsg(MSG_INFO,
15399517SBill.Taylor@Sun.COM "cnx_get_log2_chunk_size_f_hdl: unknown type\n");
15409517SBill.Taylor@Sun.COM return (0);
15419517SBill.Taylor@Sun.COM }
15429517SBill.Taylor@Sun.COM
15439517SBill.Taylor@Sun.COM ioctl_info.af_type = HERMON_FLASH_READ_QUADLET;
15449517SBill.Taylor@Sun.COM
15459517SBill.Taylor@Sun.COM ret = cnx_read_ioctl(handle, &ioctl_info);
15469517SBill.Taylor@Sun.COM if (ret != 0) {
15479517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "\nFailed to read chunk size\n");
15489517SBill.Taylor@Sun.COM return (0);
15499517SBill.Taylor@Sun.COM }
15509517SBill.Taylor@Sun.COM
15519517SBill.Taylor@Sun.COM return (cnx_get_log2_chunk_size(ioctl_info.af_quadlet));
15529517SBill.Taylor@Sun.COM }
15539517SBill.Taylor@Sun.COM
15549517SBill.Taylor@Sun.COM
15559517SBill.Taylor@Sun.COM static uint32_t
cnx_get_log2_chunk_size(uint32_t chunk_size_word)15569517SBill.Taylor@Sun.COM cnx_get_log2_chunk_size(uint32_t chunk_size_word)
15579517SBill.Taylor@Sun.COM {
15589517SBill.Taylor@Sun.COM uint8_t checksum;
15599517SBill.Taylor@Sun.COM uint32_t log2_chunk_size;
15609517SBill.Taylor@Sun.COM
15619517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_get_log2_chunk_size: chunk_size_word:"
15629517SBill.Taylor@Sun.COM " 0x%x\n", chunk_size_word);
15639517SBill.Taylor@Sun.COM
15649517SBill.Taylor@Sun.COM checksum =
15659517SBill.Taylor@Sun.COM (chunk_size_word & 0xff) +
15669517SBill.Taylor@Sun.COM ((chunk_size_word >> 8) & 0xff) +
15679517SBill.Taylor@Sun.COM ((chunk_size_word >> 16) & 0xff) +
15689517SBill.Taylor@Sun.COM ((chunk_size_word >> 24) & 0xff);
15699517SBill.Taylor@Sun.COM
15709517SBill.Taylor@Sun.COM if (checksum != 0) {
15719517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "Corrupted chunk size checksum\n");
15729517SBill.Taylor@Sun.COM return (0);
15739517SBill.Taylor@Sun.COM }
15749517SBill.Taylor@Sun.COM
15759517SBill.Taylor@Sun.COM if (chunk_size_word & 0x8) {
15769517SBill.Taylor@Sun.COM log2_chunk_size = (chunk_size_word & 0x7) + 16;
15779517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "log2 chunk size: 0x%x\n", log2_chunk_size);
15789517SBill.Taylor@Sun.COM return (log2_chunk_size);
15799517SBill.Taylor@Sun.COM } else {
15809517SBill.Taylor@Sun.COM return (0);
15819517SBill.Taylor@Sun.COM }
15829517SBill.Taylor@Sun.COM }
15839517SBill.Taylor@Sun.COM
15849517SBill.Taylor@Sun.COM static uint32_t
cnx_get_image_size_f_hdl(ib_cnx_encap_ident_t * handle,int type)15859517SBill.Taylor@Sun.COM cnx_get_image_size_f_hdl(ib_cnx_encap_ident_t *handle, int type)
15869517SBill.Taylor@Sun.COM {
15879517SBill.Taylor@Sun.COM hermon_flash_ioctl_t ioctl_info;
15889517SBill.Taylor@Sun.COM int ret;
15899517SBill.Taylor@Sun.COM
15909517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_get_image_size_f_hdl\n");
15919517SBill.Taylor@Sun.COM
15929517SBill.Taylor@Sun.COM ioctl_info.af_addr = cnx_cont2phys(handle->log2_chunk_sz,
15939517SBill.Taylor@Sun.COM CNX_IMG_SIZE_OFFSET, type);
15949517SBill.Taylor@Sun.COM ioctl_info.af_type = HERMON_FLASH_READ_QUADLET;
15959517SBill.Taylor@Sun.COM
15969517SBill.Taylor@Sun.COM ret = cnx_read_ioctl(handle, &ioctl_info);
15979517SBill.Taylor@Sun.COM if (ret != 0) {
15989517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "Failed to read image size\n");
15999517SBill.Taylor@Sun.COM return (0);
16009517SBill.Taylor@Sun.COM }
16019517SBill.Taylor@Sun.COM
16029517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "Image Size: 0x%x\n", ioctl_info.af_quadlet);
16039517SBill.Taylor@Sun.COM
16049517SBill.Taylor@Sun.COM return (ioctl_info.af_quadlet);
16059517SBill.Taylor@Sun.COM }
16069517SBill.Taylor@Sun.COM
16079517SBill.Taylor@Sun.COM static int
cnx_get_image_info(ib_cnx_encap_ident_t * handle)16089517SBill.Taylor@Sun.COM cnx_get_image_info(ib_cnx_encap_ident_t *handle)
16099517SBill.Taylor@Sun.COM {
16109517SBill.Taylor@Sun.COM uint32_t ii_ptr_addr;
16119517SBill.Taylor@Sun.COM uint32_t ii_size;
16129517SBill.Taylor@Sun.COM int *buf;
16139517SBill.Taylor@Sun.COM int i, type;
16149517SBill.Taylor@Sun.COM hermon_flash_ioctl_t ioctl_info;
16159517SBill.Taylor@Sun.COM
16169517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "cnx_get_image_info: state %x\n", handle->state);
16179517SBill.Taylor@Sun.COM
16189517SBill.Taylor@Sun.COM type = handle->state &
16199517SBill.Taylor@Sun.COM (FWFLASH_IB_STATE_IMAGE_PRI | FWFLASH_IB_STATE_IMAGE_SEC);
16209517SBill.Taylor@Sun.COM
16219517SBill.Taylor@Sun.COM /* Get the image info pointer */
16229517SBill.Taylor@Sun.COM ioctl_info.af_addr = cnx_cont2phys(handle->log2_chunk_sz,
16239517SBill.Taylor@Sun.COM CNX_IMG_INF_PTR_OFFSET, type);
16249517SBill.Taylor@Sun.COM ioctl_info.af_type = HERMON_FLASH_READ_QUADLET;
16259517SBill.Taylor@Sun.COM
16269517SBill.Taylor@Sun.COM if (cnx_read_ioctl(handle, &ioctl_info) != FWFLASH_SUCCESS) {
16279517SBill.Taylor@Sun.COM logmsg(MSG_WARN, gettext("hermon: Failed to read image info "
16289517SBill.Taylor@Sun.COM "Address\n"));
16299517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
16309517SBill.Taylor@Sun.COM }
16319517SBill.Taylor@Sun.COM ii_ptr_addr = ioctl_info.af_quadlet & 0xffffff;
16329517SBill.Taylor@Sun.COM
16339517SBill.Taylor@Sun.COM /* Get the image info size, a negative offset from the image info ptr */
16349517SBill.Taylor@Sun.COM ioctl_info.af_addr = cnx_cont2phys(handle->log2_chunk_sz,
16359517SBill.Taylor@Sun.COM ii_ptr_addr + CNX_IMG_INF_SZ_OFFSET, type);
16369517SBill.Taylor@Sun.COM ioctl_info.af_type = HERMON_FLASH_READ_QUADLET;
16379517SBill.Taylor@Sun.COM
16389517SBill.Taylor@Sun.COM if (cnx_read_ioctl(handle, &ioctl_info) != FWFLASH_SUCCESS) {
16399517SBill.Taylor@Sun.COM logmsg(MSG_WARN, gettext("hermon: Failed to read image info "
16409517SBill.Taylor@Sun.COM "size\n"));
16419517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
16429517SBill.Taylor@Sun.COM }
16439517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: ImageInfo Sz: 0x%x\n", ioctl_info.af_quadlet);
16449517SBill.Taylor@Sun.COM
16459517SBill.Taylor@Sun.COM ii_size = ioctl_info.af_quadlet;
16469517SBill.Taylor@Sun.COM /* size is in dwords--convert it to bytes */
16479517SBill.Taylor@Sun.COM ii_size *= 4;
16489517SBill.Taylor@Sun.COM
16499517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: ii_ptr_addr: 0x%x ii_size: 0x%x\n",
16509517SBill.Taylor@Sun.COM ii_ptr_addr, ii_size);
16519517SBill.Taylor@Sun.COM
16529517SBill.Taylor@Sun.COM buf = (int *)calloc(1, ii_size);
16539517SBill.Taylor@Sun.COM
16549517SBill.Taylor@Sun.COM ioctl_info.af_addr = cnx_cont2phys(handle->log2_chunk_sz,
16559517SBill.Taylor@Sun.COM ii_ptr_addr, type);
16569517SBill.Taylor@Sun.COM ioctl_info.af_type = HERMON_FLASH_READ_QUADLET;
16579517SBill.Taylor@Sun.COM
16589517SBill.Taylor@Sun.COM for (i = 0; i < ii_size/4; i++) {
16599517SBill.Taylor@Sun.COM if (cnx_read_ioctl(handle, &ioctl_info) != FWFLASH_SUCCESS) {
16609517SBill.Taylor@Sun.COM logmsg(MSG_WARN, gettext("hermon: Failed to read "
16619517SBill.Taylor@Sun.COM "image info (0x%x)\n"), i);
16629517SBill.Taylor@Sun.COM free(buf);
16639517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
16649517SBill.Taylor@Sun.COM }
16659517SBill.Taylor@Sun.COM
16669517SBill.Taylor@Sun.COM buf[i] = ioctl_info.af_quadlet;
16679517SBill.Taylor@Sun.COM ioctl_info.af_addr += 4;
16689517SBill.Taylor@Sun.COM }
16699517SBill.Taylor@Sun.COM
16709517SBill.Taylor@Sun.COM /* Parse the image info section */
16719517SBill.Taylor@Sun.COM if (cnx_parse_img_info(buf, ii_size, &handle->hwfw_img_info,
16729517SBill.Taylor@Sun.COM CNX_HW_IMG) != FWFLASH_SUCCESS) {
16739517SBill.Taylor@Sun.COM logmsg(MSG_WARN, gettext("hermon: Failed to parse Image Info "
16749517SBill.Taylor@Sun.COM "section\n"));
16759517SBill.Taylor@Sun.COM free(buf);
16769517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
16779517SBill.Taylor@Sun.COM }
16789517SBill.Taylor@Sun.COM
16799517SBill.Taylor@Sun.COM free(buf);
16809517SBill.Taylor@Sun.COM return (FWFLASH_SUCCESS);
16819517SBill.Taylor@Sun.COM }
16829517SBill.Taylor@Sun.COM
16839517SBill.Taylor@Sun.COM int
cnx_parse_img_info(int * buf,uint32_t byte_size,cnx_img_info_t * img_info,int is_image)16849517SBill.Taylor@Sun.COM cnx_parse_img_info(int *buf, uint32_t byte_size, cnx_img_info_t *img_info,
16859517SBill.Taylor@Sun.COM int is_image)
16869517SBill.Taylor@Sun.COM {
16879517SBill.Taylor@Sun.COM uint32_t *p;
16889517SBill.Taylor@Sun.COM uint32_t offs = 0;
16899517SBill.Taylor@Sun.COM uint32_t tag_num = 0;
16909517SBill.Taylor@Sun.COM int end_found = 0;
16919517SBill.Taylor@Sun.COM uint32_t tag_size, tag_id;
16929517SBill.Taylor@Sun.COM uint32_t tmp;
16939517SBill.Taylor@Sun.COM const char *str;
16949517SBill.Taylor@Sun.COM int i;
16959517SBill.Taylor@Sun.COM
16969517SBill.Taylor@Sun.COM p = (uint32_t *)buf;
16979517SBill.Taylor@Sun.COM
16989517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "hermon: cnx_parse_img_info\n");
16999517SBill.Taylor@Sun.COM
17009517SBill.Taylor@Sun.COM while (!end_found && (offs < byte_size)) {
17019517SBill.Taylor@Sun.COM if (is_image == CNX_FILE_IMG) {
17029517SBill.Taylor@Sun.COM tag_size = ntohl(*p) & 0xffffff;
17039517SBill.Taylor@Sun.COM tag_id = ntohl(*p) >> 24;
17049517SBill.Taylor@Sun.COM tmp = ntohl(*(p + 1));
17059517SBill.Taylor@Sun.COM } else {
17069517SBill.Taylor@Sun.COM tag_size = ((*p) & 0xffffff);
17079517SBill.Taylor@Sun.COM tag_id = ((*p) >> 24);
17089517SBill.Taylor@Sun.COM tmp = (*(p + 1));
17099517SBill.Taylor@Sun.COM }
17109517SBill.Taylor@Sun.COM
17119517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "tag_id: %d tag_size: %d\n", tag_id, tag_size);
17129517SBill.Taylor@Sun.COM
17139517SBill.Taylor@Sun.COM if ((offs + tag_size) > byte_size) {
17149517SBill.Taylor@Sun.COM logmsg(MSG_WARN, gettext("hermon: Image Info section "
17159517SBill.Taylor@Sun.COM "corrupted: Tag# %d - tag_id %d, size %d exceeds "
17169517SBill.Taylor@Sun.COM "info section size (%d bytes)"), tag_num, tag_id,
17179517SBill.Taylor@Sun.COM tag_size, byte_size);
17189517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
17199517SBill.Taylor@Sun.COM }
17209517SBill.Taylor@Sun.COM
17219517SBill.Taylor@Sun.COM switch (tag_id) {
17229517SBill.Taylor@Sun.COM case CNX_FW_VER:
17239517SBill.Taylor@Sun.COM if (tag_size != CNX_FW_VER_SZ) {
17249517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "ERROR: tag_id: %d tag_size: "
17259517SBill.Taylor@Sun.COM "%d expected sz %d\n", tag_id, tag_size,
17269517SBill.Taylor@Sun.COM CNX_FW_VER_SZ);
17279517SBill.Taylor@Sun.COM }
17289517SBill.Taylor@Sun.COM tmp = (tmp & CNX_MASK_FW_VER_MAJ) >> 16;
17299517SBill.Taylor@Sun.COM img_info->fw_rev.major = tmp;
17309517SBill.Taylor@Sun.COM if (is_image == CNX_FILE_IMG)
17319517SBill.Taylor@Sun.COM tmp = ntohl(*(p + 2));
17329517SBill.Taylor@Sun.COM else
17339517SBill.Taylor@Sun.COM tmp = (*(p + 2));
17349517SBill.Taylor@Sun.COM img_info->fw_rev.minor =
17359517SBill.Taylor@Sun.COM (tmp & CNX_MASK_FW_VER_MIN)>> 16;
17369517SBill.Taylor@Sun.COM img_info->fw_rev.subminor =
17379517SBill.Taylor@Sun.COM tmp & CNX_MASK_FW_VER_SUBMIN;
17389517SBill.Taylor@Sun.COM
173910618SShantkumar.Hiremath@Sun.COM logmsg(MSG_INFO, "FW_VER: %d.%d.%03d\n",
17409517SBill.Taylor@Sun.COM img_info->fw_rev.major, img_info->fw_rev.minor,
17419517SBill.Taylor@Sun.COM img_info->fw_rev.subminor);
17429517SBill.Taylor@Sun.COM break;
17439517SBill.Taylor@Sun.COM
17449517SBill.Taylor@Sun.COM case CNX_FW_BUILD_TIME:
17459517SBill.Taylor@Sun.COM if (tag_size != CNX_FW_BUILD_TIME_SZ) {
17469517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "ERROR: tag_id: %d tag_size: "
17479517SBill.Taylor@Sun.COM "%d expected sz %d\n", tag_id, tag_size,
17489517SBill.Taylor@Sun.COM CNX_FW_BUILD_TIME_SZ);
17499517SBill.Taylor@Sun.COM }
17509517SBill.Taylor@Sun.COM img_info->fw_buildtime.hour =
17519517SBill.Taylor@Sun.COM (tmp & CNX_MASK_FW_BUILD_HOUR) >> 16;
17529517SBill.Taylor@Sun.COM img_info->fw_buildtime.minute =
17539517SBill.Taylor@Sun.COM (tmp & CNX_MASK_FW_BUILD_MIN) >> 8;
17549517SBill.Taylor@Sun.COM img_info->fw_buildtime.second =
17559517SBill.Taylor@Sun.COM (tmp & CNX_MASK_FW_BUILD_SEC);
17569517SBill.Taylor@Sun.COM
17579517SBill.Taylor@Sun.COM if (is_image == CNX_FILE_IMG)
17589517SBill.Taylor@Sun.COM tmp = ntohl(*(p + 2));
17599517SBill.Taylor@Sun.COM else
17609517SBill.Taylor@Sun.COM tmp = (*(p + 2));
17619517SBill.Taylor@Sun.COM
17629517SBill.Taylor@Sun.COM img_info->fw_buildtime.year =
17639517SBill.Taylor@Sun.COM (tmp & CNX_MASK_FW_BUILD_YEAR) >> 16;
17649517SBill.Taylor@Sun.COM img_info->fw_buildtime.month =
17659517SBill.Taylor@Sun.COM (tmp & CNX_MASK_FW_BUILD_MON) >> 8;
17669517SBill.Taylor@Sun.COM img_info->fw_buildtime.day =
17679517SBill.Taylor@Sun.COM (tmp & CNX_MASK_FW_BUILD_DAY);
17689517SBill.Taylor@Sun.COM
17699517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "Build TIME: %d:%d:%d %d:%d:%d\n",
17709517SBill.Taylor@Sun.COM img_info->fw_buildtime.year,
17719517SBill.Taylor@Sun.COM img_info->fw_buildtime.month,
17729517SBill.Taylor@Sun.COM img_info->fw_buildtime.day,
17739517SBill.Taylor@Sun.COM img_info->fw_buildtime.hour,
17749517SBill.Taylor@Sun.COM img_info->fw_buildtime.minute,
17759517SBill.Taylor@Sun.COM img_info->fw_buildtime.second);
17769517SBill.Taylor@Sun.COM break;
17779517SBill.Taylor@Sun.COM
17789517SBill.Taylor@Sun.COM case CNX_DEV_TYPE:
17799517SBill.Taylor@Sun.COM if (tag_size != CNX_DEV_TYPE_SZ) {
17809517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "ERROR: tag_id: %d tag_size: "
17819517SBill.Taylor@Sun.COM "%d expected sz %d\n", tag_id, tag_size,
17829517SBill.Taylor@Sun.COM CNX_DEV_TYPE_SZ);
17839517SBill.Taylor@Sun.COM }
17849517SBill.Taylor@Sun.COM img_info->dev_id = tmp & CNX_MASK_DEV_TYPE_ID;
17859517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "DEV_TYPE: %d\n", img_info->dev_id);
17869517SBill.Taylor@Sun.COM break;
17879517SBill.Taylor@Sun.COM
17889517SBill.Taylor@Sun.COM case CNX_VSD_VENDOR_ID:
17899517SBill.Taylor@Sun.COM if (tag_size != CNX_VSD_VENDOR_ID_SZ) {
17909517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "ERROR: tag_id: %d tag_size: "
17919517SBill.Taylor@Sun.COM "%d expected sz %d\n", tag_id, tag_size,
17929517SBill.Taylor@Sun.COM CNX_VSD_VENDOR_ID_SZ);
17939517SBill.Taylor@Sun.COM }
17949517SBill.Taylor@Sun.COM img_info->vsd_vendor_id = tmp & CNX_MASK_VSD_VENDORID;
17959517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "VSD Vendor ID: 0x%lX\n",
17969517SBill.Taylor@Sun.COM img_info->vsd_vendor_id);
17979517SBill.Taylor@Sun.COM break;
17989517SBill.Taylor@Sun.COM
17999517SBill.Taylor@Sun.COM case CNX_PSID:
18009517SBill.Taylor@Sun.COM if (tag_size != CNX_PSID_SZ) {
18019517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "ERROR: tag_id: %d tag_size: "
18029517SBill.Taylor@Sun.COM "%d expected sz %d\n", tag_id, tag_size,
18039517SBill.Taylor@Sun.COM CNX_PSID_SZ);
18049517SBill.Taylor@Sun.COM }
18059517SBill.Taylor@Sun.COM str = (const char *)p;
18069517SBill.Taylor@Sun.COM str += 4;
18079517SBill.Taylor@Sun.COM
18089517SBill.Taylor@Sun.COM for (i = 0; i < CNX_PSID_SZ; i++)
18099517SBill.Taylor@Sun.COM img_info->psid[i] = str[i];
18109517SBill.Taylor@Sun.COM
18119517SBill.Taylor@Sun.COM #ifdef _LITTLE_ENDIAN
18129517SBill.Taylor@Sun.COM if (is_image == CNX_HW_IMG) {
18139517SBill.Taylor@Sun.COM for (i = 0; i < CNX_PSID_SZ; i += 4) {
18149517SBill.Taylor@Sun.COM img_info->psid[i+3] = str[i];
18159517SBill.Taylor@Sun.COM img_info->psid[i+2] = str[i+1];
18169517SBill.Taylor@Sun.COM img_info->psid[i+1] = str[i+2];
18179517SBill.Taylor@Sun.COM img_info->psid[i] = str[i+3];
18189517SBill.Taylor@Sun.COM }
18199517SBill.Taylor@Sun.COM }
18209517SBill.Taylor@Sun.COM #endif
18219517SBill.Taylor@Sun.COM
18229517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "PSID: %s\n", img_info->psid);
18239517SBill.Taylor@Sun.COM break;
18249517SBill.Taylor@Sun.COM
18259517SBill.Taylor@Sun.COM case CNX_VSD:
18269517SBill.Taylor@Sun.COM if (tag_size != CNX_VSD_SZ) {
18279517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "ERROR: tag_id: %d tag_size: "
18289517SBill.Taylor@Sun.COM "%d expected sz %d\n", tag_id, tag_size,
18299517SBill.Taylor@Sun.COM CNX_VSD_SZ);
18309517SBill.Taylor@Sun.COM }
18319517SBill.Taylor@Sun.COM str = (const char *)p;
18329517SBill.Taylor@Sun.COM str += 4;
18339517SBill.Taylor@Sun.COM
18349517SBill.Taylor@Sun.COM for (i = 0; i < CNX_VSD_SZ; i++)
18359517SBill.Taylor@Sun.COM img_info->vsd[i] = str[i];
18369517SBill.Taylor@Sun.COM
18379517SBill.Taylor@Sun.COM #ifdef _LITTLE_ENDIAN
18389517SBill.Taylor@Sun.COM if (is_image == CNX_HW_IMG) {
18399517SBill.Taylor@Sun.COM for (i = 0; i < CNX_VSD_SZ; i += 4) {
18409517SBill.Taylor@Sun.COM img_info->vsd[i+3] = str[i];
18419517SBill.Taylor@Sun.COM img_info->vsd[i+2] = str[i+1];
18429517SBill.Taylor@Sun.COM img_info->vsd[i+1] = str[i+2];
18439517SBill.Taylor@Sun.COM img_info->vsd[i] = str[i+3];
18449517SBill.Taylor@Sun.COM }
18459517SBill.Taylor@Sun.COM }
18469517SBill.Taylor@Sun.COM #endif
18479517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "VSD: %s\n", img_info->vsd);
18489517SBill.Taylor@Sun.COM break;
18499517SBill.Taylor@Sun.COM
18509517SBill.Taylor@Sun.COM case CNX_END_TAG:
18519517SBill.Taylor@Sun.COM if (tag_size != CNX_END_TAG_SZ) {
18529517SBill.Taylor@Sun.COM logmsg(MSG_INFO, "ERROR: tag_id: %d tag_size: "
18539517SBill.Taylor@Sun.COM "%d expected sz %d\n", tag_id, tag_size,
18549517SBill.Taylor@Sun.COM CNX_END_TAG_SZ);
18559517SBill.Taylor@Sun.COM }
18569517SBill.Taylor@Sun.COM end_found = 1;
18579517SBill.Taylor@Sun.COM break;
18589517SBill.Taylor@Sun.COM
18599517SBill.Taylor@Sun.COM default:
18609517SBill.Taylor@Sun.COM if (tag_id > CNX_END_TAG) {
18619517SBill.Taylor@Sun.COM logmsg(MSG_WARN, gettext("Invalid img_info "
18629517SBill.Taylor@Sun.COM "tag ID %d of size %d\n"), tag_id,
18639517SBill.Taylor@Sun.COM tag_size);
18649517SBill.Taylor@Sun.COM }
18659517SBill.Taylor@Sun.COM break;
18669517SBill.Taylor@Sun.COM }
18679517SBill.Taylor@Sun.COM
18689517SBill.Taylor@Sun.COM p += (tag_size / 4) + 1;
18699517SBill.Taylor@Sun.COM offs += tag_size + 4;
18709517SBill.Taylor@Sun.COM tag_num++;
18719517SBill.Taylor@Sun.COM }
18729517SBill.Taylor@Sun.COM
18739517SBill.Taylor@Sun.COM if (offs != byte_size) {
18749517SBill.Taylor@Sun.COM logmsg(MSG_WARN, gettext("hermon: Corrupt Image Info section "
18759517SBill.Taylor@Sun.COM "in firmware image\n"));
18769517SBill.Taylor@Sun.COM if (end_found) {
18779517SBill.Taylor@Sun.COM logmsg(MSG_WARN, gettext("Info section corrupted: "
18789517SBill.Taylor@Sun.COM "Section data size is %x bytes, but end tag found "
18799517SBill.Taylor@Sun.COM "after %x bytes.\n"), byte_size, offs);
18809517SBill.Taylor@Sun.COM } else {
18819517SBill.Taylor@Sun.COM logmsg(MSG_WARN, gettext("Info section corrupted: "
18829517SBill.Taylor@Sun.COM "Section data size is %x bytes, but end tag not "
18839517SBill.Taylor@Sun.COM "found at section end.\n"), byte_size);
18849517SBill.Taylor@Sun.COM }
18859517SBill.Taylor@Sun.COM return (FWFLASH_FAILURE);
18869517SBill.Taylor@Sun.COM }
18879517SBill.Taylor@Sun.COM
18889517SBill.Taylor@Sun.COM return (FWFLASH_SUCCESS);
18899517SBill.Taylor@Sun.COM }
1890