#!/bin/bash
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright (c) 2020 Mellanox Technologies. All rights reserved.
#
# This Software is licensed under one of the following licenses:
#
# 1) under the terms of the "Common Public License 1.0" a copy of which is
#    available from the Open Source Initiative, see
#    http://www.opensource.org/licenses/cpl.php.
#
# 2) under the terms of the "The BSD License" a copy of which is
#    available from the Open Source Initiative, see
#    http://www.opensource.org/licenses/bsd-license.php.
#
# 3) under the terms of the "GNU General Public License (GPL) Version 2" a
#    copy of which is available from the Open Source Initiative, see
#    http://www.opensource.org/licenses/gpl-license.php.
#
# Licensee has the right to choose one of the above licenses.
#
# Redistributions of source code must retain the above copyright
# notice and one of the license notices.
#
# Redistributions in binary form must reproduce both the above copyright
# notice, one of the license notices in the documentation
# and/or other materials provided with the distribution.

PATH=/opt/mellanox/iproute2/sbin:/bin:/sbin:/usr/bin:/usr/sbin

RC=0

is_bf=`lspci -s 00:00.0 2> /dev/null | grep -wq "PCI bridge: Mellanox Technologies" && echo 1 || echo 0`
if [ $is_bf -ne 1 ]; then
	exit 0
fi

prog=`basename $0`

PID=$(pgrep -oxf "/bin/bash /sbin/$prog")
if [ $$ -ne $PID ] ; then
        # $prog is running already with PID: $PID
        exit 0
fi

get_steering_mode()
{
	pci_dev=$1
	shift

	cat /sys/bus/pci/devices/${pci_dev}/net/*/compat/devlink/steering_mode 2> /dev/null
}

set_steering_mode()
{
	pci_dev=$1
	mode=$2
	shift 2

	# devlink dev param set pci/${pci_dev} name flow_steering_mode value "${mode}" cmode runtime
	echo ${mode} > /sys/bus/pci/devices/${pci_dev}/net/*/compat/devlink/steering_mode
	rc=$?
	if [ $rc -ne 0 ]; then
		logger -t $prog -i "Failed to configure steering mode ${mode} for ${pci_dev}"
	else
		logger -t $prog -i "Configured mode steering ${mode} for ${pci_dev}"
	fi

	return $rc
}

get_eswitch_mode()
{
	pci_dev=$1
	shift

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

set_eswitch_mode()
{
	pci_dev=$1
	mode=$2
	shift 2

	devlink dev eswitch set pci/${pci_dev} mode ${mode}
	rc=$?
	if [ $rc -ne 0 ]; then
		logger -t $prog -i "Failed to configure ${mode} mode for ${pci_dev}"
	else
		logger -t $prog -i "Configured ${mode} mode for ${pci_dev}"
	fi

	return $rc
}

for dev in `lspci -nD -d 15b3: | grep 'a2d[26]' | cut -d ' ' -f 1`
do
	if (mstconfig -e -d ${dev} q 2> /dev/null | grep LINK_TYPE_P | awk '{print $4}' | grep -q "IB(1)"); then
		logger -t $prog -i "Link type is IB for ${dev}. Skipping mode confiugration."
		continue
	fi

	if (mstconfig -d ${dev} q 2> /dev/null | grep -q "ECPF_ESWITCH_MANAGER.*ECPF(1)"); then
		steering_mode=`get_steering_mode ${dev}`
		if [ "${steering_mode}" == "dmfs" ]; then
			eswitch_mode=`get_eswitch_mode ${dev}`
			if [ "${eswitch_mode}" == "switchdev" ]; then
				set_eswitch_mode ${dev} legacy
				RC=$((RC+$?))
			fi

			set_steering_mode ${dev} smfs
			RC=$((RC+$?))
		fi
		eswitch_mode=`get_eswitch_mode ${dev}`
		if [ "${eswitch_mode}" != "switchdev" ]; then
			set_eswitch_mode ${dev} switchdev
			RC=$((RC+$?))
		fi
	fi
done

if [ -f /etc/mellanox/mlnx-sf.conf ]; then
	. /etc/mellanox/mlnx-sf.conf
fi

exit $RC
