9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * CDDL HEADER START
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The contents of this file are subject to the terms of the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Common Development and Distribution License (the "License").
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * You may not use this file except in compliance with the License.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * or http://www.opensolaris.org/os/licensing.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * See the License for the specific language governing permissions
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * and limitations under the License.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * When distributing Covered Code, include this CDDL HEADER in each
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If applicable, add the following below this CDDL HEADER, with the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * fields enclosed by brackets "[]" replaced with your own identifying
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * information: Portions Copyright [yyyy] [name of copyright owner]
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * CDDL HEADER END
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
b67a60d6eedde75935cdd0a5bdaf0f93210e759fShantkumar Hiremath * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Mellanox firmware image verification plugin
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <stdio.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <stdlib.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <unistd.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/types.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/stat.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/sysmacros.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <fcntl.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/condvar.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <string.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <strings.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/byteorder.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <libintl.h> /* for gettext(3c) */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <fwflash/fwflash.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include "../hdrs/MELLANOX.h"
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include "../hdrs/tavor_ib.h"
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorchar vendor[] = "MELLANOX\0";
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorextern int errno;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorextern struct vrfyplugin *verifier;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/* required functions for this plugin */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorint vendorvrfy(struct devicelist *devicenode);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/* helper functions */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int check_guid_ptr(uint8_t *data);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorint
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorvendorvrfy(struct devicelist *devicenode)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct ib_encap_ident *encap;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t sector_sz;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int *firmware;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t vp_fia, vs_fia;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t vp_imginfo, vs_imginfo;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct mlx_xps *vps;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint8_t *vfi;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int i = 0, a, b, c, d;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor char temppsid[17];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor char rawpsid[16];
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath int offset;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor encap = (struct ib_encap_ident *)devicenode->ident->encap_ident;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * NOTE that since verifier->fwimage is an array of ints,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * we have to divide our actual desired number by 4 to get
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the right data.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor firmware = verifier->fwimage;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath /*
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath * The actual location of log2_sector_sz can be calculated
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath * by adding 0x32 to the value that is written in the
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath * log2_sector_sz_ptr field. The log2_sector_sz_ptr is located
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath * at 0x16 byte offset in Invariant Sector.
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath */
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath offset = FLASH_IS_SECTOR_SIZE_OFFSET +
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath MLXSWAPBITS32(firmware[FLASH_IS_SECT_SIZE_PTR/4]);
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath sector_sz = 1 << MLXSWAPBITS32(firmware[offset/4]);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (sector_sz != encap->sector_sz) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor logmsg(MSG_ERROR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gettext("%s firmware image verifier: "
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath "Invariant Sector is invalid\n"), verifier->vendor);
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath logmsg(MSG_ERROR, gettext("Mis-match in sector size: "
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath "device's 0x%X file 0x%X\n"), encap->sector_sz, sector_sz);
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath logmsg(MSG_ERROR, gettext("Firmware image file is not "
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath "appropriate for this device.\n"));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* this is fatal */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (FWFLASH_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* now verify primary pointer sector */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((vps = calloc(1, sizeof (struct mlx_xps))) == NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor logmsg(MSG_ERROR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gettext("%s firmware image verifier: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "Unable to allocate memory for Primary Pointer "
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath "Sector verification\n"), verifier->vendor);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (FWFLASH_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor bcopy(&firmware[sector_sz / 4], vps, sizeof (struct mlx_xps));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((MLXSWAPBITS32(vps->signature) != FLASH_PS_SIGNATURE) ||
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (vps->xpsresv3 != 0)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor logmsg(MSG_ERROR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gettext("%s firmware image verifier: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "Primary Pointer Sector is invalid\n"),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verifier->vendor);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor vp_fia = MLXSWAPBITS32(vps->fia);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * A slight diversion - check the PSID in the last
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * 16 bytes of the first 256bytes in the xPS sectors.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * This will give us our part number to match. If the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * part number in the image doesn't match the part number
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * in the encap_ident info (and pn_len > 0) then we reject
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * this image as being incompatible with the HCA.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * In this bit we're only checking the info.mlx_psid field
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * of the primary image in the on-disk image. If that's
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * invalid we reject the image.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath bzero(temppsid, 17);
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath bcopy(vps->vsdpsid+0xd0, &rawpsid, 16);
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath for (i = 0; i < 16; i += 4) {
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath temppsid[i] = rawpsid[i+3];
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath temppsid[i+1] = rawpsid[i+2];
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath temppsid[i+2] = rawpsid[i+1];
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath temppsid[i+3] = rawpsid[i];
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath }
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath logmsg(MSG_INFO,
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath "tavor: have raw '%s', want munged '%s'\n",
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath rawpsid, temppsid);
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath logmsg(MSG_INFO, "tavor_vrfy: PSID file '%s' HCA's PSID '%s'\n",
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath (temppsid != NULL) ? temppsid : "(null)",
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath (encap->info.mlx_psid != NULL) ? encap->info.mlx_psid : "(null)");
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath if (encap->info.mlx_psid != NULL) {
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath int resp;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (strncmp(encap->info.mlx_psid, temppsid, 16) != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor logmsg(MSG_ERROR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gettext("%s firmware image verifier: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "firmware image file %s is not appropriate "
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath "for device "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "%s (PSID file %s vs PSID device %s)\n"),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verifier->vendor, verifier->imgfile,
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath devicenode->drvname,
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath ((temppsid != NULL) ? temppsid : "(null)"),
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath encap->info.mlx_psid);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath logmsg(MSG_ERROR,
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath gettext("Do you want to continue? (Y/N): "));
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath (void) fflush(stdin);
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath resp = getchar();
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath if (resp != 'Y' && resp != 'y') {
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath free(vps);
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath logmsg(MSG_ERROR, gettext("Not proceeding with "
0bc9814f152db9078852cc4ec759a4d8b53a1b8bXinChen "flash operation of %s on %s\n"),
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath verifier->imgfile, devicenode->drvname);
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath return (FWFLASH_FAILURE);
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor logmsg(MSG_INFO,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "%s firmware image verifier: HCA PSID (%s) "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "matches firmware image %s's PSID\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verifier->vendor,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor encap->info.mlx_psid,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verifier->imgfile);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* now verify secondary pointer sector */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor bzero(vps, sizeof (struct mlx_xps));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor bcopy(&firmware[sector_sz / 2], vps, sizeof (struct mlx_xps));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((MLXSWAPBITS32(vps->signature) != FLASH_PS_SIGNATURE) ||
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (vps->xpsresv3 != 0)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor logmsg(MSG_ERROR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gettext("%s firmware image verifier: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "Secondary Pointer Sector is invalid\n"),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verifier->vendor);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor vs_fia = MLXSWAPBITS32(vps->fia);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) free(vps);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((vfi = calloc(1, sector_sz)) == NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor logmsg(MSG_ERROR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gettext("%s firmware image verifier: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "Unable to allocate space for Primary "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "Firmware Image verification\n"),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verifier->vendor);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (FWFLASH_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor bcopy(&firmware[vp_fia / 4], vfi, sector_sz);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor bcopy(&vfi[XFI_IMGINFO_OFFSET], &i, 4);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor vp_imginfo = MLXSWAPBITS32(i);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* for readability only */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor a = (vp_imginfo & 0xff000000) >> 24;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor b = (vp_imginfo & 0x00ff0000) >> 16;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor c = (vp_imginfo & 0x0000ff00) >> 8;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor d = (vp_imginfo & 0x000000ff);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * It appears to be the case (empirically) that this particular
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * check condition for ImageInfoPtr doesn't hold for A1 firmware
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * images. So if the ((a+b+c+d)%0x100) fails, don't worry unless
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the contents of the GUID section do not match the Mellanox
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * default GUIDs 2c9000100d05[0123]. The A2++ images also have
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * these default GUIDS.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Unfortunately we can't depend on the hwrev field of the image's
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Invariant Sector for another level of confirmation, since A2++
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * images seem to have that field set to 0xa1 as well as the A1
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * images. Annoying!
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((((a+b+c+d) % 0x100) == 0) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (vp_imginfo != 0x00000000)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor logmsg(MSG_INFO,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "%s firmware image verifier: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "Primary Firmware Image Info pointer is valid\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verifier->vendor);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath logmsg(MSG_INFO,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gettext("%s firmware image verifier: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "Primary Firmware Image Info pointer is invalid "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "(0x%04x)\nChecking GUID section.....\n"),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verifier->vendor, vp_imginfo);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (check_guid_ptr(vfi) == FWFLASH_FAILURE) {
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath logmsg(MSG_INFO,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gettext("%s firmware image verifier: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "Primary Firmware Image GUID section "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "is invalid\n"),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verifier->vendor);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor i = 1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor logmsg(MSG_INFO,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "%s firmware image verifier: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "Primary GUID section is ok\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verifier->vendor);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor bzero(vfi, sector_sz);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor bcopy(&firmware[vs_fia / 4], vfi, sector_sz);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor bcopy(&vfi[XFI_IMGINFO_OFFSET], &i, 4);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor vs_imginfo = MLXSWAPBITS32(i);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* for readability only */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor a = (vs_imginfo & 0xff000000) >> 24;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor b = (vs_imginfo & 0x00ff0000) >> 16;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor c = (vs_imginfo & 0x0000ff00) >> 8;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor d = (vs_imginfo & 0x000000ff);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((((a+b+c+d) % 0x100) == 0) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (vs_imginfo != 0x00000000)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor logmsg(MSG_INFO,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "%s firmware image verifier: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "Secondary Firmware Image Info pointer is valid\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verifier->vendor);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath logmsg(MSG_INFO,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gettext("%s firmware image verifier: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "Secondary Firmware Image Info pointer is invalid "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "(0x%04x)\nChecking GUID section.....\n"),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verifier->vendor, vp_imginfo);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (check_guid_ptr(vfi) == FWFLASH_FAILURE) {
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath logmsg(MSG_INFO,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gettext("%s firmware image verifier: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "Secondary Firmware Image GUID section "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "is invalid\n"),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verifier->vendor);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor i++;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor free(vfi);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath if (i == 2)
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath logmsg(MSG_WARN, gettext("%s firmware image verifier: "
ee5d8455d3cff95bf8149073831be4560d60250dShantkumar Hiremath "FAILED\n"), verifier->vendor);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return ((i == 2) ? (FWFLASH_FAILURE) : (FWFLASH_SUCCESS));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Very simple function - we're given an array of bytes,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * we know that we need to read the value at offset FLASH_GUID_PTR
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * and jump to that location to read 4x uint64_t of (hopefully)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * GUID data. If we can read that data, and it matches the default
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Mellanox GUIDs, then we return success. We need all 4 default
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * GUIDs to match otherwise we return failure.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorcheck_guid_ptr(uint8_t *data)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct mlx_xfi xfisect;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct mlx_guid_sect guidsect;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor bcopy(data, &xfisect, sizeof (xfisect));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor bcopy(&data[MLXSWAPBITS32(xfisect.nguidptr) - 16], &guidsect,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor GUIDSECTION_SZ);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor logmsg(MSG_INFO, "nodeguid: %0llx\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor MLXSWAPBITS64(guidsect.nodeguid));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor logmsg(MSG_INFO, "port1guid: %0llx\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor MLXSWAPBITS64(guidsect.port1guid));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor logmsg(MSG_INFO, "port2guid: %0llx\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor MLXSWAPBITS64(guidsect.port2guid));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor logmsg(MSG_INFO, "sysimguid: %0llx\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor MLXSWAPBITS64(guidsect.sysimguid));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((MLXSWAPBITS64(guidsect.nodeguid) == MLX_DEFAULT_NODE_GUID) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (MLXSWAPBITS64(guidsect.port1guid) == MLX_DEFAULT_P1_GUID) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (MLXSWAPBITS64(guidsect.port2guid) == MLX_DEFAULT_P2_GUID) &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ((MLXSWAPBITS64(guidsect.sysimguid) == MLX_DEFAULT_SYSIMG_GUID) ||
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (MLXSWAPBITS64(guidsect.sysimguid) == MLX_DEFAULT_NODE_GUID)) ||
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ((((MLXSWAPBITS64(guidsect.nodeguid) & HIGHBITS64) >> 40)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor == MLX_OUI) ||
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (((MLXSWAPBITS64(guidsect.port1guid) & HIGHBITS64) >> 40)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor == MLX_OUI) ||
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (((MLXSWAPBITS64(guidsect.port2guid) & HIGHBITS64) >> 40)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor == MLX_OUI) ||
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (((MLXSWAPBITS64(guidsect.sysimguid) & HIGHBITS64) >> 40)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor == MLX_OUI))) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (FWFLASH_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (FWFLASH_FAILURE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}