#! /bin/bash
#
# Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# This software product is a proprietary product of Mellanox Technologies Ltd.
# (the "Company") and all right, title, and interest in and to the software
# product, including all associated intellectual property rights, are and
# shall remain exclusively with the Company.
#
# This software product is governed by the End User License Agreement
# provided with the software product.
#

mftconfig=mstconfig
if [ -x /usr/bin/mlxconfig ]; then
	mftconfig=mlxconfig
fi

get_eswitch_mode()
{
	pci_dev=$1
	shift

	devlink dev eswitch show pci/${pci_dev} 2> /dev/null | cut -d ' ' -f 3
}

emu_manager=`lspci -nD -d 15b3: | grep 'a2d[26]\|101d' | cut -d ' ' -f 1 | head -n 1`

eswitch_mode="get_eswitch_mode ${emu_manager}"

COUNT=0
until [ $COUNT -eq 120 ] || [ "`${eswitch_mode}`" == "switchdev" ]; do
	sleep 1
	let $(( COUNT++ ))
done

if [ "`${eswitch_mode}`" != "switchdev" ]; then
	echo "${emu_manager} is not in switch dev mode"
	exit 2
fi

configs=`$mftconfig -d ${emu_manager} q`

if [[ -z `echo "$configs" 2> /dev/null | grep "VIRTIO_NET_EMULATION_ENABLE.*True(1)"` ]]; then
	echo "${emu_manager} doesn't have VIRTIO_NET_EMULATION_ENABLE set"
	exit 1
fi

recovery_dir="/opt/mellanox/mlnx_virtnet/recovery"

fields=(PF_BAR2_ENABLE \
	PER_PF_NUM_SF \
	PCI_SWITCH_EMULATION_ENABLE \
	PCI_SWITCH_EMULATION_NUM_PORT \
	VIRTIO_NET_EMULATION_NUM_VF \
	VIRTIO_NET_EMULATION_NUM_PF \
	VIRTIO_NET_EMULATION_NUM_MSIX \
	SRIOV_EN \
	PF_SF_BAR_SIZE \
	PF_TOTAL_SF)

fields_str=""
for f in ${fields[@]};
do
	if [[ $fields_str != "" ]]; then
		fields_str="${fields_str}|${f}"
	else
		fields_str="${f}"
	fi
done

mlxconfig_cur=`echo "$configs" | grep -E $fields_str | tr -s ' '`

if [[ ! -f "${recovery_dir}/.mlxconfig_save" ]]; then
	mkdir -p ${recovery_dir}
	echo "$mlxconfig_cur" > ${recovery_dir}/.mlxconfig_save
	exit 0
fi

mlxconfig_save=`cat ${recovery_dir}/.mlxconfig_save | grep -E $fields_str | tr -s ' '`

for f in ${fields[@]};
do
	val_save=`echo "$mlxconfig_save" | grep -n $f | cut -d ' ' -f 4`
	val_cur=`echo "$mlxconfig_cur" | grep -n $f | cut -d ' ' -f 4`
	if [[ "$val_save" != "$val_cur" ]]; then
		echo "$mlxconfig_cur" > ${recovery_dir}/.mlxconfig_save
		cd $recovery_dir
		find . -type f -not \( -name ".virtnet_conf_save" -or -name ".mlxconfig_save" \) -delete
		exit 0
	fi
done

is_lag_cur=`cat "$virtnet_dir/virtnet.conf" | grep -E "is_lag" | tr -s ' ' | \
			cut -d ':' -f 2 | cut -d ',' -f 1 | awk '{$1=$1};1'`

if [[ -z "${is_lag_cur}" ]]; then
	exit 0
fi

if [[ ! -f "${recovery_dir}/.virtnet_conf_save" ]]; then
	mkdir -p ${recovery_dir}
	cp "${virtnet_dir}/virtnet.conf" "${recovery_dir}/.virtnet_conf_save"
	exit 0
fi

is_lag_save=`cat "${recovery_dir}/.virtnet_conf_save" | grep -E "is_lag" | \
			 tr -s ' '| cut -d ':' -f 2 | cut -d ',' -f 1 | awk '{$1=$1};1'`

if [[ "$is_lag_save" != "$is_lag_cur" ]]; then
	cp "${virtnet_dir}/virtnet.conf" "${recovery_dir}/.virtnet_conf_save"
	cd $recovery_dir
	find . -type f -not \( -name ".virtnet_conf_save" -or -name ".mlxconfig_save" \) -delete
	exit 0
fi

exit 0
