Blame IbaTools/opasw/opaswfwupdate/opaswfwupdate.c

Packit Service 3470d1
/* BEGIN_ICS_COPYRIGHT7 ****************************************
Packit Service 3470d1
Packit Service 3470d1
Copyright (c) 2015-2017, Intel Corporation
Packit Service 3470d1
Packit Service 3470d1
Redistribution and use in source and binary forms, with or without
Packit Service 3470d1
modification, are permitted provided that the following conditions are met:
Packit Service 3470d1
Packit Service 3470d1
    * Redistributions of source code must retain the above copyright notice,
Packit Service 3470d1
      this list of conditions and the following disclaimer.
Packit Service 3470d1
    * Redistributions in binary form must reproduce the above copyright
Packit Service 3470d1
      notice, this list of conditions and the following disclaimer in the
Packit Service 3470d1
      documentation and/or other materials provided with the distribution.
Packit Service 3470d1
    * Neither the name of Intel Corporation nor the names of its contributors
Packit Service 3470d1
      may be used to endorse or promote products derived from this software
Packit Service 3470d1
      without specific prior written permission.
Packit Service 3470d1
Packit Service 3470d1
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit Service 3470d1
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit Service 3470d1
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Packit Service 3470d1
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
Packit Service 3470d1
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit Service 3470d1
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
Packit Service 3470d1
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
Packit Service 3470d1
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
Packit Service 3470d1
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit Service 3470d1
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit Service 3470d1
Packit Service 3470d1
** END_ICS_COPYRIGHT7   ****************************************/
Packit Service 3470d1
Packit Service 3470d1
/* [ICS VERSION STRING: unknown] */
Packit Service 3470d1
Packit Service 3470d1
#include <stdio.h>
Packit Service 3470d1
#include <string.h>
Packit Service 3470d1
#include <getopt.h>
Packit Service 3470d1
#include <limits.h>
Packit Service 3470d1
#include <dirent.h>
Packit Service 3470d1
#include <sys/types.h>
Packit Service 3470d1
#include <sys/stat.h>
Packit Service 3470d1
#include <errno.h>
Packit Service 3470d1
Packit Service 3470d1
/* work around conflicting names */
Packit Service 3470d1
Packit Service 3470d1
#include "iba/ib_types.h"
Packit Service 3470d1
#include "iba/ib_sm_priv.h"
Packit Service 3470d1
#include "iba/ib_helper.h"
Packit Service 3470d1
#include "opamgt_sa_priv.h"
Packit Service 3470d1
#include <iba/ibt.h>
Packit Service 3470d1
#include "opaswcommon.h"
Packit Service 3470d1
#include "zlib.h"
Packit Service 3470d1
#include <openssl/sha.h>
Packit Service 3470d1
Packit Service 3470d1
#define FW_FILENAME_BASE		"prrFw"
Packit Service 3470d1
Packit Service 3470d1
#define FW_RESP_WAIT_TIME		2000
Packit Service 3470d1
#define FW_PAUSE				50000
Packit Service 3470d1
Packit Service 3470d1
typedef uint8_t bool_t;
Packit Service 3470d1
Packit Service 3470d1
// globals
Packit Service 3470d1
Packit Service 3470d1
int						g_debugMode = 0;
Packit Service 3470d1
int						g_verbose = 0;
Packit Service 3470d1
int						g_quiet = 0;
Packit Service 3470d1
int						g_gotHfi = 0;
Packit Service 3470d1
int						g_gotPort = 0;
Packit Service 3470d1
int						g_gotSecondary = 0;
Packit Service 3470d1
int						g_fileParam = 0;
Packit Service 3470d1
int						g_dirParam = 0;
Packit Service 3470d1
int32					g_sleepParam = 0;
Packit Service 3470d1
int32					g_usleepParam = 0;
Packit Service 3470d1
int32					g_dataLenParam = 0;
Packit Service 3470d1
int32					g_respTimeout = FW_RESP_WAIT_TIME;
Packit Service 3470d1
int						g_resetSwitch = 0;
Packit Service 3470d1
Packit Service 3470d1
char					fwFileName[FNAME_SIZE];
Packit Service 3470d1
char					inibinFileName[FNAME_SIZE];
Packit Service 3470d1
char					fwDirName[DNAME_SIZE];
Packit Service 3470d1
Packit Service 3470d1
uint32 loadFirmwareBuffer(struct omgt_port *port, char **fwBuffer, IB_PATH_RECORD *path, uint16 sessionID)
Packit Service 3470d1
{
Packit Service 3470d1
	FILE *fp;
Packit Service 3470d1
	DIR *fwDir;
Packit Service 3470d1
	struct dirent *dp;
Packit Service 3470d1
	int nread;
Packit Service 3470d1
	uint32 totalRead = 0;
Packit Service 3470d1
	uint32 bufSize;
Packit Service 3470d1
	char *p;
Packit Service 3470d1
	struct stat fileStat;
Packit Service 3470d1
	uint32 oemHash[8],binaryHash[8];
Packit Service 3470d1
	VENDOR_MAD                      mad;
Packit Service 3470d1
	FSTATUS                         status = FSUCCESS;
Packit Service 3470d1
	int				isValid = 1;
Packit Service 3470d1
	uint32				acb;
Packit Service 3470d1
	if (g_dirParam) {
Packit Service 3470d1
		if (chdir(fwDirName) < 0) {
Packit Service 3470d1
			fprintf(stderr, "Error: cannot change directory to %s: %s\n", fwDirName, strerror(errno));
Packit Service 3470d1
			return(0);
Packit Service 3470d1
		}
Packit Service 3470d1
		if (stat("emfwMapFile", &fileStat) < 0) {
Packit Service 3470d1
			if (errno == ENOENT) {
Packit Service 3470d1
				if ((fwDir = opendir(fwDirName)) == NULL) {
Packit Service 3470d1
					fprintf(stderr, "Error opening directory %s: %s\n", fwDirName, strerror(errno));
Packit Service 3470d1
					return(0);
Packit Service 3470d1
				}
Packit Service 3470d1
				while ((dp = readdir(fwDir)) != NULL) {
Packit Service 3470d1
					if (strstr(dp->d_name, FW_FILENAME_BASE) != NULL) {
Packit Service 3470d1
						snprintf(fwFileName, FNAME_SIZE, "%s/%s", fwDirName, dp->d_name);
Packit Service 3470d1
						fwFileName[FNAME_SIZE-1]=0;
Packit Service 3470d1
						break;
Packit Service 3470d1
					}
Packit Service 3470d1
				}
Packit Service 3470d1
				closedir(fwDir);
Packit Service 3470d1
				if (strlen(fwFileName) == 0) {
Packit Service 3470d1
					fprintf(stderr, "Error: no firmware file for %s found in directory %s\n", FW_FILENAME_BASE, fwDirName);
Packit Service 3470d1
					return(0);
Packit Service 3470d1
				}
Packit Service 3470d1
			} else {
Packit Service 3470d1
				fprintf(stderr, "Error: cannot validate emfwMapFile: %s\n", strerror(errno));
Packit Service 3470d1
				return(0);
Packit Service 3470d1
			}
Packit Service 3470d1
		} else {
Packit Service 3470d1
			getEMFWFileNames(port, path, sessionID, fwFileName, inibinFileName);
Packit Service 3470d1
		}
Packit Service 3470d1
	}
Packit Service 3470d1
	status = getOemHash(port,path,&mad,sessionID,oemHash,&acb;;
Packit Service 3470d1
	if (status == FSUCCESS) {
Packit Service 3470d1
		if (acb & 0x10000000) {
Packit Service 3470d1
			if (getBinaryHash(fwFileName,binaryHash) == FSUCCESS) {
Packit Service 3470d1
				if (memcmp(binaryHash, oemHash, sizeof(binaryHash)))
Packit Service 3470d1
					isValid = 0;
Packit Service 3470d1
			}
Packit Service 3470d1
			else {
Packit Service 3470d1
				fprintf(stderr,"Unable to get Signature from Binary\n");
Packit Service 3470d1
				return(0);
Packit Service 3470d1
			}
Packit Service 3470d1
		}
Packit Service 3470d1
	}
Packit Service 3470d1
	else {
Packit Service 3470d1
			fprintf(stderr,"Unable to get OEM hash\n");
Packit Service 3470d1
			return(0);
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	if(isValid){
Packit Service 3470d1
		if (stat(fwFileName, &fileStat) < 0) {
Packit Service 3470d1
			fprintf(stderr, "Error taking stat of file {%s}: %s\n",
Packit Service 3470d1
				fwFileName, strerror(errno));
Packit Service 3470d1
				return(0);
Packit Service 3470d1
		}
Packit Service 3470d1
Packit Service 3470d1
		bufSize = (uint32)fileStat.st_size + 1024; /* pad by 1K to be safe */
Packit Service 3470d1
Packit Service 3470d1
		if ((*fwBuffer = malloc(bufSize)) == NULL) {
Packit Service 3470d1
			fprintf(stderr, "Error allocating memory for firmware buffer\n");
Packit Service 3470d1
			return(0);
Packit Service 3470d1
		}
Packit Service 3470d1
Packit Service 3470d1
		if ((fp = fopen(fwFileName, "r")) == NULL) {
Packit Service 3470d1
			fprintf(stderr, "Error opening file %s for input: %s\n", fwFileName, strerror(errno));
Packit Service 3470d1
			return(0);
Packit Service 3470d1
		}
Packit Service 3470d1
		memset(*fwBuffer, 0, bufSize);
Packit Service 3470d1
		p = *fwBuffer + 4;
Packit Service 3470d1
		while ((nread = fread(p, 1, 1024, fp)) > 0) {
Packit Service 3470d1
			totalRead += nread;
Packit Service 3470d1
			p += nread;
Packit Service 3470d1
		}
Packit Service 3470d1
Packit Service 3470d1
		fclose(fp);
Packit Service 3470d1
Packit Service 3470d1
		//	xedgeDisplayBuffer(fwBuffer, totalRead);
Packit Service 3470d1
Packit Service 3470d1
		return(totalRead);
Packit Service 3470d1
	}
Packit Service 3470d1
	else{
Packit Service 3470d1
		fprintf(stderr,"Firmware signature mismatch\n");
Packit Service 3470d1
		return(0);
Packit Service 3470d1
	}
Packit Service 3470d1
}
Packit Service 3470d1
Packit Service 3470d1
#define LIST_FILE_SUPPORTED 0
Packit Service 3470d1
Packit Service 3470d1
static void usage(char *app_name)
Packit Service 3470d1
{
Packit Service 3470d1
	fprintf(stderr, "usage: %s -t target\n", app_name);
Packit Service 3470d1
#if LIST_FILE_SUPPORTED
Packit Service 3470d1
	fprintf(stderr, " [-l list_file]");
Packit Service 3470d1
#endif
Packit Service 3470d1
	fprintf(stderr, " [-v|-q] [-h hfi] [-o port] [-f fw_file | -d fw_directory] [-S]");
Packit Service 3470d1
	fprintf(stderr, "\n");
Packit Service 3470d1
	fprintf(stderr, "   -t - target on which to update fw\n");
Packit Service 3470d1
#if LIST_FILE_SUPPORTED
Packit Service 3470d1
	fprintf(stderr, "   -l - file that holds a list of targets to update\n");
Packit Service 3470d1
#endif
Packit Service 3470d1
	fprintf(stderr, "   -v - verbose output\n");
Packit Service 3470d1
	fprintf(stderr, "   -q - no output\n");
Packit Service 3470d1
	fprintf(stderr, "   -h - hfi, numbered 1..n, 0= -o port will be a\n");
Packit Service 3470d1
	fprintf(stderr, "        system wide port num (default is 0)\n");
Packit Service 3470d1
	fprintf(stderr, "   -o - port, numbered 1..n, 0=1st active (default\n");
Packit Service 3470d1
	fprintf(stderr, "        is 1st active)\n");
Packit Service 3470d1
	fprintf(stderr, "   -f - firmware file (extracted .bin file from emfw) \n");
Packit Service 3470d1
	fprintf(stderr, "   -d - firmware directory\n");
Packit Service 3470d1
	fprintf(stderr, "   -S - reset switch after update\n");
Packit Service 3470d1
	fprintf(stderr, "\n");
Packit Service 3470d1
	fprintf(stderr, "The -h and -o options permit a variety of selections:\n");
Packit Service 3470d1
	fprintf(stderr, "    -h 0       - 1st active port in system (this is the default)\n");
Packit Service 3470d1
	fprintf(stderr, "    -h 0 -o 0  - 1st active port in system\n");
Packit Service 3470d1
	fprintf(stderr, "    -h x       - 1st active port on HFI x\n");
Packit Service 3470d1
	fprintf(stderr, "    -h x -o 0  - 1st active port on HFI x\n");
Packit Service 3470d1
	fprintf(stderr, "    -h 0 -o y  - port y within system (irrespective of which ports are active)\n");
Packit Service 3470d1
	fprintf(stderr, "    -h x -o y  - HFI x, port y\n");
Packit Service 3470d1
Packit Service 3470d1
#if 0 /* non-documented options */
Packit Service 3470d1
	fprintf(stderr, "   -F - do secondary EEPROM (default if primary)\n");
Packit Service 3470d1
	fprintf(stderr, "   -s - delay in seconds between requests\n");
Packit Service 3470d1
	fprintf(stderr, "   -u - delay in microseconds between requests\n");
Packit Service 3470d1
	fprintf(stderr, "   -T - response timeout in microseconds\n");
Packit Service 3470d1
	fprintf(stderr, "   -z - write data length in bytes\n");
Packit Service 3470d1
#endif
Packit Service 3470d1
Packit Service 3470d1
	exit(2);
Packit Service 3470d1
}
Packit Service 3470d1
Packit Service 3470d1
int main(int argc, char *argv[])
Packit Service 3470d1
{
Packit Service 3470d1
	char				*cmdName;
Packit Service 3470d1
	const char			*opts="FDSvqt:l:h:o:d:f:m:s:u:T:z:";
Packit Service 3470d1
	uint8				*fwBuffer = NULL;
Packit Service 3470d1
	uint8				*fwBuffer2 = NULL;
Packit Service 3470d1
	char				parameter[100];
Packit Service 3470d1
	uint8				*p;
Packit Service 3470d1
#if FWDELAY_WORKAROUND
Packit Service 3470d1
	char				*sleepVal;
Packit Service 3470d1
#endif
Packit Service 3470d1
	uint32				fwSize;
Packit Service 3470d1
	EUI64				destPortGuid = -1;
Packit Service 3470d1
	int					c;
Packit Service 3470d1
	uint8				hfi = 0;
Packit Service 3470d1
	uint8				port = 0;
Packit Service 3470d1
	IB_PATH_RECORD		path;
Packit Service 3470d1
	uint16				sessionID = 0;
Packit Service 3470d1
	uint32				*u;
Packit Service 3470d1
	uint32				crcEEPROM;
Packit Service 3470d1
	uint32				crc;
Packit Service 3470d1
	VENDOR_MAD_JUMBO	mad;
Packit Service 3470d1
	FSTATUS				status = FSUCCESS;
Packit Service 3470d1
	struct              omgt_port *omgt_port_session = NULL;
Packit Service 3470d1
Packit Service 3470d1
	// determine how we've been invoked
Packit Service 3470d1
	cmdName = strrchr(argv[0], '/');			// Find last '/' in path
Packit Service 3470d1
	if (cmdName != NULL) {
Packit Service 3470d1
		cmdName++;								// Skip over last '/'
Packit Service 3470d1
	} else {
Packit Service 3470d1
		cmdName = argv[0];
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	// initialize
Packit Service 3470d1
	fwFileName[0] = '\0';
Packit Service 3470d1
	
Packit Service 3470d1
Packit Service 3470d1
	// parse options and parameters
Packit Service 3470d1
	while (-1 != (c = getopt(argc, argv, opts))) {
Packit Service 3470d1
		switch (c) {
Packit Service 3470d1
			case 'D':
Packit Service 3470d1
				g_debugMode = 1;
Packit Service 3470d1
				break;
Packit Service 3470d1
Packit Service 3470d1
			case 't':
Packit Service 3470d1
				errno = 0;
Packit Service 3470d1
				strncpy(parameter, optarg, sizeof(parameter)-1);
Packit Service 3470d1
				parameter[sizeof(parameter)-1] = 0;
Packit Service 3470d1
				if ((p = (uint8 *)strchr(parameter, ',')) != NULL) {
Packit Service 3470d1
					*p = '\0';
Packit Service 3470d1
				}
Packit Service 3470d1
				if (FSUCCESS != StringToUint64(&destPortGuid, parameter, NULL, 0, TRUE)) {
Packit Service 3470d1
					fprintf(stderr, "%s: Error: Invalid GUID: %s\n", cmdName, optarg);
Packit Service 3470d1
					usage(cmdName);
Packit Service 3470d1
				}
Packit Service 3470d1
				break;
Packit Service 3470d1
Packit Service 3470d1
			case 'l':
Packit Service 3470d1
#if !LIST_FILE_SUPPORTED
Packit Service 3470d1
				fprintf(stderr, "Error: l option is not supported at this time\n");
Packit Service 3470d1
				exit(1);
Packit Service 3470d1
#endif
Packit Service 3470d1
				break;
Packit Service 3470d1
Packit Service 3470d1
			case 'v':
Packit Service 3470d1
				g_verbose = 1;
Packit Service 3470d1
				break;
Packit Service 3470d1
Packit Service 3470d1
			case 'q':
Packit Service 3470d1
				g_quiet = 1;
Packit Service 3470d1
				break;
Packit Service 3470d1
Packit Service 3470d1
			case 'h':
Packit Service 3470d1
				if (FSUCCESS != StringToUint8(&hfi, optarg, NULL, 0, TRUE)) {
Packit Service 3470d1
					fprintf(stderr, "%s: Error: Invalid HFI Number: %s\n", cmdName, optarg);
Packit Service 3470d1
					usage(cmdName);
Packit Service 3470d1
				}
Packit Service 3470d1
				g_gotHfi = 1;
Packit Service 3470d1
				break;
Packit Service 3470d1
Packit Service 3470d1
			case 'o':
Packit Service 3470d1
				if (FSUCCESS != StringToUint8(&port, optarg, NULL, 0, TRUE)) {
Packit Service 3470d1
					fprintf(stderr, "%s: Error: Invalid Port Number: %s\n", cmdName, optarg);
Packit Service 3470d1
					usage(cmdName);
Packit Service 3470d1
				}
Packit Service 3470d1
				g_gotPort = 1;
Packit Service 3470d1
				break;
Packit Service 3470d1
Packit Service 3470d1
			case 'f':
Packit Service 3470d1
				g_fileParam = 1;
Packit Service 3470d1
				memcpy(fwFileName, optarg, FNAME_SIZE);
Packit Service 3470d1
				// Validate Filename
Packit Service 3470d1
				if (!fwFileName[0]) {
Packit Service 3470d1
					fprintf(stderr, "%s: Error: null input filename\n", cmdName);
Packit Service 3470d1
					exit(2);
Packit Service 3470d1
				}
Packit Service 3470d1
				break;
Packit Service 3470d1
Packit Service 3470d1
			case 'd':
Packit Service 3470d1
				g_dirParam = 1;
Packit Service 3470d1
				memcpy(fwDirName, optarg, DNAME_SIZE);
Packit Service 3470d1
				break;
Packit Service 3470d1
Packit Service 3470d1
			case 's':
Packit Service 3470d1
				if (FSUCCESS != StringToInt32(&g_sleepParam, optarg, NULL, 0, TRUE)
Packit Service 3470d1
					|| g_sleepParam < 0) {
Packit Service 3470d1
					fprintf(stderr, "%s: Error: Invalid delay value: %s\n", cmdName, optarg);
Packit Service 3470d1
					usage(cmdName);
Packit Service 3470d1
				}
Packit Service 3470d1
				break;
Packit Service 3470d1
Packit Service 3470d1
			case 'u':
Packit Service 3470d1
				if (FSUCCESS != StringToInt32(&g_usleepParam, optarg, NULL, 0, TRUE)
Packit Service 3470d1
					|| g_usleepParam < 0) {
Packit Service 3470d1
					fprintf(stderr, "%s: Error: Invalid delay value: %s\n", cmdName, optarg);
Packit Service 3470d1
					usage(cmdName);
Packit Service 3470d1
				}
Packit Service 3470d1
				break;
Packit Service 3470d1
Packit Service 3470d1
			case 'z':
Packit Service 3470d1
				if (FSUCCESS != StringToInt32(&g_dataLenParam, optarg, NULL, 0, TRUE)
Packit Service 3470d1
					|| g_dataLenParam < 0) {
Packit Service 3470d1
					fprintf(stderr, "%s: Error: Invalid data length value: %s\n", cmdName, optarg);
Packit Service 3470d1
					usage(cmdName);
Packit Service 3470d1
				}
Packit Service 3470d1
				break;
Packit Service 3470d1
Packit Service 3470d1
			case 'T':
Packit Service 3470d1
				if (FSUCCESS != StringToInt32(&g_respTimeout, optarg, NULL, 0, TRUE)
Packit Service 3470d1
					|| g_respTimeout < 0) {
Packit Service 3470d1
					fprintf(stderr, "%s: Error: Invalid delay value: %s\n", cmdName, optarg);
Packit Service 3470d1
					usage(cmdName);
Packit Service 3470d1
				}
Packit Service 3470d1
				break;
Packit Service 3470d1
Packit Service 3470d1
			case 'S':
Packit Service 3470d1
				g_resetSwitch = 1;
Packit Service 3470d1
				break;
Packit Service 3470d1
Packit Service 3470d1
			case 'F':
Packit Service 3470d1
				g_gotSecondary = 1;
Packit Service 3470d1
				break;
Packit Service 3470d1
Packit Service 3470d1
			default:
Packit Service 3470d1
				usage(cmdName);
Packit Service 3470d1
				break;
Packit Service 3470d1
Packit Service 3470d1
		}
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	// user has requested display of help
Packit Service 3470d1
	if (argc == 1) {
Packit Service 3470d1
		usage(cmdName);
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	if (-1 == destPortGuid) {
Packit Service 3470d1
		fprintf(stderr, "%s: Error: Must specify a target GUID\n", cmdName);
Packit Service 3470d1
		exit(1);
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	if ((!g_fileParam) && (!g_dirParam)) {
Packit Service 3470d1
		fprintf(stderr, "%s: Error: Must specify either a directory or file for the firmware\n", cmdName);
Packit Service 3470d1
		exit(1);
Packit Service 3470d1
	} else if ((g_fileParam) && (g_dirParam)) {
Packit Service 3470d1
		fprintf(stderr, "%s: Error: Cannot specify both a directory and file for the firmware\n", cmdName);
Packit Service 3470d1
		exit(1);
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	if (g_quiet && (g_debugMode || g_verbose)) {
Packit Service 3470d1
		fprintf(stderr, "%s: Error: Can not specify both -q and -D|-v\n", cmdName);
Packit Service 3470d1
		exit(1);
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	if (g_sleepParam && g_usleepParam) {
Packit Service 3470d1
		fprintf(stderr, "%s: Error: Can not specify both -s and -u\n", cmdName);
Packit Service 3470d1
		exit(1);
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
#if FWDELAY_WORKAROUND
Packit Service 3470d1
	if ((sleepVal = getenv("FWDELAY")) != NULL) {
Packit Service 3470d1
		g_usleepParam = atoi(sleepVal);
Packit Service 3470d1
		printf("Overriding delay with value %d\n", g_usleepParam);
Packit Service 3470d1
	}
Packit Service 3470d1
#endif
Packit Service 3470d1
Packit Service 3470d1
	// Get the path
Packit Service 3470d1
Packit Service 3470d1
	struct omgt_params params = {.debug_file = g_debugMode ? stderr : NULL};
Packit Service 3470d1
	status = omgt_open_port_by_num(&omgt_port_session, hfi, port, &params);
Packit Service 3470d1
	if (status != 0) {
Packit Service 3470d1
		fprintf(stderr, "%s: Error: Unable to open fabric interface.\n", cmdName);
Packit Service 3470d1
		exit(1);
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	if (getDestPath(omgt_port_session, destPortGuid, cmdName, &path) != FSUCCESS) {
Packit Service 3470d1
		fprintf(stderr, "%s: Error: Failed to get destination path\n", cmdName);
Packit Service 3470d1
		goto err_exit;
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	// Send a ClassPortInfo to see if the switch is responding
Packit Service 3470d1
Packit Service 3470d1
	status = sendClassPortInfoMad(omgt_port_session, &path, (VENDOR_MAD*)&mad;;
Packit Service 3470d1
	if (status != FSUCCESS) {
Packit Service 3470d1
		fprintf(stderr, "%s: Error: Failed to send/rcv ClassPortInfo\n", cmdName);
Packit Service 3470d1
		status = FERROR;
Packit Service 3470d1
		goto err_exit;
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	// Get a session ID
Packit Service 3470d1
Packit Service 3470d1
	sessionID = getSessionID(omgt_port_session, &path);
Packit Service 3470d1
	if (sessionID == (uint16)-1) {
Packit Service 3470d1
		fprintf(stderr, "%s: Error: Failed to obtain sessionID\n", cmdName);
Packit Service 3470d1
		status = FERROR;
Packit Service 3470d1
		goto err_exit;
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	// read the file into the buffer
Packit Service 3470d1
Packit Service 3470d1
	fwSize = loadFirmwareBuffer(omgt_port_session, (char **)&fwBuffer, &path, sessionID);
Packit Service 3470d1
	if (fwSize == 0) {
Packit Service 3470d1
		fprintf(stderr, "%s: Error: Failed to load firmware file\n", cmdName);
Packit Service 3470d1
		if (sessionID>0) releaseSession(omgt_port_session, &path, sessionID);
Packit Service 3470d1
		status = FERROR;
Packit Service 3470d1
		goto err_exit;
Packit Service 3470d1
	}
Packit Service 3470d1
	u = (uint32 *)&fwBuffer[fwSize - 4];
Packit Service 3470d1
Packit Service 3470d1
	// Loop sending i2cAccess sets to update firmware
Packit Service 3470d1
Packit Service 3470d1
	if (!g_quiet) {
Packit Service 3470d1
		printf("Updating firmware... ");
Packit Service 3470d1
		fflush(stdout);
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	if (status != FSUCCESS) {
Packit Service 3470d1
		// error trying to erase the old firmware
Packit Service 3470d1
		fprintf(stderr, "%s: Error erasing old firmware rc: %d\n", cmdName, status);
Packit Service 3470d1
	} else {
Packit Service 3470d1
		status = opaswEepromRW(omgt_port_session, &path, sessionID, (void *)&mad, g_respTimeout,
Packit Service 3470d1
							   fwSize + 4, 0, (uint8 *)fwBuffer, TRUE, g_gotSecondary);
Packit Service 3470d1
		if (status != FSUCCESS) {
Packit Service 3470d1
			// error trying to update the firmware
Packit Service 3470d1
			fprintf(stderr, "%s: Error updating firmware rc: %d\n", cmdName, status);
Packit Service 3470d1
		}
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	// now read firmware back in and verify checksum
Packit Service 3470d1
Packit Service 3470d1
	if (!g_quiet) {
Packit Service 3470d1
		printf("\nUpdate complete ... verifying ... ");
Packit Service 3470d1
		fflush(stdout);
Packit Service 3470d1
	}
Packit Service 3470d1
	if ((fwBuffer2 = malloc(fwSize + 1024)) == NULL) {
Packit Service 3470d1
		fprintf(stderr, "Error allocating memory for firmware read back buffer\n");
Packit Service 3470d1
		if (sessionID>0) releaseSession(omgt_port_session, &path, sessionID);
Packit Service 3470d1
		goto err_exit;
Packit Service 3470d1
    }
Packit Service 3470d1
Packit Service 3470d1
	if (status == FSUCCESS) {
Packit Service 3470d1
		memset(fwBuffer2, 0, fwSize + 1024);
Packit Service 3470d1
Packit Service 3470d1
		status = opaswEepromRW(omgt_port_session, &path, sessionID, (void *)&mad, g_respTimeout,
Packit Service 3470d1
							   fwSize + 4, 0, (uint8 *)fwBuffer2, FALSE, g_gotSecondary);
Packit Service 3470d1
Packit Service 3470d1
		if (!g_quiet) {
Packit Service 3470d1
			printf("\n");
Packit Service 3470d1
			fflush(stdout);
Packit Service 3470d1
		}
Packit Service 3470d1
		if (status == FSUCCESS) {
Packit Service 3470d1
			u = (uint32 *)&fwBuffer2[fwSize];
Packit Service 3470d1
			crcEEPROM = *u;
Packit Service 3470d1
			crc = crc32(0, (uint8 *)&fwBuffer2[CSS_HEADER_SIZE + 4], fwSize - 4 - CSS_HEADER_SIZE);
Packit Service 3470d1
			if (crcEEPROM != crc) {
Packit Service 3470d1
				printf("Verification failed\n");
Packit Service 3470d1
				fprintf(stderr, "Error: CRC mismatch: 0x%08x : 0x%08x\n", ntoh32(crc), ntoh32(crcEEPROM));
Packit Service 3470d1
				status = FERROR;
Packit Service 3470d1
			} else {
Packit Service 3470d1
				if (g_verbose)
Packit Service 3470d1
					fprintf(stderr, "CRC match: 0x%08x : 0x%08x\n", ntoh32(crc), ntoh32(crcEEPROM));
Packit Service 3470d1
				printf("Verification succeeded\n");
Packit Service 3470d1
			}
Packit Service 3470d1
		}
Packit Service 3470d1
		// reset switch if necessary
Packit Service 3470d1
		if ((status == FSUCCESS) && g_resetSwitch) {
Packit Service 3470d1
			printf("Resetting switch...\n");
Packit Service 3470d1
			status = sendRebootMad(omgt_port_session, &path, sessionID, (VENDOR_MAD*)&mad, 2000);
Packit Service 3470d1
			if (status != FSUCCESS) {
Packit Service 3470d1
				fprintf(stderr, "%s: Error sending MAD packet to switch\n", cmdName);
Packit Service 3470d1
			}
Packit Service 3470d1
		}
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	if (!g_resetSwitch)
Packit Service 3470d1
		if (sessionID>0) releaseSession(omgt_port_session, &path, sessionID);
Packit Service 3470d1
Packit Service 3470d1
	printf("opaswfwupdate completed\n");
Packit Service 3470d1
Packit Service 3470d1
err_exit:
Packit Service 3470d1
	omgt_close_port(omgt_port_session);
Packit Service 3470d1
Packit Service 3470d1
	if (fwBuffer != NULL)
Packit Service 3470d1
		free(fwBuffer);
Packit Service 3470d1
Packit Service 3470d1
	if (fwBuffer2 != NULL)
Packit Service 3470d1
		free(fwBuffer2);
Packit Service 3470d1
Packit Service 3470d1
	if (status == FSUCCESS)
Packit Service 3470d1
		exit(0);
Packit Service 3470d1
	else
Packit Service 3470d1
		exit(1);
Packit Service 3470d1
Packit Service 3470d1
}