# bash completion for ethtool(8)                          -*- shell-script -*-
# shellcheck shell=bash disable=SC2207

# Complete a word representing a set of characters.
# @param $@ chars	Characters which may be present in completed set.
_ethtool_compgen_letterset()
{
	local char
	for char; do
		case "$cur" in
			*"$char"*)
				# $cur already contains $char
				;;
			*)
				COMPREPLY+=( "$cur$char" )
				;;
		esac
	done
}

# Generate completions for words matched case-insensitively
# @param $@ choices	Completion choices.
_ethtool_compgen_nocase()
{
	local reset
	reset=$( shopt -p nocasematch )
	shopt -s nocasematch

	local choice
	for choice; do
		case "$choice" in
			"$cur"*) COMPREPLY+=( "$choice" ) ;;
		esac
	done

	$reset
}

# Gets names from a section of ethtool output.
# @param $1 section_bre	POSIX BRE matching section heading (without : at end).
# @param $@		ethtool arguments
_ethtool_get_names_in_section()
{
	local section_bre="$1"
	shift

	PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin" \
		ethtool "$@" 2>/dev/null |
		command sed -n "
# Line is section heading iff it ends with :
# From requested section heading to next section heading
/^$section_bre:$/,/:$/ {
	# If line is section heading, ignore it
	/:$/d
	# Remove value and separator, if present
	s/[[:space:]]*:.*//
	# Remove leading space, if present
	s/^[[:space:]]*//
	# Print the line
	p
}"
}

# Complete an RSS Context ID
_ethtool_context()
{
	COMPREPLY=(
		$(PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin" \
			ethtool --show-nfc "${words[2]}" 2>/dev/null |
			command sed -n 's/^[[:space:]]*RSS Context ID:[[:space:]]*\([0-9]*\)$/\1/p' |
			sort -u) )
}

# Complete a network flow traffic type
# Available OPTIONS:
#	 --hash  Complete only types suitable for rx hashing
_ethtool_flow_type()
{
	local types='ah4 ah6 esp4 esp6 ether sctp4 sctp6 tcp4 tcp6 udp4 udp6'
	if [ "${1-}" != --hash ]; then
		types="$types ip4 ip6"
	fi
	COMPREPLY=( $( compgen -W "$types" -- "$cur" ) )
}

# Completion for ethtool --change
_ethtool_change()
{
	local -A settings=(
		[advertise]=notseen
		[autoneg]=notseen
		[duplex]=notseen
		[mdix]=notseen
		[msglvl]=notseen
		[port]=notseen
		[phyad]=notseen
		[speed]=notseen
		[wol]=notseen
		[xcvr]=notseen
	)

	local -A msgtypes=(
		[drv]=notseen
		[hw]=notseen
		[ifdown]=notseen
		[ifup]=notseen
		[intr]=notseen
		[link]=notseen
		[pktdata]=notseen
		[probe]=notseen
		[rx_err]=notseen
		[rx_status]=notseen
		[timer]=notseen
		[tx_done]=notseen
		[tx_err]=notseen
		[tx_queued]=notseen
		[wol]=notseen
	)

	# Mark seen settings and msgtypes, and whether in msglvl sub-command
	local in_msglvl=
	local word
	for word in "${words[@]:3:${#words[@]}-4}"; do
		if [ "$in_msglvl" ] && [ "${msgtypes[$word]+set}" ]; then
			msgtypes[$word]=seen
		elif [ "${settings[$word]+set}" ]; then
			settings[$word]=seen
			if [ "$word" = msglvl ]; then
				in_msglvl=1
			else
				in_msglvl=
			fi
		fi
	done

	if [ "$in_msglvl" ] && [ "${msgtypes[$prev]+set}" ]; then
		# All msgtypes take an on/off argument
		COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) )
		return
	fi

	case "$prev" in
		advertise)
			# Hex number
			return ;;
		autoneg)
			COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) )
			return ;;
		duplex)
			COMPREPLY=( $( compgen -W 'half full' -- "$cur" ) )
			return ;;
		mdix)
			COMPREPLY=( $( compgen -W 'auto on off' -- "$cur" ) )
			return ;;
		msglvl)
			# Unsigned integer or msgtype
			COMPREPLY=( $( compgen -W "${!msgtypes[*]}" -- "$cur" ) )
			return ;;
		port)
			COMPREPLY=( $( compgen -W 'aui bnc fibre mii tp' -- "$cur" ) )
			return ;;
		phyad)
			# Integer
			return ;;
		sopass)
			_mac_addresses
			return ;;
		speed)
			# Number
			return ;;
		wol)
			# $cur is a set of wol type characters.
			_ethtool_compgen_letterset p u m b a g s f d
			return ;;
		xcvr)
			COMPREPLY=( $( compgen -W 'internal external' -- "$cur" ) )
			return ;;
	esac

	local -a comp_words=()

	# Add settings not seen to completions
	local setting
	for setting in "${!settings[@]}"; do
		if [ "${settings[$setting]}" = notseen ]; then
			comp_words+=( "$setting" )
		fi
	done

	# Add settings not seen to completions
	if [ "$in_msglvl" ]; then
		local msgtype
		for msgtype in "${!msgtypes[@]}"; do
			if [ "${msgtypes[$msgtype]}" = notseen ]; then
				comp_words+=( "$msgtype" )
			fi
		done
	fi

	COMPREPLY=( $( compgen -W "${comp_words[*]}" -- "$cur" ) )
}

# Completion for ethtool --change-eeprom
_ethtool_change_eeprom()
{
	local -A settings=(
		[length]=1
		[magic]=1
		[offset]=1
		[value]=1
	)

	if [ "${settings[$prev]+set}" ]; then
		# All settings take an unsigned integer argument
		return
	fi

	# Remove settings which have been seen
	local word
	for word in "${words[@]:3:${#words[@]}-4}"; do
		unset "settings[$word]"
	done

	COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) )
}

# Completion for ethtool --coalesce
_ethtool_coalesce()
{
	local -A settings=(
		[adaptive-rx]=1
		[adaptive-tx]=1
		[pkt-rate-high]=1
		[pkt-rate-low]=1
		[rx-frames]=1
		[rx-frames-high]=1
		[rx-frames-irq]=1
		[rx-frames-low]=1
		[rx-usecs]=1
		[rx-usecs-high]=1
		[rx-usecs-irq]=1
		[rx-usecs-low]=1
		[sample-interval]=1
		[stats-block-usecs]=1
		[tx-frames]=1
		[tx-frames-high]=1
		[tx-frames-irq]=1
		[tx-frames-low]=1
		[tx-usecs]=1
		[tx-usecs-high]=1
		[tx-usecs-irq]=1
		[tx-usecs-low]=1
	)

	case "$prev" in
		adaptive-rx|\
		adaptive-tx)
			COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) )
			return ;;
	esac

	if [ "${settings[$prev]+set}" ]; then
		# Unsigned integer
		return
	fi

	# Remove settings which have been seen
	local word
	for word in "${words[@]:3:${#words[@]}-4}"; do
		unset "settings[$word]"
	done

	COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) )
}

# Completion for ethtool --config-nfc <devname> flow-type
_ethtool_config_nfc_flow_type()
{
	if [ "$cword" -eq 4 ]; then
		_ethtool_flow_type --spec
		return
	fi

	case "$prev" in
		context)
			_ethtool_context
			return ;;
		dst|\
		dst-mac|\
		src)
			# TODO: Complete only local for dst and remote for src
			_mac_addresses
			return ;;
		dst-ip)
			# Note: RX classification, so dst is usually local
			case "${words[4]}" in
				*4) _ip_addresses -4 return ;;
				*6) _ip_addresses -6 return ;;
			esac
			return ;;
		src-ip)
			# Note: RX classification, so src is usually remote
			# TODO: Remote IP addresses (ARP cache + /etc/hosts + ?)
			return ;;
		m|\
		*-mask)
			# MAC, IP, or integer bitmask
			return ;;
	esac

	local -A settings=(
		[action]=1
		[context]=1
		[loc]=1
		[queue]=1
		[vf]=1
	)

	if [ "${settings[$prev]+set}" ]; then
		# Integer
		return
	fi

	case "${words[4]}" in
		ah4|\
		esp4)
			local -A fields=(
				[dst-ip]=1
				[dst-mac]=1
				[spi]=1
				[src-ip]=1
				[tos]=1
				[user-def]=1
				[vlan-etype]=1
				[vlan]=1
			)
			;;
		ah6|\
		esp6)
			local -A fields=(
				[dst-ip]=1
				[dst-mac]=1
				[spi]=1
				[src-ip]=1
				[tclass]=1
				[user-def]=1
				[vlan-etype]=1
				[vlan]=1
			)
			;;
		ether)
			local -A fields=(
				[dst]=1
				[proto]=1
				[src]=1
				[user-def]=1
				[vlan-etype]=1
				[vlan]=1
			)
			;;
		ip4)
			local -A fields=(
				[dst-ip]=1
				[dst-mac]=1
				[dst-port]=1
				[l4data]=1
				[l4proto]=1
				[spi]=1
				[src-ip]=1
				[src-port]=1
				[tos]=1
				[user-def]=1
				[vlan-etype]=1
				[vlan]=1
			)
			;;
		ip6)
			local -A fields=(
				[dst-ip]=1
				[dst-mac]=1
				[dst-port]=1
				[l4data]=1
				[l4proto]=1
				[spi]=1
				[src-ip]=1
				[src-port]=1
				[tclass]=1
				[user-def]=1
				[vlan-etype]=1
				[vlan]=1
			)
			;;
		sctp4|\
		tcp4|\
		udp4)
			local -A fields=(
				[dst-ip]=1
				[dst-mac]=1
				[dst-port]=1
				[src-ip]=1
				[src-port]=1
				[tos]=1
				[user-def]=1
				[vlan-etype]=1
				[vlan]=1
			)
			;;
		sctp6|\
		tcp6|\
		udp6)
			local -A fields=(
				[dst-ip]=1
				[dst-mac]=1
				[dst-port]=1
				[src-ip]=1
				[src-port]=1
				[tclass]=1
				[user-def]=1
				[vlan-etype]=1
				[vlan]=1
			)
			;;
		*)
			return ;;
	esac

	if [ "${fields[$prev]+set}" ]; then
		# Integer
		return
	fi

	# If the previous 2 words were a field+value, suggest a mask
	local mask=
	if [ "${fields[${words[$cword-2]}]+set}" ]; then
		mask="m ${words[$cword-2]}-mask"
	fi

	# Remove fields and settings which have been seen
	local word
	for word in "${words[@]:5:${#words[@]}-6}"; do
		unset "fields[$word]" "settings[$word]"
	done

	# Remove mutually-exclusive options
	if ! [ "${settings[action]+set}" ]; then
		unset 'settings[queue]' 'settings[vf]'
	fi
	if ! [ "${settings[queue]+set}" ]; then
		unset 'settings[action]'
	fi
	if ! [ "${settings[vf]+set}" ]; then
		unset 'settings[action]'
	fi

	COMPREPLY=( $( compgen -W "$mask ${!fields[*]} ${!settings[*]}" -- "$cur" ) )
}

# Completion for ethtool --config-nfc
_ethtool_config_nfc()
{
	if [ "$cword" -eq 3 ]; then
		COMPREPLY=( $( compgen -W 'delete flow-type rx-flow-hash' -- "$cur" ) )
		return
	fi

	case "${words[3]}" in
		delete)
			# Unsigned integer
			return ;;
		flow-type)
			_ethtool_config_nfc_flow_type
			return ;;
		rx-flow-hash)
			case "$cword" in
				4)
					_ethtool_flow_type --hash
					return ;;
				5)
					_ethtool_compgen_letterset m v t s d f n r
					return ;;
				6)
					COMPREPLY=( $( compgen -W context -- "$cur" ) )
					return ;;
				7)
					_ethtool_context
					return ;;
			esac
			return ;;
	esac
}

# Completion for ethtool --eeprom-dump
_ethtool_eeprom_dump()
{
	local -A settings=(
		[length]=1
		[offset]=1
		[raw]=1
	)

	if [ "$prev" = raw ]; then
		COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) )
		return
	fi

	if [ "${settings[$prev]+set}" ]; then
		# Unsigned integer argument
		return
	fi

	# Remove settings which have been seen
	local word
	for word in "${words[@]:3:${#words[@]}-4}"; do
		unset "settings[$word]"
	done

	COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) )
}

# Completion for ethtool --features
_ethtool_features()
{
	local -A abbreviations=(
		[generic-receive-offload]=gro
		[generic-segmentation-offload]=gso
		[large-receive-offload]=lro
		[ntuple-filters]=ntuple
		[receive-hashing]=rxhash
		[rx-checksumming]=rx
		[rx-vlan-offload]=rxvlan
		[scatter-gather]=sg
		[tcp-segmentation-offload]=tso
		[tx-checksumming]=tx
		[tx-vlan-offload]=txvlan
		[udp-fragmentation-offload]=ufo
	)

	local -A features=()
	local feature status fixed
	# shellcheck disable=SC2034
	while read -r feature status fixed; do
		if [ -z "$feature" ]; then
			# Ignore blank line from empty expansion in here-document
			continue
		fi

		if [ "$feature" = Features ]; then
			# Ignore heading
			continue
		fi

		if [ "$fixed" = '[fixed]' ]; then
			# Fixed features can't be changed
			continue
		fi

		feature=${feature%:}
		if [ "${abbreviations[$feature]+set}" ]; then
			features[${abbreviations[$feature]}]=1
		else
			features[$feature]=1
		fi
	done <<ETHTOOL_FEATURES
$(PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin" \
	ethtool --show-features "${words[2]}" 2>/dev/null)
ETHTOOL_FEATURES

	if [ "${features[$prev]+set}" ]; then
		COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) )
		return
	fi

	# Remove features which have been seen
	local word
	for word in "${words[@]:3:${#words[@]}-4}"; do
		unset "features[$word]"
	done

	COMPREPLY=( $( compgen -W "${!features[*]}" -- "$cur" ) )
}

# Complete the current word as a kernel firmware file (for request_firmware)
# See https://www.kernel.org/doc/html/latest/driver-api/firmware/core.html
_ethtool_firmware()
{
	local -a firmware_paths=(
		/lib/firmware/updates/
		/lib/firmware/
	)

	local release
	if release=$( uname -r 2>/dev/null ); then
		firmware_paths+=(
			"/lib/firmware/updates/$release/"
			"/lib/firmware/$release/"
		)
	fi

	local fw_path_para
	if fw_path_para=$( cat /sys/module/firmware_class/parameters/path 2>/dev/null ) \
			&& [ -n "$fw_path_para" ]; then
		firmware_paths+=( "$fw_path_para" )
	fi

	local -A firmware_files=()

	local firmware_path
	for firmware_path in "${firmware_paths[@]}"; do
		local firmware_file
		for firmware_file in "$firmware_path"*; do
			if [ -f "$firmware_file" ]; then
				firmware_files[${firmware_file##*/}]=1
			fi
		done
	done

	local IFS='
'
	COMPREPLY=( $( compgen -W "${!firmware_files[*]}" -- "$cur" ) )
}

# Completion for ethtool --flash
_ethtool_flash()
{
	if [ "$cword" -eq 3 ]; then
		_ethtool_firmware
		return
	fi
}

# Completion for ethtool --get-dump
_ethtool_get_dump()
{
	case "$cword" in
		3)
			COMPREPLY=( $( compgen -W data -- "$cur" ) )
			return ;;
		4)
			# Output filename
			local IFS='
'
			COMPREPLY=( $( compgen -f -- "$cur" ) )
			return ;;
	esac
}

# Completion for ethtool --get-phy-tunable
_ethtool_get_phy_tunable()
{
	if [ "$cword" -eq 3 ]; then
		COMPREPLY=( $( compgen -W downshift -- "$cur" ) )
		return
	fi
}

# Completion for ethtool --module-info
_ethtool_module_info()
{
	local -A settings=(
		[hex]=1
		[length]=1
		[offset]=1
		[raw]=1
	)

	case "$prev" in
		hex|\
		raw)
			COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) )
			return ;;
	esac

	if [ "${settings[$prev]+set}" ]; then
		# Unsigned integer argument
		return
	fi

	# Remove settings which have been seen
	local word
	for word in "${words[@]:3:${#words[@]}-4}"; do
		unset "settings[$word]"
	done

	COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) )
}

# Completion for ethtool --pause
_ethtool_pause()
{
	local -A settings=(
		[autoneg]=1
		[rx]=1
		[tx]=1
	)

	if [ "${settings[$prev]+set}" ]; then
		COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) )
		return
	fi

	# Remove settings which have been seen
	local word
	for word in "${words[@]:3:${#words[@]}-4}"; do
		unset "settings[$word]"
	done

	COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) )
}

# Completion for ethtool --per-queue
_ethtool_per_queue()
{
	local -a subcommands=(
		--coalesce
		--show-coalesce
	)

	if [ "$cword" -eq 3 ]; then
		COMPREPLY=( $( compgen -W "queue_mask ${subcommands[*]}" -- "$cur" ) )
		return
	fi

	local sc_start=3
	if [ "${words[3]}" = queue_mask ] ; then
		case "$cword" in
			4)
				# Hex number
				return ;;
			5)
				COMPREPLY=( $( compgen -W "${subcommands[*]}" -- "$cur" ) )
				return ;;
		esac

		sc_start=5
	fi

	case "${words[$sc_start]}" in
		--coalesce)
			# Remove --per-queue args to match normal --coalesce invocation
			local words=(
				"${words[0]}"
				--coalesce
				"${words[2]}"
				"${words[@]:$sc_start+1:${#words[@]}-$sc_start-1}"
			)
			_ethtool_coalesce
			return ;;
		--show-coalesce)
			# No args
			return ;;
	esac
}

# Completion for ethtool --register-dump
_ethtool_register_dump()
{
	local -A settings=(
		[file]=1
		[hex]=1
		[raw]=1
	)

	case "$prev" in
		hex|\
		raw)
			COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) )
			return ;;
		file)
			local IFS='
'
			COMPREPLY=( $( compgen -f -- "$cur" ) )
			return ;;
	esac

	# Remove settings which have been seen
	local word
	for word in "${words[@]:3:${#words[@]}-4}"; do
		unset "settings[$word]"
	done

	COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) )
}

# Completion for ethtool --reset
_ethtool_reset()
{
	if [ "$prev" = flags ]; then
		# Unsigned integer
		return
	fi

	local -A flag_names=(
		[ap]=1
		[dma]=1
		[filter]=1
		[irq]=1
		[mac]=1
		[mgmt]=1
		[offload]=1
		[phy]=1
		[ram]=1
	)

	local -A all_flag_names=()
	local flag_name
	for flag_name in "${!flag_names[@]}"; do
		all_flag_names[$flag_name]=1
		all_flag_names[$flag_name-shared]=1
	done

	# Remove all_flag_names which have been seen
	local any_dedicated=
	local word
	for word in "${words[@]:3:${#words[@]}-4}"; do
		case "$word" in
			all)
				# Flags are always additive.
				# Nothing to add after "all".
				return ;;
			dedicated)
				any_dedicated=1
				# "dedicated" sets all non-shared flags
				for flag_name in "${!flag_names[@]}"; do
					unset "all_flag_names[$flag_name]"
				done
				continue ;;
		esac

		if [ "${flag_names[$word]+set}" ]; then
			any_dedicated=1
		fi

		unset "all_flag_names[$word]"
	done

	COMPREPLY=( $( compgen -W "${!all_flag_names[*]}" -- "$cur" ) )

	# Although it is permitted to mix named and un-named flags or duplicate
	# flags with "all" or "dedicated", it's not likely intentional.
	# Reconsider if a real use-case (or good consistency argument) is found.
	if [ "$cword" -eq 3 ]; then
		COMPREPLY+=( all dedicated flags )
	elif [ -z "$any_dedicated" ]; then
		COMPREPLY+=( dedicated )
	fi
}

# Completion for ethtool --rxfh
_ethtool_rxfh()
{
	local -A settings=(
		[context]=1
		[default]=1
		[delete]=1
		[equal]=1
		[hfunc]=1
		[hkey]=1
		[weight]=1
	)

	case "$prev" in
		context)
			_ethtool_context
			# "new" to create a new context
			COMPREPLY+=( new )
			return ;;
		equal)
			# Positive integer
			return ;;
		hfunc)
			# Complete available RSS hash functions
			COMPREPLY=(
				$(_ethtool_get_names_in_section 'RSS hash function' \
					--show-rxfh "${words[2]}")
			)
			return ;;
		hkey)
			# Pairs of hex digits separated by :
			return ;;
		weight)
			# Non-negative integer
			return ;;
	esac

	local word
	for word in "${words[@]:3:${#words[@]}-4}"; do
		# Remove settings which have been seen
		unset "settings[$word]"

		# Remove settings which are mutually-exclusive with seen settings
		case "$word" in
			context)
				unset 'settings[default]'
				;;
			default)
				unset \
					'settings[context]' \
					'settings[delete]' \
					'settings[equal]' \
					'settings[weight]'
				;;
			delete)
				unset \
					'settings[default]' \
					'settings[equal]' \
					'settings[hkey]' \
					'settings[weight]'
				;;
			equal)
				unset \
					'settings[default]' \
					'settings[delete]' \
					'settings[weight]'
				;;
			hkey)
				unset 'settings[delete]'
				;;
			weight)
				unset \
					'settings[default]' \
					'settings[delete]' \
					'settings[equal]'
				;;
		esac
	done


	COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) )
}

# Completion for ethtool --set-channels
_ethtool_set_channels()
{
	local -A settings=(
		[combined]=1
		[other]=1
		[rx]=1
		[tx]=1
	)

	if [ "${settings[$prev]+set}" ]; then
		# Unsigned integer argument
		return
	fi

	# Remove settings which have been seen
	local word
	for word in "${words[@]:3:${#words[@]}-4}"; do
		unset "settings[$word]"
	done

	COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) )
}

# Completion for ethtool --set-eee
_ethtool_set_eee()
{
	local -A settings=(
		[advertise]=1
		[eee]=1
		[tx-lpi]=1
		[tx-timer]=1
	)

	case "$prev" in
		advertise|\
		tx-timer)
			# Unsigned integer
			return ;;
		eee|\
		tx-lpi)
			COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) )
			return ;;
	esac

	# Remove settings which have been seen
	local word
	for word in "${words[@]:3:${#words[@]}-4}"; do
		unset "settings[$word]"
	done

	COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) )
}

# Completion for ethtool --set-fec
_ethtool_set_fec()
{
	if [ "$cword" -eq 3 ]; then
		COMPREPLY=( $( compgen -W encoding -- "$cur" ) )
		return
	fi

	local -A modes=(
		[auto]=auto
		[rs]=RS
		[off]=off
		[baser]=BaseR
	)

	# Remove modes which have been seen
	local word
	for word in "${words[@]:3:${#words[@]}-4}"; do
		# ethtool recognizes modes case-insensitively
		unset "modes[${word,,}]"
	done

	_ethtool_compgen_nocase "${modes[@]}"
}

# Completion for ethtool --set-phy-tunable
_ethtool_set_phy_tunable()
{
	case "$cword" in
		3)
			COMPREPLY=( $( compgen -W downshift -- "$cur" ) )
			return ;;
		4)
			COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) )
			return ;;
		5)
			COMPREPLY=( $( compgen -W count -- "$cur" ) )
			return ;;
	esac
}

# Completion for ethtool --set-priv-flags
_ethtool_set_priv_flags()
{
	if [ $(( cword % 2 )) -eq 0 ]; then
		COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) )
		return
	fi

	# Get available private flags
	local -A flags=()
	local flag
	while IFS= read -r flag; do
		# Ignore blank line from empty here-document
		if [ -n "$flag" ]; then
			flags[$flag]=1
		fi
	done <<ETHTOOL_PRIV_FLAGS
$(_ethtool_get_names_in_section \
	'Private flags for [[:graph:]]*' --show-priv-flags "${words[2]}")
ETHTOOL_PRIV_FLAGS

	# Remove flags which have been seen
	local word
	for word in "${words[@]:3:${#words[@]}-4}"; do
		unset "flags[$word]"
	done

	COMPREPLY=( $( compgen -W "${!flags[*]}" -- "$cur" ) )
}

# Completion for ethtool --set-ring
_ethtool_set_ring()
{
	local -A settings=(
		[rx-jumbo]=1
		[rx-mini]=1
		[rx]=1
		[tx]=1
	)

	if [ "${settings[$prev]+set}" ]; then
		# Unsigned integer argument
		return
	fi

	# Remove settings which have been seen
	local word
	for word in "${words[@]:3:${#words[@]}-4}"; do
		unset "settings[$word]"
	done

	COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) )
}

# Completion for ethtool --show-nfc
_ethtool_show_nfc()
{
	if [ "$cword" -eq 3 ]; then
		COMPREPLY=( $( compgen -W 'rule rx-flow-hash' -- "$cur" ) )
		return
	fi

	case "${words[3]}" in
		rule)
			if [ "$cword" -eq 4 ]; then
				COMPREPLY=(
					$(PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin" \
						ethtool --show-nfc "${words[2]}" 2>/dev/null |
						command sed -n 's/^Filter:[[:space:]]*\([0-9]*\)$/\1/p')
				)
			fi
			return ;;
		rx-flow-hash)
			case "$cword" in
				4)
					_ethtool_flow_type --hash
					return ;;
				5)
					COMPREPLY=( $( compgen -W context -- "$cur" ) )
					return ;;
				6)
					_ethtool_context
					return ;;
			esac
			;;
	esac
}

# Completion for ethtool --show-rxfh
_ethtool_show_rxfh()
{
	case "$cword" in
		3)
			COMPREPLY=( $( compgen -W context -- "$cur" ) )
			return ;;
		4)
			_ethtool_context
			return ;;
	esac
}

# Completion for ethtool --test
_ethtool_test()
{
	if [ "$cword" -eq 3 ]; then
		COMPREPLY=( $( compgen -W 'external_lb offline online' -- "$cur" ) )
		return
	fi
}


# Complete any ethtool command
_ethtool()
{
	local cur prev words cword
	_init_completion || return

	# Per "Contributing to bash-completion", complete non-duplicate long opts
	local -A suggested_funcs=(
		[--change-eeprom]=change_eeprom
		[--change]=change
		[--coalesce]=coalesce
		[--config-nfc]=config_nfc
		[--driver]=devname
		[--dump-module-eeprom]=module_info
		[--eeprom-dump]=eeprom_dump
		[--features]=features
		[--flash]=flash
		[--get-dump]=get_dump
		[--get-phy-tunable]=get_phy_tunable
		[--identify]=devname
		[--module-info]=module_info
		[--negotiate]=devname
		[--offload]=features
		[--pause]=pause
		[--per-queue]=per_queue
		[--phy-statistics]=devname
		[--register-dump]=register_dump
		[--reset]=reset
		[--set-channels]=set_channels
		[--set-dump]=devname
		[--set-eee]=set_eee
		[--set-fec]=set_fec
		[--set-phy-tunable]=set_phy_tunable
		[--set-priv-flags]=set_priv_flags
		[--set-ring]=set_ring
		[--set-rxfh-indir]=rxfh
		[--show-channels]=devname
		[--show-coalesce]=devname
		[--show-eee]=devname
		[--show-features]=devname
		[--show-fec]=devname
		[--show-nfc]=show_nfc
		[--show-offload]=devname
		[--show-pause]=devname
		[--show-permaddr]=devname
		[--show-priv-flags]=devname
		[--show-ring]=devname
		[--show-rxfh]=show_rxfh
		[--show-time-stamping]=devname
		[--statistics]=devname
		[--test]=test
	)
	local -A other_funcs=(
		[--config-ntuple]=config_nfc
		[--rxfh]=rxfh
		[--show-ntuple]=show_nfc
		[--show-rxfh-indir]=devname
		[-A]=pause
		[-C]=coalesce
		[-E]=change_eeprom
		[-G]=set_ring
		[-K]=features
		[-L]=set_channels
		[-N]=config_nfc
		[-P]=devname
		[-Q]=per_queue
		[-S]=devname
		[-T]=devname
		[-U]=config_nfc
		[-W]=devname
		[-X]=rxfh
		[-a]=devname
		[-c]=devname
		[-d]=register_dump
		[-e]=eeprom_dump
		[-f]=flash
		[-g]=devname
		[-i]=devname
		[-k]=devname
		[-l]=devname
		[-m]=module_info
		[-n]=show_nfc
		[-p]=devname
		[-r]=devname
		[-s]=change
		[-t]=test
		[-u]=show_nfc
		[-w]=get_dump
		[-x]=devname
	)

	if [ "$cword" -le 1 ]; then
		_available_interfaces
		COMPREPLY+=(
			$( compgen -W "--help --version ${!suggested_funcs[*]}" -- "$cur" )
		)
		return
	fi

	local func=${suggested_funcs[${words[1]}]-${other_funcs[${words[1]}]-}}
	if [ "$func" ]; then
		# All sub-commands have devname as their first argument
		if [ "$cword" -eq 2 ]; then
			_available_interfaces
			return
		fi

		if [ "$func" != devname ]; then
			"_ethtool_$func"
		fi
	fi
} &&
complete -F _ethtool ethtool

# ex: filetype=sh sts=8 sw=8 ts=8 noet
