19e39c5baSBill Taylor /*
29e39c5baSBill Taylor  * CDDL HEADER START
39e39c5baSBill Taylor  *
49e39c5baSBill Taylor  * The contents of this file are subject to the terms of the
59e39c5baSBill Taylor  * Common Development and Distribution License (the "License").
69e39c5baSBill Taylor  * You may not use this file except in compliance with the License.
79e39c5baSBill Taylor  *
89e39c5baSBill Taylor  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99e39c5baSBill Taylor  * or http://www.opensolaris.org/os/licensing.
109e39c5baSBill Taylor  * See the License for the specific language governing permissions
119e39c5baSBill Taylor  * and limitations under the License.
129e39c5baSBill Taylor  *
139e39c5baSBill Taylor  * When distributing Covered Code, include this CDDL HEADER in each
149e39c5baSBill Taylor  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159e39c5baSBill Taylor  * If applicable, add the following below this CDDL HEADER, with the
169e39c5baSBill Taylor  * fields enclosed by brackets "[]" replaced with your own identifying
179e39c5baSBill Taylor  * information: Portions Copyright [yyyy] [name of copyright owner]
189e39c5baSBill Taylor  *
199e39c5baSBill Taylor  * CDDL HEADER END
209e39c5baSBill Taylor  */
219e39c5baSBill Taylor 
229e39c5baSBill Taylor /*
23*b67a60d6SShantkumar Hiremath  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
249e39c5baSBill Taylor  */
259e39c5baSBill Taylor 
269e39c5baSBill Taylor /*
279e39c5baSBill Taylor  * ConnectX (hermon) firmware image verification plugin
289e39c5baSBill Taylor  */
299e39c5baSBill Taylor 
309e39c5baSBill Taylor #include <stdio.h>
319e39c5baSBill Taylor #include <stdlib.h>
329e39c5baSBill Taylor #include <unistd.h>
339e39c5baSBill Taylor #include <sys/types.h>
349e39c5baSBill Taylor #include <sys/stat.h>
359e39c5baSBill Taylor #include <sys/sysmacros.h>
369e39c5baSBill Taylor #include <fcntl.h>
379e39c5baSBill Taylor #include <sys/condvar.h>
389e39c5baSBill Taylor #include <string.h>
399e39c5baSBill Taylor #include <strings.h>
409e39c5baSBill Taylor 
419e39c5baSBill Taylor #include <sys/byteorder.h>
429e39c5baSBill Taylor 
439e39c5baSBill Taylor #include <libintl.h> /* for gettext(3c) */
449e39c5baSBill Taylor 
459e39c5baSBill Taylor #include <fwflash/fwflash.h>
469e39c5baSBill Taylor #include "../hdrs/hermon_ib.h"
479e39c5baSBill Taylor 
489e39c5baSBill Taylor char vendor[] = "MELLANOX\0";
499e39c5baSBill Taylor 
509e39c5baSBill Taylor extern struct vrfyplugin *verifier;
519e39c5baSBill Taylor 
529e39c5baSBill Taylor 
539e39c5baSBill Taylor /* required functions for this plugin */
549e39c5baSBill Taylor int vendorvrfy(struct devicelist *devicenode);
559e39c5baSBill Taylor 
569e39c5baSBill Taylor /* helper functions */
579e39c5baSBill Taylor static uint16_t cnx_check_hwver_img(ib_cnx_encap_ident_t *handle);
589e39c5baSBill Taylor static void cnx_flash_verify_flash_match_img(ib_cnx_encap_ident_t *handle);
599e39c5baSBill Taylor static void cnx_flash_verify_flash_pn_img(ib_cnx_encap_ident_t *handle,
609e39c5baSBill Taylor     uchar_t *psid, int psid_size);
619e39c5baSBill Taylor static uchar_t *cnx_flash_get_psid_img(ib_cnx_encap_ident_t *handle);
629e39c5baSBill Taylor static void cnx_display_fwver(ib_cnx_encap_ident_t *handle);
639e39c5baSBill Taylor static int cnx_check_guid_section();
649e39c5baSBill Taylor 
659e39c5baSBill Taylor 
669e39c5baSBill Taylor int
vendorvrfy(struct devicelist * devicenode)679e39c5baSBill Taylor vendorvrfy(struct devicelist *devicenode)
689e39c5baSBill Taylor {
699e39c5baSBill Taylor 	struct ib_cnx_encap_ident_s	*handle;
709e39c5baSBill Taylor 	uint16_t	ver;
719e39c5baSBill Taylor 
729e39c5baSBill Taylor 	logmsg(MSG_INFO, "hermon: vendorvrfy \n");
739e39c5baSBill Taylor 
749e39c5baSBill Taylor 	handle = (struct ib_cnx_encap_ident_s *)devicenode->ident->encap_ident;
759e39c5baSBill Taylor 
769e39c5baSBill Taylor 	if (CNX_I_CHECK_HANDLE(handle)) {
779e39c5baSBill Taylor 		logmsg(MSG_ERROR, gettext("hermon: Invalid Handle for "
789e39c5baSBill Taylor 		    "device %s! \n"), devicenode->access_devname);
799e39c5baSBill Taylor 		return (FWFLASH_FAILURE);
809e39c5baSBill Taylor 	}
819e39c5baSBill Taylor 
829e39c5baSBill Taylor 	/*
839e39c5baSBill Taylor 	 * NOTE verifier->fwimage is where file is read to.
849e39c5baSBill Taylor 	 */
859e39c5baSBill Taylor 	if (cnx_is_magic_pattern_present(&verifier->fwimage[0], 1) !=
869e39c5baSBill Taylor 	    FWFLASH_SUCCESS) {
879e39c5baSBill Taylor 		logmsg(MSG_ERROR, gettext("%s firmware image verifier: "
889e39c5baSBill Taylor 		    "No magic pattern found in firmware file %s \n"),
899e39c5baSBill Taylor 		    verifier->vendor, verifier->imgfile);
909e39c5baSBill Taylor 		return (FWFLASH_FAILURE);
919e39c5baSBill Taylor 	}
929e39c5baSBill Taylor 
939e39c5baSBill Taylor 	if (cnx_check_guid_section() == FWFLASH_FAILURE) {
949e39c5baSBill Taylor 		logmsg(MSG_INFO, "%s firmware image verifier: "
959e39c5baSBill Taylor 		    "Firmware Image GUID section is invalid\n",
969e39c5baSBill Taylor 		    verifier->vendor);
979e39c5baSBill Taylor 	}
989e39c5baSBill Taylor 
999e39c5baSBill Taylor 	cnx_flash_verify_flash_match_img(handle);
1009e39c5baSBill Taylor 
1019e39c5baSBill Taylor 	/* Check Hardware Rev */
1029e39c5baSBill Taylor 	ver = cnx_check_hwver_img(handle);
1039e39c5baSBill Taylor 	if (ver != 0) {
1049e39c5baSBill Taylor 		logmsg(MSG_ERROR, gettext("hermon: Firmware mismatch: "
1059e39c5baSBill Taylor 		    "ver(0x%X) hw_ver(0x%X)\n"), (ver >> 8), ver & 0xFF);
1069e39c5baSBill Taylor 		return (FWFLASH_FAILURE);
1079e39c5baSBill Taylor 	}
1089e39c5baSBill Taylor 
1099e39c5baSBill Taylor 	if (handle->hwfw_match == 0) {
110ee5d8455SShantkumar Hiremath 		int resp;
111ee5d8455SShantkumar Hiremath 
1129e39c5baSBill Taylor 		if (handle->pn_len != 0) {
1139e39c5baSBill Taylor 			/* HW VPD exist and a mismatch was found */
1149e39c5baSBill Taylor 			logmsg(MSG_ERROR, gettext("hermon: Please verify that "
1159e39c5baSBill Taylor 			    "the firmware image is intended for use with this "
1169e39c5baSBill Taylor 			    "hardware\n"));
1179e39c5baSBill Taylor 		} else {
1189e39c5baSBill Taylor 			logmsg(MSG_ERROR, gettext("hermon: Unable to verify "
1199e39c5baSBill Taylor 			    "firmware is appropriate for the hardware\n"));
1209e39c5baSBill Taylor 		}
121ee5d8455SShantkumar Hiremath 		logmsg(MSG_ERROR, gettext("Do you want to continue? (Y/N): "));
122ee5d8455SShantkumar Hiremath 		(void) fflush(stdin);
123ee5d8455SShantkumar Hiremath 		resp = getchar();
124ee5d8455SShantkumar Hiremath 		if (resp != 'Y' && resp != 'y') {
125ee5d8455SShantkumar Hiremath 			logmsg(MSG_ERROR, gettext("Not proceeding with "
126*b67a60d6SShantkumar Hiremath 			    "flash operation of %s on %s \n"),
127ee5d8455SShantkumar Hiremath 			    verifier->imgfile, devicenode->drvname);
128ee5d8455SShantkumar Hiremath 			return (FWFLASH_FAILURE);
129ee5d8455SShantkumar Hiremath 		}
130ee5d8455SShantkumar Hiremath 	} else {
131ee5d8455SShantkumar Hiremath 		logmsg(MSG_INFO, "%s firmware image verifier: HCA PSID (%s) "
132ee5d8455SShantkumar Hiremath 		    "matches firmware image %s's PSID\n", verifier->vendor,
133ee5d8455SShantkumar Hiremath 		    handle->info.mlx_psid, verifier->imgfile);
1349e39c5baSBill Taylor 
135ee5d8455SShantkumar Hiremath 		cnx_display_fwver(handle);
136ee5d8455SShantkumar Hiremath 	}
1379e39c5baSBill Taylor 
1389e39c5baSBill Taylor 	return (FWFLASH_SUCCESS);
1399e39c5baSBill Taylor }
1409e39c5baSBill Taylor 
1419e39c5baSBill Taylor static uint16_t
cnx_check_hwver_img(ib_cnx_encap_ident_t * handle)1429e39c5baSBill Taylor cnx_check_hwver_img(ib_cnx_encap_ident_t *handle)
1439e39c5baSBill Taylor {
1449e39c5baSBill Taylor 	uint8_t	hwver;
1459e39c5baSBill Taylor 	uint8_t	local_hwver;
1469e39c5baSBill Taylor 
1479e39c5baSBill Taylor 	logmsg(MSG_INFO, "hermon: verify: cnx_check_hwver_img\n");
1489e39c5baSBill Taylor 	if ((handle->state & FWFLASH_IB_STATE_IMAGE_PRI) == 0 &&
1499e39c5baSBill Taylor 	    (handle->state & FWFLASH_IB_STATE_IMAGE_SEC) == 0) {
1509e39c5baSBill Taylor 		logmsg(MSG_ERROR, gettext("hermon: Must read in image "
1519e39c5baSBill Taylor 		    "first\n"));
1529e39c5baSBill Taylor 		return (1);
1539e39c5baSBill Taylor 	}
1549e39c5baSBill Taylor 
1559e39c5baSBill Taylor 	/* Read Flash HW Version */
1569e39c5baSBill Taylor 	hwver = (uint8_t)handle->hwrev;
1579e39c5baSBill Taylor 	local_hwver = (ntohl(verifier->fwimage[CNX_HWVER_OFFSET / 4]) &
1589e39c5baSBill Taylor 	    CNX_HWVER_MASK) >> 24;
1599e39c5baSBill Taylor 
1609e39c5baSBill Taylor 	logmsg(MSG_INFO, "local_hwver: %x, hwver: %x\n", local_hwver, hwver);
1619e39c5baSBill Taylor 
1629e39c5baSBill Taylor 	if ((hwver == 0xA0 || hwver == 0x00 || hwver == 0x20) &&
1639e39c5baSBill Taylor 	    (local_hwver == 0x00 || local_hwver == 0xA0 ||
1649e39c5baSBill Taylor 	    local_hwver == 0x20)) {
1659e39c5baSBill Taylor 		logmsg(MSG_INFO, ("A0 board found.\r\n"));
1669e39c5baSBill Taylor 	} else if (hwver == 0xA1 && local_hwver == 0xA1) {
1679e39c5baSBill Taylor 		logmsg(MSG_INFO, ("A1 board found.\r\n"));
1689e39c5baSBill Taylor 	} else if (hwver == 0xA2 && local_hwver == 0xA2) {
1699e39c5baSBill Taylor 		logmsg(MSG_INFO, ("A2 board found.\r\n"));
1709e39c5baSBill Taylor 	} else if (hwver == 0xA3 && local_hwver == 0xA3) {
1719e39c5baSBill Taylor 		logmsg(MSG_INFO, ("A3 board found.\r\n"));
172*b67a60d6SShantkumar Hiremath 	} else if (hwver == 0xB0 && local_hwver == 0xB0) {
173*b67a60d6SShantkumar Hiremath 		logmsg(MSG_INFO, ("B0 board found.\r\n"));
174*b67a60d6SShantkumar Hiremath 	} else if (hwver != local_hwver) {
1759e39c5baSBill Taylor 		return ((uint16_t)(local_hwver << 8) | hwver);
1769e39c5baSBill Taylor 	}
1779e39c5baSBill Taylor 	return (0);
1789e39c5baSBill Taylor }
1799e39c5baSBill Taylor 
1809e39c5baSBill Taylor static void
cnx_display_fwver(ib_cnx_encap_ident_t * handle)1819e39c5baSBill Taylor cnx_display_fwver(ib_cnx_encap_ident_t *handle)
1829e39c5baSBill Taylor {
1839e39c5baSBill Taylor 	logmsg(MSG_INFO, "hermon: verify: cnx_display_fwver\n");
1849e39c5baSBill Taylor 
1859e39c5baSBill Taylor 	(void) fprintf(stdout, gettext("  The current HCA firmware version "
186ee5d8455SShantkumar Hiremath 	    "is    : %d.%d.%03d\n"),
1879e39c5baSBill Taylor 	    handle->hwfw_img_info.fw_rev.major,
1889e39c5baSBill Taylor 	    handle->hwfw_img_info.fw_rev.minor,
1899e39c5baSBill Taylor 	    handle->hwfw_img_info.fw_rev.subminor);
1909e39c5baSBill Taylor 	(void) fprintf(stdout, gettext("  Will be updated to HCA firmware "
191ee5d8455SShantkumar Hiremath 	    "ver of : %d.%d.%03d\n"),
1929e39c5baSBill Taylor 	    handle->file_img_info.fw_rev.major,
1939e39c5baSBill Taylor 	    handle->file_img_info.fw_rev.minor,
1949e39c5baSBill Taylor 	    handle->file_img_info.fw_rev.subminor);
1959e39c5baSBill Taylor }
1969e39c5baSBill Taylor 
1979e39c5baSBill Taylor static uchar_t *
cnx_flash_get_psid_img(ib_cnx_encap_ident_t * handle)1989e39c5baSBill Taylor cnx_flash_get_psid_img(ib_cnx_encap_ident_t *handle)
1999e39c5baSBill Taylor {
2009e39c5baSBill Taylor 	uint32_t	ii_ptr_addr;
2019e39c5baSBill Taylor 	uint32_t	ii_size;
2029e39c5baSBill Taylor 
2039e39c5baSBill Taylor 	logmsg(MSG_INFO, "hermon: verify: cnx_flash_get_psid_img\n");
2049e39c5baSBill Taylor 
2059e39c5baSBill Taylor 	/* Get the image info pointer */
2069e39c5baSBill Taylor 	ii_ptr_addr = ntohl(verifier->fwimage[CNX_IMG_INF_PTR_OFFSET / 4]);
2079e39c5baSBill Taylor 	ii_ptr_addr &= 0xffffff; /* Bits 23:0 - Image Info Data Pointer */
2089e39c5baSBill Taylor 
2099e39c5baSBill Taylor 	/* Get the image info size, a negative offset from the image info ptr */
2109e39c5baSBill Taylor 	ii_size =
2119e39c5baSBill Taylor 	    ntohl(verifier->fwimage[(ii_ptr_addr + CNX_IMG_INF_SZ_OFFSET) / 4]);
2129e39c5baSBill Taylor 	/* size is in dwords--convert it to bytes */
2139e39c5baSBill Taylor 	ii_size *= 4;
2149e39c5baSBill Taylor 
2159e39c5baSBill Taylor 	logmsg(MSG_INFO, "ImgInfo_ptr_addr: 0x%lx, ImgInfo_size: 0x%x\n",
2169e39c5baSBill Taylor 	    ii_ptr_addr, ii_size);
2179e39c5baSBill Taylor 
2189e39c5baSBill Taylor 	/* Parse the image info section */
2199e39c5baSBill Taylor 	if (cnx_parse_img_info(&verifier->fwimage[ii_ptr_addr / 4], ii_size,
2209e39c5baSBill Taylor 	    &handle->file_img_info, CNX_FILE_IMG) != FWFLASH_SUCCESS) {
2219e39c5baSBill Taylor 		logmsg(MSG_WARN, gettext("hermon: Failed to parse ImageInfo "
2229e39c5baSBill Taylor 		    "section\n"));
2239e39c5baSBill Taylor 		return (NULL);
2249e39c5baSBill Taylor 	}
2259e39c5baSBill Taylor 
2269e39c5baSBill Taylor 	return (handle->file_img_info.psid);
2279e39c5baSBill Taylor }
2289e39c5baSBill Taylor 
2299e39c5baSBill Taylor static void
cnx_flash_verify_flash_pn_img(ib_cnx_encap_ident_t * handle,uchar_t * psid,int psid_size)2309e39c5baSBill Taylor cnx_flash_verify_flash_pn_img(ib_cnx_encap_ident_t *handle, uchar_t *psid,
2319e39c5baSBill Taylor     int psid_size)
2329e39c5baSBill Taylor {
2339e39c5baSBill Taylor 	int	i;
2349e39c5baSBill Taylor 	int	no_match = 0;
2359e39c5baSBill Taylor 
2369e39c5baSBill Taylor 	logmsg(MSG_INFO, "hermon: verify: cnx_flash_verify_flash_pn_img\n");
2379e39c5baSBill Taylor 	/* verify fw matches the hardware */
2389e39c5baSBill Taylor 	if (handle->hwfw_match == 1) {
2399e39c5baSBill Taylor 		/* already been verified */
2409e39c5baSBill Taylor 		return;
2419e39c5baSBill Taylor 	}
2429e39c5baSBill Taylor 
2439e39c5baSBill Taylor 	/* find the PSID from FW in the mlx table */
2449e39c5baSBill Taylor 	for (i = 0; i < MLX_MAX_ID; i++) {
2459e39c5baSBill Taylor 		if (handle->hwfw_match == 1) {
2469e39c5baSBill Taylor 			/*
2479e39c5baSBill Taylor 			 * Need this check here and the 'continue's below
2489e39c5baSBill Taylor 			 * because there are some cards that have a
2499e39c5baSBill Taylor 			 * 'new' part number but the same PSID value.
2509e39c5baSBill Taylor 			 */
2519e39c5baSBill Taylor 			break;
2529e39c5baSBill Taylor 		}
2539e39c5baSBill Taylor 
2549e39c5baSBill Taylor 		/* match PSID */
2559e39c5baSBill Taylor 		if (strncmp((const char *)psid, mlx_mdr[i].mlx_psid,
2569e39c5baSBill Taylor 		    psid_size) == 0) {
2579e39c5baSBill Taylor 			logmsg(MSG_INFO, "Found Matching firmware image's "
2589e39c5baSBill Taylor 			    "PSID (%s) entry in MDR Table\n", psid);
2599e39c5baSBill Taylor 
2609e39c5baSBill Taylor 			logmsg(MSG_INFO, "Search for firmware image's part# "
2619e39c5baSBill Taylor 			    "(%s), MDR/HW PN (%s) \n",
2629e39c5baSBill Taylor 			    handle->info.mlx_pn, mlx_mdr[i].mlx_pn);
2639e39c5baSBill Taylor 
2649e39c5baSBill Taylor 			/* match part numbers */
2659e39c5baSBill Taylor 			if (strncmp(handle->info.mlx_pn, mlx_mdr[i].mlx_pn,
2669e39c5baSBill Taylor 			    handle->pn_len) == 0) {
2679e39c5baSBill Taylor 				handle->hwfw_match = 1;
2689e39c5baSBill Taylor 				logmsg(MSG_INFO, "Match Found \n");
2699e39c5baSBill Taylor 				continue;
2709e39c5baSBill Taylor 			} else {
2719e39c5baSBill Taylor 				handle->hwfw_match = 0;
2729e39c5baSBill Taylor 				no_match = i;
2739e39c5baSBill Taylor 				logmsg(MSG_INFO, "Match NOT Found \n");
2749e39c5baSBill Taylor 				continue;
2759e39c5baSBill Taylor 			}
2769e39c5baSBill Taylor 		}
2779e39c5baSBill Taylor 	}
2789e39c5baSBill Taylor 	if (i == MLX_MAX_ID && no_match == 0) {
2799e39c5baSBill Taylor 		/* no match found */
2809e39c5baSBill Taylor 		handle->hwfw_match = 0;
2819e39c5baSBill Taylor 		handle->pn_len = 0;
2829e39c5baSBill Taylor 		logmsg(MSG_WARN, gettext("hermon: No PSID match found\n"));
2839e39c5baSBill Taylor 	} else {
2849e39c5baSBill Taylor 		if (handle->hwfw_match == 0) {
2859e39c5baSBill Taylor 			logmsg(MSG_WARN, gettext("WARNING: Firmware "
2869e39c5baSBill Taylor 			    "image is meant for %s but the hardware "
2879e39c5baSBill Taylor 			    "is %s\n"), mlx_mdr[no_match].mlx_pn,
2889e39c5baSBill Taylor 			    handle->info.mlx_pn);
2899e39c5baSBill Taylor 		}
2909e39c5baSBill Taylor 	}
2919e39c5baSBill Taylor }
2929e39c5baSBill Taylor 
2939e39c5baSBill Taylor static void
cnx_flash_verify_flash_match_img(ib_cnx_encap_ident_t * handle)2949e39c5baSBill Taylor cnx_flash_verify_flash_match_img(ib_cnx_encap_ident_t *handle)
2959e39c5baSBill Taylor {
2969e39c5baSBill Taylor 	uchar_t	*psid;
2979e39c5baSBill Taylor 
2989e39c5baSBill Taylor 	logmsg(MSG_INFO, "hermon: verify: cnx_flash_verify_flash_match_img\n");
2999e39c5baSBill Taylor 	/* get PSID of firmware file */
3009e39c5baSBill Taylor 	psid = cnx_flash_get_psid_img(handle);
3019e39c5baSBill Taylor 	if (psid == NULL) {
3029e39c5baSBill Taylor 		handle->hwfw_match = 0;
3039e39c5baSBill Taylor 		handle->pn_len = 0;
3049e39c5baSBill Taylor 		return;
3059e39c5baSBill Taylor 	}
3069e39c5baSBill Taylor 	logmsg(MSG_INFO, "FW PSID (%s)\n", psid);
3079e39c5baSBill Taylor 
3089e39c5baSBill Taylor 	/*
3099e39c5baSBill Taylor 	 * Check the part number of the hardware against the part number
3109e39c5baSBill Taylor 	 * of the firmware file. If the hardware information is not
3119e39c5baSBill Taylor 	 * available, check the currently loaded firmware against the
3129e39c5baSBill Taylor 	 * firmware file to be uploaded.
3139e39c5baSBill Taylor 	 */
3149e39c5baSBill Taylor 	if (handle->pn_len != 0) {
3159e39c5baSBill Taylor 		cnx_flash_verify_flash_pn_img(handle, psid, CNX_PSID_SZ);
3169e39c5baSBill Taylor 	}
3179e39c5baSBill Taylor }
3189e39c5baSBill Taylor 
3199e39c5baSBill Taylor 
3209e39c5baSBill Taylor static int
cnx_check_guid_section()3219e39c5baSBill Taylor cnx_check_guid_section()
3229e39c5baSBill Taylor {
3239e39c5baSBill Taylor 	struct mlx_cnx_xfi  		xfisect;
3249e39c5baSBill Taylor 	struct mlx_cnx_guid_sect	guidsect;
3259e39c5baSBill Taylor 	uint32_t			nguidptr_addr;
3269e39c5baSBill Taylor 	uint16_t			calculated_crc;
3279e39c5baSBill Taylor 
3289e39c5baSBill Taylor 	logmsg(MSG_INFO, "cnx_check_guid_section: \n");
3299e39c5baSBill Taylor 
3309e39c5baSBill Taylor 	bcopy(&verifier->fwimage[0], &xfisect, sizeof (struct mlx_cnx_xfi));
3319e39c5baSBill Taylor 	logmsg(MSG_INFO, "FailSafeChunkSz: 0x%08x, ImageInfoPtr: 0x%08x\n",
3329e39c5baSBill Taylor 	    MLXSWAPBITS32(xfisect.failsafechunkinfo),
3339e39c5baSBill Taylor 	    MLXSWAPBITS32(xfisect.imageinfoptr) & CNX_XFI_IMGINFO_PTR_MASK);
3349e39c5baSBill Taylor 	logmsg(MSG_INFO, "FW Size: 0x%08x NGUIDPTR: 0x%08x\n",
3359e39c5baSBill Taylor 	    MLXSWAPBITS32(xfisect.fwimagesz), MLXSWAPBITS32(xfisect.nguidptr));
3369e39c5baSBill Taylor 
3379e39c5baSBill Taylor 	nguidptr_addr = (MLXSWAPBITS32(xfisect.nguidptr) - 0x10) / 4;
3389e39c5baSBill Taylor 	bcopy(&verifier->fwimage[nguidptr_addr], &guidsect,
3399e39c5baSBill Taylor 	    sizeof (struct mlx_cnx_guid_sect));
3409e39c5baSBill Taylor 
3419e39c5baSBill Taylor 	logmsg(MSG_INFO, "Node GUID : 0x%016llx \n",
3429e39c5baSBill Taylor 	    MLXSWAPBITS64(guidsect.nodeguid));
3439e39c5baSBill Taylor 	logmsg(MSG_INFO, "Port1 GUID: 0x%016llx \n",
3449e39c5baSBill Taylor 	    MLXSWAPBITS64(guidsect.port1guid));
3459e39c5baSBill Taylor 	logmsg(MSG_INFO, "Port2 GUID: 0x%016llx \n",
3469e39c5baSBill Taylor 	    MLXSWAPBITS64(guidsect.port2guid));
3479e39c5baSBill Taylor 	logmsg(MSG_INFO, "SysIm GUID: 0x%016llx \n",
3489e39c5baSBill Taylor 	    MLXSWAPBITS64(guidsect.sysimguid));
3499e39c5baSBill Taylor 	logmsg(MSG_INFO, "Port 1 MAC: 0x%016llx \n",
3509e39c5baSBill Taylor 	    MLXSWAPBITS64(guidsect.port1_mac));
3519e39c5baSBill Taylor 	logmsg(MSG_INFO, "Port 2 MAC: 0x%016llx \n",
3529e39c5baSBill Taylor 	    MLXSWAPBITS64(guidsect.port2_mac));
3539e39c5baSBill Taylor 
3549e39c5baSBill Taylor 	calculated_crc = cnx_crc16((uint8_t *)&verifier->fwimage[nguidptr_addr],
3559e39c5baSBill Taylor 	    CNX_GUID_CRC16_SIZE, CNX_FILE_IMG);
3569e39c5baSBill Taylor 	if (calculated_crc != ntohs(guidsect.guidcrc)) {
3579e39c5baSBill Taylor 		logmsg(MSG_WARN, gettext("hermon: calculated crc value 0x%x "
3589e39c5baSBill Taylor 		    "differs from GUID section 0x%x\n"), calculated_crc,
3599e39c5baSBill Taylor 		    ntohs(guidsect.guidcrc));
3609e39c5baSBill Taylor 	} else {
3619e39c5baSBill Taylor 		logmsg(MSG_INFO, "hermon: calculated crc value 0x%x MATCHES "
3629e39c5baSBill Taylor 		    "with GUID section 0x%x\n", calculated_crc,
3639e39c5baSBill Taylor 		    ntohs(guidsect.guidcrc));
3649e39c5baSBill Taylor 	}
3659e39c5baSBill Taylor 
3669e39c5baSBill Taylor 	if ((MLXSWAPBITS64(guidsect.nodeguid) == MLX_DEFAULT_NODE_GUID) &&
3679e39c5baSBill Taylor 	    (MLXSWAPBITS64(guidsect.port1guid) == MLX_DEFAULT_P1_GUID) &&
3689e39c5baSBill Taylor 	    (MLXSWAPBITS64(guidsect.port2guid) == MLX_DEFAULT_P2_GUID) &&
3699e39c5baSBill Taylor 	    ((MLXSWAPBITS64(guidsect.sysimguid) == MLX_DEFAULT_SYSIMG_GUID) ||
3709e39c5baSBill Taylor 	    (MLXSWAPBITS64(guidsect.sysimguid) == MLX_DEFAULT_NODE_GUID)) ||
3719e39c5baSBill Taylor 	    ((((MLXSWAPBITS64(guidsect.nodeguid) & HIGHBITS64) >> 40) ==
3729e39c5baSBill Taylor 	    MLX_OUI) ||
3739e39c5baSBill Taylor 	    (((MLXSWAPBITS64(guidsect.port1guid) & HIGHBITS64) >> 40) ==
3749e39c5baSBill Taylor 	    MLX_OUI) ||
3759e39c5baSBill Taylor 	    (((MLXSWAPBITS64(guidsect.port2guid) & HIGHBITS64) >> 40) ==
3769e39c5baSBill Taylor 	    MLX_OUI) ||
3779e39c5baSBill Taylor 	    (((MLXSWAPBITS64(guidsect.sysimguid) & HIGHBITS64) >> 40) ==
3789e39c5baSBill Taylor 	    MLX_OUI)) ||
3799e39c5baSBill Taylor 	    ((((MLXSWAPBITS64(guidsect.nodeguid) & HIGHBITS64) >> 40) ==
3809e39c5baSBill Taylor 	    SUNW_OUI) ||
3819e39c5baSBill Taylor 	    (((MLXSWAPBITS64(guidsect.port1guid) & HIGHBITS64) >> 40) ==
3829e39c5baSBill Taylor 	    SUNW_OUI) ||
3839e39c5baSBill Taylor 	    (((MLXSWAPBITS64(guidsect.port2guid) & HIGHBITS64) >> 40) ==
3849e39c5baSBill Taylor 	    SUNW_OUI) ||
3859e39c5baSBill Taylor 	    (((MLXSWAPBITS64(guidsect.sysimguid) & HIGHBITS64) >> 40) ==
3869e39c5baSBill Taylor 	    SUNW_OUI))) {
3879e39c5baSBill Taylor 		logmsg(MSG_INFO, "%s firmware image verifier: GUID Prefix "
3889e39c5baSBill Taylor 		    "is as expected\n", verifier->vendor);
3899e39c5baSBill Taylor 		return (FWFLASH_SUCCESS);
3909e39c5baSBill Taylor 	} else {
3919e39c5baSBill Taylor 		logmsg(MSG_INFO, "%s firmware image verifier: GUID prefix "
3929e39c5baSBill Taylor 		    "is not as expected\n", verifier->vendor);
3939e39c5baSBill Taylor 		return (FWFLASH_FAILURE);
3949e39c5baSBill Taylor 	}
3959e39c5baSBill Taylor }
396