#!/bin/bash
#
# Emulate the ifModeSet command on the 4.0 Linux-based switches.
# Requires mii-tool.
#
THIS_CP=$(/sbin/sin |/bin/grep "^Control Processor" |/bin/sed 's/^.*.: //g')
TMPFILE=/tmp/mii$$.cfg
FILE=/etc/fabos/mii.cfg
MNTFILE=/mnt$FILE
ADMIN=$(/usr/bin/id |/bin/sed 's/ .*//;s/^uid=//' |/bin/grep -E 'admin|root' |/bin/grep -E 'root|admin|factory')
CONSOLE=$(/usr/bin/tty |/bin/grep -E 'ttyS0|ttyS1')

SWBD=`/sbin/sin | /bin/sed -n -e 's/^.\+\(SWBD\)\([[:digit:]]\{1,\}\).\+$/\2/gp' 2> /dev/null`

function set_phy() {
	MII_MODES=${MII_MODES%,} 	# remove trailing comma
	echo "/sbin/mii-tool $MII_CMD $MII_MODES $IFACE" > $TMPFILE
	/fabos/libexec/ifmode_to_ethmode.sh $TMPFILE
	retval=$?
	if [ "$retval" == "0" ]; then
	echo -n "Committing configuration..."
	echo "/sbin/mii-tool $MII_CMD $MII_MODES $IFACE" > $FILE
	echo "/sbin/mii-tool $MII_CMD $MII_MODES $IFACE" > $MNTFILE
	#record a raslog
        /fabos/cliexec/errlogtest -i SWCH-1033 -a $IFACE
	fi
	/bin/rm -f $TMPFILE
	/fabos/rbin/sync
	echo "done."
}

function print_usage() {
	echo
	echo "Interactive Usage:"
	echo "-----------------"
	echo "  ifModeSet <interface>"
	echo "  Example:"
	echo "  ifModeSet \"eth0\""
	echo
	echo "Non Interactive Usage:"
	echo "---------------------"
	echo "  ifModeSet <interface> -an [ON|on|OFF|off] -speed [1000|100|10] -cap [FULL|full|HALF|half]"
	echo "  Example:"
	echo "  ifModeSet eth0 -an on -speed 100 -cap FULL"
	echo
	exit 1
}

function block_ifmodeset() {
	argc=$#
	argv=("$@")
	support=0
	for ((i=0;i<=$argc;i++))
	do 
		opt=${argv[$i]}
		if [ "$opt" == "-support" ]; then
			support=1
		fi
	done
	if [ $support -eq 0 ] ; then
		echo "This command is deprecated in Fabric OS v8.0.1. Please use command ethif."
		 exit 1
	fi
}
	
function decode_args() {
	argc=$# 
	argv=("$@")
	an=""
	speed=""
	cap=""
	for ((i=0;i<$argc;i++))
	do
		opt=${argv[$i]}
		opt_arg=${argv[$i+1]}

		if [ "$opt" == "-an" ]; then
			an=$opt_arg 					
			echo "an:$an"
		fi
		if [ "$opt" == "-speed" ]; then
			speed=$opt_arg 					
			echo "speed:$speed"
		fi
		if [ "$opt" == "-cap" ]; then
			cap=$opt_arg 					
			echo "cap:$cap"
		fi
		if [ "$opt" == "--help" ]; then
			print_usage
		fi
	done
	if [ "$an" == "" -o "$an" != "ON" -a "$an" != "OFF" -a "$an" != "on" -a "$an" != "off" ] ; then
		echo "Error: -an option missing or invalid value entered."
		validation_error=1
	fi
	if [ "$speed" == "" -o "$speed" != "1000" -a "$speed" != "100" -a "$speed" != "10" ] ; then
		echo "Error: -speed option missing or invalid value entered."
		validation_error=1
	fi
	if [ "$cap" == "" -o "$cap" != "FULL" -a "$cap" != "HALF" -a "$cap" != "full" -a "$cap" != "half" ] ; then
		echo "Error: -cap option missing or invalid value entered."
		validation_error=1
	fi
	if [ "$validation_error" == "1" ] ;  then
		print_usage
	fi
}

function process_args() {
	if [ "$an" == "ON" -o "$an" == "on" ] ; then
		MII_CMD="-A"	# auto-negotiate
		ADVERTISE="Advertise "
		DEFMODE="yes"
		auto=1
	elif [ "$an" == "OFF" -o "$an" == "off" ] ; then
		MII_CMD="-F"	# force
		ADVERTISE="Force "
		DEFMODE="no"
		auto=0
	fi
	echo "MII_CMD:$MII_CMD"
	echo "ADVERTISE:$ADVERTISE"
	echo "DEFMODE:$DEFMODE"
	echo "auto:$auto"
	if [ "$speed" == "1000" ] && ([ "$cap" == "FULL" -o "$cap" == "full" ]) ; then
		# echo "1"
		MII_MODES=$MII_MODES"1000baseT-FD,"
	fi
	if [ "$speed" == "1000" ] && ([ "$cap" == "HALF" -o "$cap" == "half" ]) ; then
		# echo "2"
		MII_MODES=$MII_MODES"1000baseT-HD,"
	fi
	if [ "$speed" == "100" ] && ([ "$cap" == "FULL" -o "$cap" == "full" ]) ; then
		# echo "3"
		MII_MODES=$MII_MODES"100baseTx-FD,"
	fi
	if [ "$speed" == "100" ] && ([ "$cap" == "HALF" -o "$cap" == "half" ]) ; then
		# echo "4"
		MII_MODES=$MII_MODES"100baseTx-HD,"
	fi
	if [ "$speed" == "10" ] && ([ "$cap" == "FULL" -o "$cap" == "full" ]) ; then
		# echo "5"
		MII_MODES=$MII_MODES"10baseT-FD,"
	fi
	if [ "$speed" == "10" ] && ([ "$cap" == "HALF" -o "$cap" == "half" ]) ; then
		# echo "6"
		MII_MODES=$MII_MODES"10baseT-HD,"
	fi
	# When forcing, we can only set one mode 
	echo "MII_MODE:$MII_MODES"
	if [ "$auto" = "0" ]; then 
		set_phy; 
		exit 0; 
	fi
}
# Check for command line arguments
arg_c=$#
block_ifmodeset $@

if [ "$arg_c" -gt 2 ]; then
	decode_args $@
fi

IFACE=$1
if [ "$IFACE" = "" ]; then
	echo "Error: <interface> not  specified."
	print_usage
fi

# bonding enable only on zentron
if [ $SWBD = 62 -o $SWBD = 77 -o $SWBD = 141 -o $SWBD = 142 -o $SWBD = 166 -o $SWBD = 165 ]; then
	if [ "$IFACE" != "eth0" ] && [ "$IFACE" != "eth3" ]; then
		echo "Error: ifModeSet can only be used with eth0 or eth3."
		exit 1
	fi
else
	if [ "$IFACE" != "eth0" ]; then
		echo "Error: ifModeSet can only be used with eth0."
		exit 1
	fi
fi

if [ "$ADMIN" = "" ]; then
	echo "Error: ifModeSet - Permission denied"
	exit 1
fi

if [ "$IFACE" = "eth3" ]; then
	FILE=/etc/fabos/mii.eth3.cfg
	MNTFILE=/mnt$FILE
fi

# populate $1,$2,$3,$4,$5,$6 with output of ethmode
set -- `/fabos/libexec/ethmode "$IFACE"`



# bit mask of link modes supported on this port
SUPPORTED=$4

MII_MODES=""

if [ "$CONSOLE" = "" ]; then
	echo
	echo "Exercise care when using this command.  Forcing the link to "
	echo "an operating mode not supported by the network equipment "
	echo "to which it is attached, may result in an inability to "
	echo "communicate with the system through its ethernet interface."
	echo 
	echo "It is recommended that you only use this command from the "
	echo "serial console port."
	echo 

	echo -n "Are you sure you really want to do this? (yes, y, no, n): [no] "
	read ans
	if [ "$ans" = "y" -o "$ans" = "yes" ]; then
		echo "Proceed with caution.";
	else
		echo "The link is not altered."
		exit 0;
	fi
fi

if [ "$arg_c" -gt 2 ]; then
	process_args
	set_phy		# do it
	exit 0;
fi

echo -n "Auto-negotiate (yes, y, no, n): [no] "
read ans
if [ "$ans" = "y" -o "$ans" = "yes" ]; then
	MII_CMD="-A"	# auto-negotiate
	ADVERTISE="Advertise "
	DEFMODE="yes"
	auto=1
else
	MII_CMD="-F"	# force
	ADVERTISE="Force "
	DEFMODE="no"
	auto=0
fi

# GigE interfaces over copper only work with autonegotiation enabled
let "SUP1000FD = $SUPPORTED & 32"
if [ "$auto" = "1" ] && [ $SUP1000FD -ne 0 ]; then
	echo -n "$ADVERTISE"
	echo -n "1000 Mbps / Full Duplex (yes, y, no, n): [$DEFMODE] "
	read ans
	if [ "$ans" = "" ]; then ans="$DEFMODE"; fi
	if [ "$ans" = "y" -o "$ans" = "yes" ]; then
		MII_MODES=$MII_MODES"1000baseT-FD,"
	fi
fi

let "SUP1000HD = $SUPPORTED & 16"
if [ "$auto" = "1" ] && [ $SUP1000HD -ne 0 ]; then
	echo -n "$ADVERTISE"
	echo -n "1000 Mbps / Half Duplex (yes, y, no, n): [$DEFMODE] "
	read ans
	if [ "$ans" = "" ]; then ans="$DEFMODE"; fi
	if [ "$ans" = "y" -o "$ans" = "yes" ]; then
		MII_MODES=$MII_MODES"1000baseT-HD,"
	fi
fi

# we assume that all ports support 100 or 10, FD or HD, autoneg or forced
# except on Graphite and Carbon. Graphite and Carbon support 1G only when
# in OEM chassis and 100M in test I/O environment.
if [ $SWBD -eq 157 -o $SWBD -eq 158 -o $SWBD -eq 176 -o $SWBD -eq 177 ]; then
	let "SUP100FD = $SUPPORTED & 8"
else
	let "SUP100FD = 1"
fi

if [ $SUP100FD -ne 0 ]; then
echo -n "$ADVERTISE"
echo -n "100 Mbps / Full Duplex (yes, y, no, n): [$DEFMODE] "
read ans
if [ "$ans" = "" ]; then ans="$DEFMODE"; fi
if [ "$ans" = "y" -o "$ans" = "yes" ]; then
	MII_MODES=$MII_MODES"100baseTx-FD,"
	# When forcing, we can only set one mode 
	if [ "$auto" = "0" ]; then set_phy; exit 0; fi
fi
fi

if [ $SWBD -ne 157 -a $SWBD -ne 158 -a $SWBD -ne 176 -a $SWBD -ne 177 ]; then
echo -n "$ADVERTISE"
echo -n "10 Mbps / Full Duplex (yes, y, no, n): [$DEFMODE] "
read ans
if [ "$ans" = "" ]; then ans="$DEFMODE"; fi
if [ "$ans" = "y" -o "$ans" = "yes" ]; then
	MII_MODES=$MII_MODES"10baseT-FD,"
	# When forcing, we can only set one mode 
	if [ "$auto" = "0" ]; then set_phy; exit 0; fi
fi
fi

if [ "$MII_MODES" = "" ]; then
	echo "You must select at least one link operating mode."
	exit 1
fi

set_phy		# do it
exit 0

