#!/bin/sh
#
# Copyright (c) 2019-2020 Citrix Systems, Inc. All rights reserved.
# This software and documentation contain valuable trade
# secrets and proprietary property belonging to Citrix Systems, Inc.
# None of this software and documentation may be copied,
# duplicated or disclosed without the express
# written permission of Citrix Systems, Inc.
#
# 11/19/19
#
# This file contains shell script code needed for
# Fortville NIC firmware update.
#
# usage:  sh fortville_fw_update <optional firmware version>
#

SPECIFIED_FW_VERSION=${1}

FW_UPDATE_VERS_DEFAULT=7.00
SCRIPTS_DIR=/var/tmp/Fortville_Silicom_Intel/scripts
FW_PARM_FILE_NAME=.fortville_firmware_upgrade_parm_file
PARM_FILE=${SCRIPTS_DIR}/${FW_PARM_FILE_NAME}
NSCONFIG=/nsconfig
FW_UPDATE_SUBR="./fortville_fw_update_subr"

#
# Load the subroutine file
#
if [ -f ${FW_UPDATE_SUBR} ]
then
	. ${FW_UPDATE_SUBR}
else
	echo ">>> Missing ${FW_UPDATE_SUBR} file!"
	exit 100
fi

log_msg ">>> ================================================================"
log_msg ">>> Invoking fortville_fw_update script $(date)"

has_silicom_nics
HAS_SILICOM=$?
if [ ${HAS_SILICOM} -eq 0 ]
then
	log_msg ">>> Has Silicom NICs"
else
	log_msg ">>> Does not have Silicom NICs"
fi

has_intel_nics
HAS_INTEL=$?
if [ ${HAS_INTEL} -eq 0 ]
then
	log_msg ">>> Has Intel NICs"
else
	log_msg ">>> Does not have Intel NICs"
fi

#
# Bail out if there are no Fortville NICs in this system.
#
if [ $HAS_SILICOM -ne 0 ] && [ $HAS_INTEL -ne 0 ]
then
	echo "does not have Silicom or Intel"
	echo "Silicom = $HAS_SILICOM Intel = $HAS_INTEL"
	log_msg ">>> This NetScaler does not contain any Fortville NICs."
	log_msg ">>> Exiting Fortville firmware update script."
	exit 101
else
	log_msg ">>> has at least one of Silicom and Intel NICs"
	#echo ">>> Silicom = $HAS_SILICOM, Intel = $HAS_INTEL"
fi

#
# Bail out if the kernel does not support Fortville firmware update
#
sysctl dev.ixl.0.en_firmware_update > /dev/null 2>&1
SYSCTL_RET=$?
if [ ${SYSCTL_RET} -ne 0 ]
then
	# kernel without FW update support returns 1
	echo "sysctl did not return 0, ${SYSCTL_RET}"
	log_msg ">>> Installed kernel does not support Fortville firmware" \
	    "update:  ${SYSCTL_RET}"
	log_msg ">>> Exiting Fortville firmware update script."
	exit 102
else
	# kernel with FW update support returns 0
	#echo "sysctl returned 0, ${SYSCTL_RET}"
fi

#
# If a firmware version argument is passed in, use it.
# Else, choose the current default.
#
if [ "x${SPECIFIED_FW_VERSION}" = "x" ]
then
	log_msg ">>> Target firmware version not passed in"
	FW_UPDATE_VERS=${FW_UPDATE_VERS_DEFAULT}
else
	log_msg ">>> Target firmware version passed in: " \
	    "${SPECIFIED_FW_VERSION}"
	FW_UPDATE_VERS=${SPECIFIED_FW_VERSION}
fi


#
# Write initial state and loop values in the parameter file.
# FW_UPDATE_VERS:
#   target firmware version string (set above)
# FW_UPDATE_STATE:
#   0:   Update (updating) Silicom NICs
#   10:  Update (updating) Intel NICs
# FW_UPDATE_LOOP_COUNT:
#   number of times we have attempted to update this family of NICs
#   - note:  5 attempts per NIC vendor is the current maximum
#
FW_UPDATE_STATE=0
FW_UPDATE_LOOP_COUNT=0

write_parms_to_file $PARM_FILE

#
# If firmware update state machine script does not exist, exit.
# Fixme:  Need to check for other scripts.
#
if [ ! -e ${SCRIPTS_DIR}/fortville_fw_update_state_machine ]
then
        log_msg ">>> ${SCRIPTS_DIR}/fortville_fw_update_state_machine does not exist!"
        exit 103
else
        # reboot into developer mode
        touch /nsconfig/.developer
	# copy script to rc.local; it will be automatically invoked after reboot
        /bin/cp ${SCRIPTS_DIR}/fortville_fw_update_state_machine ${NSCONFIG}/rc.local
        log_msg ">>> Performing initial reboot for firmware update..."
	sleep 1
        reboot
fi


exit 202

