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 * Mellanox firmware image verification plugin
289e39c5baSBill Taylor */
299e39c5baSBill Taylor
309e39c5baSBill Taylor
319e39c5baSBill Taylor #include <stdio.h>
329e39c5baSBill Taylor #include <stdlib.h>
339e39c5baSBill Taylor #include <unistd.h>
349e39c5baSBill Taylor #include <sys/types.h>
359e39c5baSBill Taylor #include <sys/stat.h>
369e39c5baSBill Taylor #include <sys/sysmacros.h>
379e39c5baSBill Taylor #include <fcntl.h>
389e39c5baSBill Taylor #include <sys/condvar.h>
399e39c5baSBill Taylor #include <string.h>
409e39c5baSBill Taylor #include <strings.h>
419e39c5baSBill Taylor
429e39c5baSBill Taylor #include <sys/byteorder.h>
439e39c5baSBill Taylor
449e39c5baSBill Taylor #include <libintl.h> /* for gettext(3c) */
459e39c5baSBill Taylor
469e39c5baSBill Taylor #include <fwflash/fwflash.h>
479e39c5baSBill Taylor #include "../hdrs/MELLANOX.h"
489e39c5baSBill Taylor #include "../hdrs/tavor_ib.h"
499e39c5baSBill Taylor
509e39c5baSBill Taylor char vendor[] = "MELLANOX\0";
519e39c5baSBill Taylor
529e39c5baSBill Taylor extern int errno;
539e39c5baSBill Taylor extern struct vrfyplugin *verifier;
549e39c5baSBill Taylor
559e39c5baSBill Taylor
569e39c5baSBill Taylor /* required functions for this plugin */
579e39c5baSBill Taylor int vendorvrfy(struct devicelist *devicenode);
589e39c5baSBill Taylor
599e39c5baSBill Taylor
609e39c5baSBill Taylor /* helper functions */
619e39c5baSBill Taylor static int check_guid_ptr(uint8_t *data);
629e39c5baSBill Taylor
639e39c5baSBill Taylor
649e39c5baSBill Taylor int
vendorvrfy(struct devicelist * devicenode)659e39c5baSBill Taylor vendorvrfy(struct devicelist *devicenode)
669e39c5baSBill Taylor {
679e39c5baSBill Taylor struct ib_encap_ident *encap;
689e39c5baSBill Taylor uint32_t sector_sz;
699e39c5baSBill Taylor int *firmware;
709e39c5baSBill Taylor uint32_t vp_fia, vs_fia;
719e39c5baSBill Taylor uint32_t vp_imginfo, vs_imginfo;
729e39c5baSBill Taylor struct mlx_xps *vps;
739e39c5baSBill Taylor uint8_t *vfi;
749e39c5baSBill Taylor int i = 0, a, b, c, d;
759e39c5baSBill Taylor char temppsid[17];
769e39c5baSBill Taylor char rawpsid[16];
77ee5d8455SShantkumar Hiremath int offset;
789e39c5baSBill Taylor
799e39c5baSBill Taylor encap = (struct ib_encap_ident *)devicenode->ident->encap_ident;
809e39c5baSBill Taylor
819e39c5baSBill Taylor /*
829e39c5baSBill Taylor * NOTE that since verifier->fwimage is an array of ints,
839e39c5baSBill Taylor * we have to divide our actual desired number by 4 to get
849e39c5baSBill Taylor * the right data.
859e39c5baSBill Taylor */
869e39c5baSBill Taylor firmware = verifier->fwimage;
879e39c5baSBill Taylor
88ee5d8455SShantkumar Hiremath /*
89ee5d8455SShantkumar Hiremath * The actual location of log2_sector_sz can be calculated
90ee5d8455SShantkumar Hiremath * by adding 0x32 to the value that is written in the
91ee5d8455SShantkumar Hiremath * log2_sector_sz_ptr field. The log2_sector_sz_ptr is located
92ee5d8455SShantkumar Hiremath * at 0x16 byte offset in Invariant Sector.
93ee5d8455SShantkumar Hiremath */
94ee5d8455SShantkumar Hiremath offset = FLASH_IS_SECTOR_SIZE_OFFSET +
95ee5d8455SShantkumar Hiremath MLXSWAPBITS32(firmware[FLASH_IS_SECT_SIZE_PTR/4]);
96ee5d8455SShantkumar Hiremath
97ee5d8455SShantkumar Hiremath sector_sz = 1 << MLXSWAPBITS32(firmware[offset/4]);
989e39c5baSBill Taylor
999e39c5baSBill Taylor if (sector_sz != encap->sector_sz) {
1009e39c5baSBill Taylor logmsg(MSG_ERROR,
1019e39c5baSBill Taylor gettext("%s firmware image verifier: "
102ee5d8455SShantkumar Hiremath "Invariant Sector is invalid\n"), verifier->vendor);
103ee5d8455SShantkumar Hiremath logmsg(MSG_ERROR, gettext("Mis-match in sector size: "
104ee5d8455SShantkumar Hiremath "device's 0x%X file 0x%X\n"), encap->sector_sz, sector_sz);
105ee5d8455SShantkumar Hiremath logmsg(MSG_ERROR, gettext("Firmware image file is not "
106ee5d8455SShantkumar Hiremath "appropriate for this device.\n"));
1079e39c5baSBill Taylor /* this is fatal */
1089e39c5baSBill Taylor return (FWFLASH_FAILURE);
1099e39c5baSBill Taylor }
1109e39c5baSBill Taylor
1119e39c5baSBill Taylor /* now verify primary pointer sector */
1129e39c5baSBill Taylor if ((vps = calloc(1, sizeof (struct mlx_xps))) == NULL) {
1139e39c5baSBill Taylor logmsg(MSG_ERROR,
1149e39c5baSBill Taylor gettext("%s firmware image verifier: "
1159e39c5baSBill Taylor "Unable to allocate memory for Primary Pointer "
116ee5d8455SShantkumar Hiremath "Sector verification\n"), verifier->vendor);
1179e39c5baSBill Taylor return (FWFLASH_FAILURE);
1189e39c5baSBill Taylor }
1199e39c5baSBill Taylor bcopy(&firmware[sector_sz / 4], vps, sizeof (struct mlx_xps));
1209e39c5baSBill Taylor if ((MLXSWAPBITS32(vps->signature) != FLASH_PS_SIGNATURE) ||
1219e39c5baSBill Taylor (vps->xpsresv3 != 0)) {
1229e39c5baSBill Taylor logmsg(MSG_ERROR,
1239e39c5baSBill Taylor gettext("%s firmware image verifier: "
1249e39c5baSBill Taylor "Primary Pointer Sector is invalid\n"),
1259e39c5baSBill Taylor verifier->vendor);
1269e39c5baSBill Taylor }
1279e39c5baSBill Taylor vp_fia = MLXSWAPBITS32(vps->fia);
1289e39c5baSBill Taylor
1299e39c5baSBill Taylor /*
1309e39c5baSBill Taylor * A slight diversion - check the PSID in the last
1319e39c5baSBill Taylor * 16 bytes of the first 256bytes in the xPS sectors.
1329e39c5baSBill Taylor * This will give us our part number to match. If the
1339e39c5baSBill Taylor * part number in the image doesn't match the part number
1349e39c5baSBill Taylor * in the encap_ident info (and pn_len > 0) then we reject
1359e39c5baSBill Taylor * this image as being incompatible with the HCA.
1369e39c5baSBill Taylor *
1379e39c5baSBill Taylor * In this bit we're only checking the info.mlx_psid field
1389e39c5baSBill Taylor * of the primary image in the on-disk image. If that's
1399e39c5baSBill Taylor * invalid we reject the image.
1409e39c5baSBill Taylor */
1419e39c5baSBill Taylor
142ee5d8455SShantkumar Hiremath bzero(temppsid, 17);
143ee5d8455SShantkumar Hiremath bcopy(vps->vsdpsid+0xd0, &rawpsid, 16);
144ee5d8455SShantkumar Hiremath
145ee5d8455SShantkumar Hiremath for (i = 0; i < 16; i += 4) {
146ee5d8455SShantkumar Hiremath temppsid[i] = rawpsid[i+3];
147ee5d8455SShantkumar Hiremath temppsid[i+1] = rawpsid[i+2];
148ee5d8455SShantkumar Hiremath temppsid[i+2] = rawpsid[i+1];
149ee5d8455SShantkumar Hiremath temppsid[i+3] = rawpsid[i];
150ee5d8455SShantkumar Hiremath }
151ee5d8455SShantkumar Hiremath logmsg(MSG_INFO,
152ee5d8455SShantkumar Hiremath "tavor: have raw '%s', want munged '%s'\n",
153ee5d8455SShantkumar Hiremath rawpsid, temppsid);
154ee5d8455SShantkumar Hiremath logmsg(MSG_INFO, "tavor_vrfy: PSID file '%s' HCA's PSID '%s'\n",
155ee5d8455SShantkumar Hiremath (temppsid != NULL) ? temppsid : "(null)",
156ee5d8455SShantkumar Hiremath (encap->info.mlx_psid != NULL) ? encap->info.mlx_psid : "(null)");
157ee5d8455SShantkumar Hiremath
158ee5d8455SShantkumar Hiremath if (encap->info.mlx_psid != NULL) {
159ee5d8455SShantkumar Hiremath int resp;
1609e39c5baSBill Taylor if (strncmp(encap->info.mlx_psid, temppsid, 16) != 0) {
1619e39c5baSBill Taylor logmsg(MSG_ERROR,
1629e39c5baSBill Taylor gettext("%s firmware image verifier: "
1639e39c5baSBill Taylor "firmware image file %s is not appropriate "
164ee5d8455SShantkumar Hiremath "for device "
1659e39c5baSBill Taylor "%s (PSID file %s vs PSID device %s)\n"),
1669e39c5baSBill Taylor verifier->vendor, verifier->imgfile,
167ee5d8455SShantkumar Hiremath devicenode->drvname,
168ee5d8455SShantkumar Hiremath ((temppsid != NULL) ? temppsid : "(null)"),
169ee5d8455SShantkumar Hiremath encap->info.mlx_psid);
1709e39c5baSBill Taylor
171ee5d8455SShantkumar Hiremath logmsg(MSG_ERROR,
172ee5d8455SShantkumar Hiremath gettext("Do you want to continue? (Y/N): "));
173ee5d8455SShantkumar Hiremath (void) fflush(stdin);
174ee5d8455SShantkumar Hiremath resp = getchar();
175ee5d8455SShantkumar Hiremath if (resp != 'Y' && resp != 'y') {
176ee5d8455SShantkumar Hiremath free(vps);
177ee5d8455SShantkumar Hiremath logmsg(MSG_ERROR, gettext("Not proceeding with "
1780bc9814fSXinChen "flash operation of %s on %s\n"),
179ee5d8455SShantkumar Hiremath verifier->imgfile, devicenode->drvname);
180ee5d8455SShantkumar Hiremath return (FWFLASH_FAILURE);
181ee5d8455SShantkumar Hiremath }
1829e39c5baSBill Taylor } else {
1839e39c5baSBill Taylor logmsg(MSG_INFO,
1849e39c5baSBill Taylor "%s firmware image verifier: HCA PSID (%s) "
1859e39c5baSBill Taylor "matches firmware image %s's PSID\n",
1869e39c5baSBill Taylor verifier->vendor,
1879e39c5baSBill Taylor encap->info.mlx_psid,
1889e39c5baSBill Taylor verifier->imgfile);
1899e39c5baSBill Taylor }
1909e39c5baSBill Taylor }
1919e39c5baSBill Taylor
1929e39c5baSBill Taylor
1939e39c5baSBill Taylor /* now verify secondary pointer sector */
1949e39c5baSBill Taylor bzero(vps, sizeof (struct mlx_xps));
1959e39c5baSBill Taylor
1969e39c5baSBill Taylor bcopy(&firmware[sector_sz / 2], vps, sizeof (struct mlx_xps));
1979e39c5baSBill Taylor if ((MLXSWAPBITS32(vps->signature) != FLASH_PS_SIGNATURE) ||
1989e39c5baSBill Taylor (vps->xpsresv3 != 0)) {
1999e39c5baSBill Taylor logmsg(MSG_ERROR,
2009e39c5baSBill Taylor gettext("%s firmware image verifier: "
2019e39c5baSBill Taylor "Secondary Pointer Sector is invalid\n"),
2029e39c5baSBill Taylor verifier->vendor);
2039e39c5baSBill Taylor }
2049e39c5baSBill Taylor vs_fia = MLXSWAPBITS32(vps->fia);
2059e39c5baSBill Taylor
2069e39c5baSBill Taylor (void) free(vps);
2079e39c5baSBill Taylor
2089e39c5baSBill Taylor if ((vfi = calloc(1, sector_sz)) == NULL) {
2099e39c5baSBill Taylor logmsg(MSG_ERROR,
2109e39c5baSBill Taylor gettext("%s firmware image verifier: "
2119e39c5baSBill Taylor "Unable to allocate space for Primary "
2129e39c5baSBill Taylor "Firmware Image verification\n"),
2139e39c5baSBill Taylor verifier->vendor);
2149e39c5baSBill Taylor return (FWFLASH_FAILURE);
2159e39c5baSBill Taylor }
2169e39c5baSBill Taylor bcopy(&firmware[vp_fia / 4], vfi, sector_sz);
2179e39c5baSBill Taylor bcopy(&vfi[XFI_IMGINFO_OFFSET], &i, 4);
2189e39c5baSBill Taylor vp_imginfo = MLXSWAPBITS32(i);
2199e39c5baSBill Taylor
2209e39c5baSBill Taylor /* for readability only */
2219e39c5baSBill Taylor a = (vp_imginfo & 0xff000000) >> 24;
2229e39c5baSBill Taylor b = (vp_imginfo & 0x00ff0000) >> 16;
2239e39c5baSBill Taylor c = (vp_imginfo & 0x0000ff00) >> 8;
2249e39c5baSBill Taylor d = (vp_imginfo & 0x000000ff);
2259e39c5baSBill Taylor
2269e39c5baSBill Taylor /*
2279e39c5baSBill Taylor * It appears to be the case (empirically) that this particular
2289e39c5baSBill Taylor * check condition for ImageInfoPtr doesn't hold for A1 firmware
2299e39c5baSBill Taylor * images. So if the ((a+b+c+d)%0x100) fails, don't worry unless
2309e39c5baSBill Taylor * the contents of the GUID section do not match the Mellanox
2319e39c5baSBill Taylor * default GUIDs 2c9000100d05[0123]. The A2++ images also have
2329e39c5baSBill Taylor * these default GUIDS.
2339e39c5baSBill Taylor *
2349e39c5baSBill Taylor * Unfortunately we can't depend on the hwrev field of the image's
2359e39c5baSBill Taylor * Invariant Sector for another level of confirmation, since A2++
2369e39c5baSBill Taylor * images seem to have that field set to 0xa1 as well as the A1
2379e39c5baSBill Taylor * images. Annoying!
2389e39c5baSBill Taylor */
2399e39c5baSBill Taylor
2409e39c5baSBill Taylor if ((((a+b+c+d) % 0x100) == 0) &&
2419e39c5baSBill Taylor (vp_imginfo != 0x00000000)) {
2429e39c5baSBill Taylor logmsg(MSG_INFO,
2439e39c5baSBill Taylor "%s firmware image verifier: "
2449e39c5baSBill Taylor "Primary Firmware Image Info pointer is valid\n",
2459e39c5baSBill Taylor verifier->vendor);
2469e39c5baSBill Taylor } else {
2479e39c5baSBill Taylor
248ee5d8455SShantkumar Hiremath logmsg(MSG_INFO,
2499e39c5baSBill Taylor gettext("%s firmware image verifier: "
2509e39c5baSBill Taylor "Primary Firmware Image Info pointer is invalid "
2519e39c5baSBill Taylor "(0x%04x)\nChecking GUID section.....\n"),
2529e39c5baSBill Taylor verifier->vendor, vp_imginfo);
2539e39c5baSBill Taylor
2549e39c5baSBill Taylor if (check_guid_ptr(vfi) == FWFLASH_FAILURE) {
255ee5d8455SShantkumar Hiremath logmsg(MSG_INFO,
2569e39c5baSBill Taylor gettext("%s firmware image verifier: "
2579e39c5baSBill Taylor "Primary Firmware Image GUID section "
2589e39c5baSBill Taylor "is invalid\n"),
2599e39c5baSBill Taylor verifier->vendor);
2609e39c5baSBill Taylor i = 1;
2619e39c5baSBill Taylor } else {
2629e39c5baSBill Taylor logmsg(MSG_INFO,
2639e39c5baSBill Taylor "%s firmware image verifier: "
2649e39c5baSBill Taylor "Primary GUID section is ok\n",
2659e39c5baSBill Taylor verifier->vendor);
2669e39c5baSBill Taylor }
2679e39c5baSBill Taylor
2689e39c5baSBill Taylor }
2699e39c5baSBill Taylor
2709e39c5baSBill Taylor bzero(vfi, sector_sz);
2719e39c5baSBill Taylor bcopy(&firmware[vs_fia / 4], vfi, sector_sz);
2729e39c5baSBill Taylor
2739e39c5baSBill Taylor bcopy(&vfi[XFI_IMGINFO_OFFSET], &i, 4);
2749e39c5baSBill Taylor vs_imginfo = MLXSWAPBITS32(i);
2759e39c5baSBill Taylor
2769e39c5baSBill Taylor /* for readability only */
2779e39c5baSBill Taylor a = (vs_imginfo & 0xff000000) >> 24;
2789e39c5baSBill Taylor b = (vs_imginfo & 0x00ff0000) >> 16;
2799e39c5baSBill Taylor c = (vs_imginfo & 0x0000ff00) >> 8;
2809e39c5baSBill Taylor d = (vs_imginfo & 0x000000ff);
2819e39c5baSBill Taylor
2829e39c5baSBill Taylor if ((((a+b+c+d) % 0x100) == 0) &&
2839e39c5baSBill Taylor (vs_imginfo != 0x00000000)) {
2849e39c5baSBill Taylor logmsg(MSG_INFO,
2859e39c5baSBill Taylor "%s firmware image verifier: "
2869e39c5baSBill Taylor "Secondary Firmware Image Info pointer is valid\n",
2879e39c5baSBill Taylor verifier->vendor);
2889e39c5baSBill Taylor } else {
289ee5d8455SShantkumar Hiremath logmsg(MSG_INFO,
2909e39c5baSBill Taylor gettext("%s firmware image verifier: "
2919e39c5baSBill Taylor "Secondary Firmware Image Info pointer is invalid "
2929e39c5baSBill Taylor "(0x%04x)\nChecking GUID section.....\n"),
2939e39c5baSBill Taylor verifier->vendor, vp_imginfo);
2949e39c5baSBill Taylor
2959e39c5baSBill Taylor if (check_guid_ptr(vfi) == FWFLASH_FAILURE) {
296ee5d8455SShantkumar Hiremath logmsg(MSG_INFO,
2979e39c5baSBill Taylor gettext("%s firmware image verifier: "
2989e39c5baSBill Taylor "Secondary Firmware Image GUID section "
2999e39c5baSBill Taylor "is invalid\n"),
3009e39c5baSBill Taylor verifier->vendor);
3019e39c5baSBill Taylor i++;
3029e39c5baSBill Taylor }
3039e39c5baSBill Taylor }
3049e39c5baSBill Taylor
3059e39c5baSBill Taylor free(vfi);
3069e39c5baSBill Taylor
307ee5d8455SShantkumar Hiremath if (i == 2)
308ee5d8455SShantkumar Hiremath logmsg(MSG_WARN, gettext("%s firmware image verifier: "
309ee5d8455SShantkumar Hiremath "FAILED\n"), verifier->vendor);
3109e39c5baSBill Taylor
3119e39c5baSBill Taylor return ((i == 2) ? (FWFLASH_FAILURE) : (FWFLASH_SUCCESS));
3129e39c5baSBill Taylor }
3139e39c5baSBill Taylor
3149e39c5baSBill Taylor
3159e39c5baSBill Taylor /*
3169e39c5baSBill Taylor * Very simple function - we're given an array of bytes,
3179e39c5baSBill Taylor * we know that we need to read the value at offset FLASH_GUID_PTR
3189e39c5baSBill Taylor * and jump to that location to read 4x uint64_t of (hopefully)
3199e39c5baSBill Taylor * GUID data. If we can read that data, and it matches the default
3209e39c5baSBill Taylor * Mellanox GUIDs, then we return success. We need all 4 default
3219e39c5baSBill Taylor * GUIDs to match otherwise we return failure.
3229e39c5baSBill Taylor */
3239e39c5baSBill Taylor static int
check_guid_ptr(uint8_t * data)3249e39c5baSBill Taylor check_guid_ptr(uint8_t *data)
3259e39c5baSBill Taylor {
3269e39c5baSBill Taylor struct mlx_xfi xfisect;
3279e39c5baSBill Taylor struct mlx_guid_sect guidsect;
3289e39c5baSBill Taylor
3299e39c5baSBill Taylor bcopy(data, &xfisect, sizeof (xfisect));
3309e39c5baSBill Taylor bcopy(&data[MLXSWAPBITS32(xfisect.nguidptr) - 16], &guidsect,
3319e39c5baSBill Taylor GUIDSECTION_SZ);
3329e39c5baSBill Taylor
3339e39c5baSBill Taylor logmsg(MSG_INFO, "nodeguid: %0llx\n",
3349e39c5baSBill Taylor MLXSWAPBITS64(guidsect.nodeguid));
3359e39c5baSBill Taylor logmsg(MSG_INFO, "port1guid: %0llx\n",
3369e39c5baSBill Taylor MLXSWAPBITS64(guidsect.port1guid));
3379e39c5baSBill Taylor logmsg(MSG_INFO, "port2guid: %0llx\n",
3389e39c5baSBill Taylor MLXSWAPBITS64(guidsect.port2guid));
3399e39c5baSBill Taylor logmsg(MSG_INFO, "sysimguid: %0llx\n",
3409e39c5baSBill Taylor MLXSWAPBITS64(guidsect.sysimguid));
3419e39c5baSBill Taylor
3429e39c5baSBill Taylor if ((MLXSWAPBITS64(guidsect.nodeguid) == MLX_DEFAULT_NODE_GUID) &&
3439e39c5baSBill Taylor (MLXSWAPBITS64(guidsect.port1guid) == MLX_DEFAULT_P1_GUID) &&
3449e39c5baSBill Taylor (MLXSWAPBITS64(guidsect.port2guid) == MLX_DEFAULT_P2_GUID) &&
3459e39c5baSBill Taylor ((MLXSWAPBITS64(guidsect.sysimguid) == MLX_DEFAULT_SYSIMG_GUID) ||
3469e39c5baSBill Taylor (MLXSWAPBITS64(guidsect.sysimguid) == MLX_DEFAULT_NODE_GUID)) ||
3479e39c5baSBill Taylor ((((MLXSWAPBITS64(guidsect.nodeguid) & HIGHBITS64) >> 40)
3489e39c5baSBill Taylor == MLX_OUI) ||
3499e39c5baSBill Taylor (((MLXSWAPBITS64(guidsect.port1guid) & HIGHBITS64) >> 40)
3509e39c5baSBill Taylor == MLX_OUI) ||
3519e39c5baSBill Taylor (((MLXSWAPBITS64(guidsect.port2guid) & HIGHBITS64) >> 40)
3529e39c5baSBill Taylor == MLX_OUI) ||
3539e39c5baSBill Taylor (((MLXSWAPBITS64(guidsect.sysimguid) & HIGHBITS64) >> 40)
3549e39c5baSBill Taylor == MLX_OUI))) {
3559e39c5baSBill Taylor return (FWFLASH_SUCCESS);
3569e39c5baSBill Taylor } else {
3579e39c5baSBill Taylor return (FWFLASH_FAILURE);
3589e39c5baSBill Taylor }
3599e39c5baSBill Taylor }
360