#!/usr/local/bin/bash

# This adapter config script is for the Chelsio T580 card to switch between 2x40G, 4x10G and QSA
#
#cat /usr/share/hwdata/pci.ids | grep T580- | grep 541
#        5410  T580-LP-CR Unified Wire Ethernet Controller
#        540d  T580-CR Unified Wire Ethernet Controller
#        5414  T580-LP-SO-CR Unified Wire Ethernet Controller

echo
vpd_dir=/usr/local/share/vpds
bin_dir=/usr/local/bin

# Test for lspci and pciconf - Not required anymore
#which lspci > /dev/null 2>&1
#if [ $? -ne 0 ]; then
#    echo "Error: lspci command not found. Please install pciutils package  and retry the command"
#    exit 1
#fi

which pciconf > /dev/null 2>&1
if [ $? -ne 0 ]; then
    echo "Error: pciconf command not found. Please install libpci package and retry the command"
    exit 1
fi


T580_LP_CR=`pciconf -l|grep "1425.*5410"|wc -l`
T580_CR=`pciconf -l|grep "1425.*540d"|wc -l`
T580_LP_SO_CR=`pciconf -l|grep "1425.*5414"|wc -l`

if [ "$T580_LP_CR" -gt 0 ] || [ "$T580_CR" -gt 0 ] || [ "$T580_LP_SO_CR" -gt 0 ]; then
	echo Chelsio T580 card detected
else
	echo Chelsio T580 card not detected
	exit 1
fi

#############################################################
# List Chelsio T580 devices                                 #
#############################################################
i=0
echo; 
echo "Chelsio T580 PCI devices :"
echo "|--------------------------------|"
devicelist=`pciconf -l|awk '{gsub("chip=","", $0); gsub("1425","",$4);print $4}'`

IS_DONE_T580_5414=0
IS_DONE_T580_540D=0
IS_DONE_T580_5410=0

for pci_dev in $devicelist
do
	device="$pci_dev"
	if [ "$device" == 0x5410 ]; then
		if [ "$IS_DONE_T580_5410" == 1 ]; then
                        continue
                fi

		t580_list=`pciconf -l |awk {'print $0'}|grep 0x5410|cut -d : -f 2 -f 3`
                num_devices=`echo $t580_list|wc -l`

		if [ "$num_devices" == 1 ]; then
			i=`echo "$i + 1" | bc`
			Devices[$i]=$pci_dev
			# Convert Bus and Dev from Decimal to Hex Values
			busd=`pciconf -l |awk {'print $0'}|grep 0x5410|cut -d : -f 2`
                        bush=`echo "obase=16; $busd" | bc`
                        devd=`pciconf -l |awk {'print $0'}|grep 0x5410|cut -d : -f 3`
                        devh=`echo "obase=16; $devd" | bc`
                        dev[$i]=$bush":"$devh".0"
			devd[$i]=$busd":"$devd".0"

			echo -e "| $i T580-LP-CR     ${devd[$i]}\t |"
		else
			for t580_dev in $t580_list
                        do
                                i=`echo "$i + 1" | bc`
				Devices[$i]=$pci_dev
				# Convert Bus and Dev from Decimal to Hex Values
				busd=`echo $t580_dev|cut -d : -f 1`
				bush=`echo "obase=16; $busd" | bc`
				devd=`echo $t580_dev|cut -d : -f 2`
				devh=`echo "obase=16; $devd" | bc`
				dev[$i]=$bush":"$devh".0"
				devd[$i]=$busd":"$devd".0"

				echo -e "| $i T580-LP-CR     ${devd[$i]}\t |"
                        done
		fi
		IS_DONE_T580_5410=1
	elif [ "$device" == 0x540d ]; then
		if [ "$IS_DONE_T580_540D" == 1 ]; then
                        continue
                fi

                t580_list=`pciconf -l |awk {'print $0'}|grep 0x540d|cut -d : -f 2 -f 3`
                num_devices=`echo $t580_list|wc -l`
		if [ "$num_devices" == 1 ]; then

			i=`echo "$i + 1" | bc`
			Devices[$i]=$pci_dev
			# Convert Bus and Dev from Decimal to Hex Values
			busd=`pciconf -l |awk {'print $0'}|grep 0x540d|cut -d : -f 2`
                        bush=`echo "obase=16; $busd" | bc`
                        devd=`pciconf -l |awk {'print $0'}|grep 0x540d|cut -d : -f 3`
                        devh=`echo "obase=16; $devd" | bc`
                        dev[$i]=$bush":"$devh".0"
			devd[$i]=$busd":"$devd".0"

			echo -e "| $i T580-CR        ${devd[$i]}\t |"
		else
                        for t580_dev in $t580_list
                        do
                                i=`echo "$i + 1" | bc`
				Devices[$i]=$pci_dev
				# Convert Bus and Dev from Decimal to Hex Values
				busd=`echo $t580_dev|cut -d : -f 1`
                                bush=`echo "obase=16; $busd" | bc`
                                devd=`echo $t580_dev|cut -d : -f 2`
                                devh=`echo "obase=16; $devd" | bc`
				dev[$i]=$bush":"$devh".0"
			 	devd[$i]=$busd":"$devd".0"

				echo -e "| $i T580-CR        ${devd[$i]}\t |"
                        done

		fi
		IS_DONE_T580_540D=1

	elif [ "$device" == 0x5414 ]; then
		if [ "$IS_DONE_T580_5414" == 1 ]; then
			continue
		fi

		t580_list=`pciconf -l |awk {'print $0'}|grep 0x5414|cut -d : -f 2 -f 3`
		num_devices=`echo $t580_list|wc -l`
		if [ "$num_devices" == 1 ]; then
			i=`echo "$i + 1" | bc`
			Devices[$i]=$pci_dev
			# Convert Bus and Dev from Decimal to Hex Values
			busd=`pciconf -l |awk {'print $0'}|grep 0x5414|cut -d : -f 2`
			bush=`echo "obase=16; $busd" | bc`
			devd=`pciconf -l |awk {'print $0'}|grep 0x5414|cut -d : -f 3`
			devh=`echo "obase=16; $devd" | bc`
			dev[$i]=$bush":"$devh".0"
			devd[$i]=$busd":"$devd".0"

			echo -e "| $i T580-SO-CR     ${devd[$i]}\t |"
		else
			for t580_dev in $t580_list
			do
				i=`echo "$i + 1" | bc`
				Devices[$i]=$pci_dev
				# Convert Bus and Dev from Decimal to Hex Values
				busd=`echo $t580_dev|cut -d : -f 1`
                                bush=`echo "obase=16; $busd" | bc`
                                devd=`echo $t580_dev|cut -d : -f 2`
                                devh=`echo "obase=16; $devd" | bc`
				dev[$i]=$bush":"$devh".0"
				devd[$i]=$busd":"$devd".0"

				echo -e "| $i T580-SO-CR     ${devd[$i]}\t |"
			done
		fi
		IS_DONE_T580_5414=1
	fi
done
echo "|--------------------------------|"; echo

# echo "Before 'Please select device to modify'"
# echo ${Devices[1]}
# echo ${dev[1]}

#############################################################
# Select device to modify                                   #
#############################################################
dev_in=1
if [ $i -ne 1 ]; then
	echo -n "Please select device to modify [$dev_in]: "
	read dev_in
	echo
	if [ -z $dev_in ]; then dev_in=1; fi

	printf "%s\n" $dev_in |grep -E "^[+-]?[0-9]+$" > /dev/null
	if [ "$?" == 0 ]; then
		if [ $dev_in -lt 1 ]; then
			echo "Illegal index selected, quitting..."; echo
			exit 1;
		fi

		device=`echo ${Devices[$dev_in]} 2> /dev/null`
        	if [ "$device" == 0x5410 ]; then
                        #dev=`pciconf -l |awk {'print $0'}|grep 0x5410|cut -d : -f 2 -f 3`
			dev=${dev[$dev_in]}
        	elif [ "$device" == 0x540d ]; then
			dev=`pciconf -l |awk {'print $0'}|grep 0x540d|cut -d : -f 2 -f 3`
                        dev=${dev[$dev_in]}
        	elif [ "$device" == 0x5414 ]; then
			dev=`pciconf -l |awk {'print $0'}|grep 0x5414|cut -d : -f 2 -f 3`
			dev=${dev[$dev_in]}
		else
			echo "Illegal value selected, quitting..."; echo
			exit 1
		fi
	else
		echo "Numeric value expected, quitting..."; echo
		exit 1
	fi
else
	device=`echo ${Devices[1]}`
	#dev=`pciconf -l |awk {'print $0'}|grep $device|cut -d : -f 2 -f 3`
	dev=${dev[1]}

fi

# echo "Before 'Possible T580 adapter modes:'"
# echo $device
# echo $dev

echo "Possible T580 adapter modes: "
echo "|------------------------------|"
echo "| 1: 2x40G                     |"
echo "| 2: 4x10G                     |"
echo "| 3: QSA                       |"
echo "|------------------------------|"
echo
echo -n "Select mode for adapter (1,2,3): "
read mode
echo

	
# dev=`echo ${dev[$dev_in]}|cut -c -6`
# dev=$dev"0"

if [ "$mode" == 1 ]; then 
	echo Programming mode 1: 2x40G 
	echo
	#echo $dev
	if [ "$device" == 0x5410 ]; then #T580-LP-CR 2x40G
		echo $bin_dir/t5seeprom -b $dev write -fvpd:$vpd_dir/t580_lp_cr_variable_2133_vpd.bin
		$bin_dir/t5seeprom -b $dev write -fvpd:$vpd_dir/t580_lp_cr_variable_2133_vpd.bin
	elif [ "$device" == 0x540d ]; then #T580-CR 2x40G
		echo $bin_dir/t5seeprom -b $dev write -fvpd:$vpd_dir/t580_cr_variable_2133_vpd.bin
		$bin_dir/t5seeprom -b $dev write -fvpd:$vpd_dir/t580_cr_variable_2133_vpd.bin
	elif [ "$device" == 0x5414 ]; then #T580-LP-SO-CR 2x40G
		echo $bin_dir/t5seeprom -b $dev write -fvpd:$vpd_dir/t580_lp_so_variable_vpd.bin
		$bin_dir/t5seeprom -b $dev write -fvpd:$vpd_dir/t580_lp_so_variable_vpd.bin
	fi
	echo
	echo "Please reboot the machine for the changes to take effect"
elif [ "$mode" == 2 ]; then 
	echo Programming mode 2: 4x10G 
	echo
	if [ "$device" == 0x5410 ]; then #T580-LP-CR 4x10G
		echo $bin_dir/t5seeprom -b $dev write -fvpd:$vpd_dir/t580_lp_cr_spider_variable_2133_vpd.bin
		$bin_dir/t5seeprom -b $dev write -fvpd:$vpd_dir/t580_lp_cr_spider_variable_2133_vpd.bin
	elif [ "$device" == 0x540d ]; then #T580-CR 4x10G
		echo $bin_dir/t5seeprom -b $dev write -fvpd:$vpd_dir/t580_cr_spider_variable_2133_vpd.bin
		$bin_dir/t5seeprom -b $dev write -fvpd:$vpd_dir/t580_cr_spider_variable_2133_vpd.bin
	elif [ "$device" == 0x5414 ]; then #T580-LP-SO-CR 4x10G
		echo $bin_dir/t5seeprom -b $dev write -fvpd:$vpd_dir/t580_lp_so_spider_variable_2133_vpd.bin
		$bin_dir/t5seeprom -b $dev write -fvpd:$vpd_dir/t580_lp_so_spider_variable_2133_vpd.bin
	fi
	echo
	echo "Please reboot the machine for the changes to take effect"

elif [ "$mode" == 3 ]; then 
	echo Programming mode 3: QSA
	echo
	if [ "$device" == 0x5410 ]; then #T580-LP-CR QSA 
		echo $bin_dir/t5seeprom -b $dev write -fvpd:$vpd_dir/t580_lp_cr_qsa_variable_2133_vpd.bin
		$bin_dir/t5seeprom -b $dev write -fvpd:$vpd_dir/t580_lp_cr_qsa_variable_2133_vpd.bin
	elif [ "$device" == 0x540d ]; then #T580-CR QSA 
		echo $bin_dir/t5seeprom -b $dev write -fvpd:$vpd_dir/t580_cr_qsa_variable_2133_vpd.bin
 		$bin_dir/t5seeprom -b $dev write -fvpd:$vpd_dir/t580_cr_qsa_variable_2133_vpd.bin
	elif [ "$device" == 0x5414 ]; then #T580-LP-SO-CR QSA 
		echo $bin_dir/t5seeprom -b $dev write -fvpd:$vpd_dir/t580_lp_so_qsa_variable_vpd.bin
		$bin_dir/t5seeprom -b $dev write -fvpd:$vpd_dir/t580_lp_so_qsa_variable_vpd.bin
	fi
	echo
	echo "Please reboot the machine for the changes to take effect"
else
	echo Programming mode 1: 2x40G or mode 2: 4x10G or mode 3: QSA  not selected; 
fi

echo
