Blame IbaTools/opasw/opaswfwupdate/opaswfwupdate.c

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