#! /bin/sh
# netlink v1.0 (2004-05-12)
# Solaris interface setup tool
# Copyright Anders Nordby <anders@fix.no>, initial version created 2002-01-19.

startup() {
# nada:
	:
# examples:
	forcefull bge0 100
#	forcefull bge1 1000
#	forcefull dmfe0
#	forcefull eri0
}

showmodes() {
	# $1: dev $2, $3..: params
	dev=$1
	for par in `echo $@ | xargs -n 1 echo | tail +2`
	do
		if [ "`ndd -get $dev $par | grep -v 'operation failed'`" = "1" ]
		then
			printval=`echo $par | sed "s/^lp_/adv/"`
			case $printval in
			'adv_autoneg_cap') printf "autonegotiation ";;
			'adv_1000fdx_cap') printf "1000BaseTX/full-duplex ";;
			'adv_1000hdx_cap') printf "1000BaseTX/half-duplex ";;
			'adv_100fdx_cap') printf "100BaseTX/full-duplex ";;
			'adv_100hdx_cap') printf "100BaseTX/half-duplex ";;
			'adv_100T4_cap') printf "100BaseT4 ";;
			'adv_10fdx_cap') printf "10BaseT/full-duplex ";;
			'adv_10hdx_cap') printf "10BaseT/half-duplex ";;
			esac
		fi
	done
}

setmodes() {
	# $1: dev $2: value $3, $4..: params
	dev=$1
	for par in `echo $@ | xargs -n 1 echo | tail +3`
	do
		ndd -set $dev $par $2 | grep -v 'operation failed'
	done
}

showstatus() {
# $1: driver $2: instance $3: lp (optional, for link partner)
	case $1 in
	dmfe|bge)
		device=/dev/$1$2
		currinstance=""
		;;
	*)
		device=/dev/$1
		currinstance="`ndd -get $device instance`"
		ndd -set $device instance $2
		;;
	esac

	case $3 in
	lp)
		printf "Link partner on $1$2 status:\n\t[ "
		showmodes $device lp_autoneg_cap lp_1000fdx_cap lp_1000hdx_cap lp_100fdx_cap lp_100hdx_cap lp_100T4_cap lp_10fdx_cap lp_10hdx_cap
		;;
	*)
		printf "Interface $1$2 status:\n\t[ "
		showmodes $device adv_autoneg_cap adv_1000fdx_cap adv_1000hdx_cap adv_100fdx_cap adv_100hdx_cap adv_100T4_cap adv_10fdx_cap adv_10hdx_cap
		;;
	esac
	printf "]\n"

	if [ ! -z "$currinstance" ]
	then
		ndd -set $device instance $currinstance
	fi
}

doforcefull() {
# $1: driver $2: instance $3: variant
	case $1 in
	dmfe|bge)
		device=/dev/$1$2
		currinstance=""
		;;
	*)
		device=/dev/$1
		currinstance="`ndd -get $device instance`"
		ndd -set $device instance $2
		;;
	esac

	printf "Forcing $1$2 to "
	case $3 in
	10)
		printf "10BaseTX full-duplex / no auto-negotiation .. "
		setmodes $device 0 adv_autoneg_cap adv_1000fdx_cap adv_1000hdx_cap adv_100fdx_cap adv_100hdx_cap adv_100T4_cap adv_10hdx_cap
		setmodes $device 1 adv_10fdx_cap
		;;
	100)
		printf "100BaseTX full-duplex / no auto-negotiation .. "
		setmodes $device 0 adv_autoneg_cap adv_1000fdx_cap adv_1000hdx_cap adv_100hdx_cap adv_100T4_cap adv_10fdx_cap adv_10hdx_cap
		setmodes $device 1 adv_100fdx_cap
		;;
	1000)
		printf "1000BaseTX full-duplex / no auto-negotiation .. "
		setmodes $device 0 adv_autoneg_cap adv_1000hdx_cap adv_100fdx_cap adv_100hdx_cap adv_100T4_cap adv_10fdx_cap adv_10hdx_cap
		setmodes $device 1 adv_1000fdx_cap
		;;
	esac

	setmodes $device 0 adv_autoneg_cap
	printf "OK\n"

	if [ ! -z "$currinstance" ]
	then
		ndd -set $device instance $currinstance
	fi
}

forcefull() {
	doforcefull "`echo $1 | tr -d '[:digit:]'`" "`echo $1 | tr -d '[:alpha:]'`" $2
}

dosetdefault() {
# $1: driver $2: instance
	case $1 in
	dmfe|bge)
		device=/dev/$1$2
		currinstance=""
		;;
	*)
		device=/dev/$1
		currinstance="`ndd -get $device instance`"
		ndd -set $device instance $2
		;;
	esac

	printf "Setting default media settings/options for interface $1$2 .. ";
	setmodes $device 1 adv_autoneg_cap adv_1000fdx_cap adv_1000hdx_cap adv_100fdx_cap adv_100hdx_cap adv_100T4_cap adv_10fdx_cap adv_10hdx_cap adv_autoneg_cap
	printf "OK\n"

	if [ ! -z "$currinstance" ]
	then
		ndd -set $device instance $currinstance
	fi
}

setdefault() {
	dosetdefault "`echo $1 | tr -d '[:digit:]'`" "`echo $1 | tr -d '[:alpha:]'`"
}

usage() {
	echo "Usage: $0 <status|statuslp|forcefull10|forcefull100|forcefull1000|setdefault> <interface>"
}

if [ -z "$2" -a "$1" != "start" ]
then
	usage
	exit 1
fi

instance="`echo $2 | tr -d '[:alpha:]'`"
driver="`echo $2 | tr -d '[:digit:]'`"

case $1 in
start) startup;;
status) showstatus $driver $instance;;
statuslp) showstatus $driver $instance lp;;
forcefull10|forcefull100|forcefull1000)
	forcefull $2 `echo $1 | tr -d '[:alpha:]'`
	;;
setdefault) setdefault $2;;
*) usage;;
esac
