🏡 index : github.com/captn3m0/RT-AX53U.git

#!/bin/sh

OPTIMIZED_FOR="$1"
CPU_LIST=`cat /proc/interrupts | sed -n '1p'`
NUM_OF_CPU=0; for i in $CPU_LIST; do NUM_OF_CPU=`expr $NUM_OF_CPU + 1`; done;
DEFAULT_RPS=0

# $1: CPU#
# $2: irq list for added.
CPU_AFFINITY_ADD()
{
	eval oval=\$CPU${1}_AFFINITY
	eval CPU${1}_AFFINITY=\"\$CPU${1}_AFFINITY $2\"
}

# $1: CPU#
# $2: Interface name for added.
CPU_RPS_ADD()
{
	eval oval=\$CPU${1}_RPS
	eval CPU${1}_RPS=\"\$CPU${1}_RPS $2\"
	dbg2 "CPU${1}_RPS=\"\$CPU${1}_RPS $2\""
}

MT7621()
{
	num_of_wifi=$1
	storage=$2
	DEFAULT_RPS=0

	#Physical IRQ# setting
	eth_trx=10
	PCIe0=11
	PCIe1=31

	# Please update the CPU binding in each cases.
	# CPU#_AFFINITY="add binding irq number here"
	# CPU#_RPS="add binding interface name here"
	dbg "[MT7621]"
	if [ "$num_of_wifi" = "0" ]; then
		CPU0_AFFINITY="$eth_trx"
		CPU1_AFFINITY=""
		CPU2_AFFINITY=""
		CPU3_AFFINITY=""

		CPU0_RPS="$ethif1 $ethif2"
		CPU1_RPS="$ethif1 $ethif2"
		CPU2_RPS="$ethif1 $ethif2"
		CPU3_RPS="$ethif1 $ethif2"
	elif [ "$num_of_wifi" = "1" ]; then
                CPU0_AFFINITY=""
                CPU1_AFFINITY="$eth_trx"
                CPU2_AFFINITY="$PCIe0"
                CPU3_AFFINITY="$PCIe1"

                CPU0_RPS="$ethif1 $ethif2 $wifi1 $wifi2 $wifi1_apcli0"
                CPU1_RPS="$wifi1 $wifi2 $wifi1_apcli0"
                CPU2_RPS="$ethif1 $ethif2"
                CPU3_RPS=""
	elif [ "$num_of_wifi" = "2" ]; then
		CPU0_AFFINITY=""
		CPU1_AFFINITY="$eth_trx"
		CPU2_AFFINITY="$PCIe1"
		CPU3_AFFINITY="$PCIe0"

		CPU0_RPS="$ethif1 $ethif2 $wifi1 $wifi2 $wifi1_apcli0 $wifi2_apcli0"
		CPU1_RPS="$wifi1 $wifi2 $wifi1_apcli0 $wifi2_apcli0"
		CPU2_RPS="$ethif1 $ethif2"
		CPU3_RPS=""
	else
		dbg "MT7621 with $NUM_OF_WIFI Wi-Fi bands is not support"
	fi
}

# $1: The prefix of vifs
# $2: The number of vifs
gen_vifs_to_rps_if()
{
	if [ $# -lt 2 ]; then
		dbg "gen_vifs_to_rps_if requires 2 parameters"
		return
	fi

	vif=$1
	total=$2
	#dbg "gen_vifs_to_rps_if $vif $total"
	i=0
	while [ "$i" -lt "$total" ]; do
		eval prefix=\$$vif
		eval $vif$i=$prefix$i

		RPS_IF_LIST="$RPS_IF_LIST $prefix$i"

		dbg2 "\$$vif$i=$prefix$i"

		i=`expr $i + 1`
	done
}

get_eth_if_name()
{
	ethif1="eth0"
	ethif2="eth1"
	dbg2 "# Ethernet interface list"
	dbg2 "\$ethif1=$ethif1\n\$ethif2=$ethif2"
	RPS_IF_LIST="$RPS_IF_LIST $ethif1 $ethif2"
}

# Try to get Wi-Fi interface name from l1profile
get_wifi_if_name()
{
	l1dat_exist=`l1dat 2>/dev/null`
	if [ -z "$l1dat_exist" ]; then
		dbg "Layer 1 profile does not exist."
		dbg "Please check l1dat "

		wifi1="ra0"
		wifi1_prefix="ra"
		wifi1_apcli="apcli"
		wifi1_wds="wds"
		wifi1_mesh="mesh"
		wifi2="rai0"
		wifi2_prefix="rai"
		wifi2_apcli="apclii"
		wifi2_wds="wdsi"
		wifi2_mesh="meshi"
		wifi3="rae0"
		wifi3_prefix="rae"
		wifi3_apcli="apclie"
		wifi3_wds="wdse"
		wifi3_mesh="meshe"

	else
		#wifi_if1s=`l1dat idx2if 1`
		#wifi_if2s=`l1dat idx2if 2`
		#wifi_if3s=`l1dat idx2if 3`
		wifi_if1s=`l1dat zone2if dev1`
		wifi_if2s=`l1dat zone2if dev2`
		wifi_if3s=`l1dat zone2if dev3`
	
		wifi1=`echo $wifi_if1s | awk '{print $1}'`
		wifi1_prefix=`echo $wifi_if1s | awk '{print $2}'`
		wifi1_apcli=`echo $wifi_if1s | awk '{print $3}'`
		wifi1_wds=`echo $wifi_if1s | awk '{print $4}'`
		wifi1_mesh=`echo $wifi_if1s | awk '{print $5}'`
	
		wifi2=`echo $wifi_if2s | awk '{print $1}'`
		wifi2_prefix=`echo $wifi_if2s | awk '{print $2}'`
		wifi2_apcli=`echo $wifi_if2s | awk '{print $3}'`
		wifi2_wds=`echo $wifi_if2s | awk '{print $4}'`
		wifi2_mesh=`echo $wifi_if2s | awk '{print $5}'`
	
		wifi3=`echo $wifi_if3s | awk '{print $1}'`
		wifi3_prefix=`echo $wifi_if3s | awk '{print $2}'`
		wifi3_apcli=`echo $wifi_if3s | awk '{print $3}'`
		wifi3_wds=`echo $wifi_if3s | awk '{print $4}'`
		wifi3_mesh=`echo $wifi_if3s | awk '{print $5}'`

		# idx = 0 : not a DBDC interface
		# idx = 1 : main(physical) interface of 1st Wi-Fi band
		# idx > 1 : virtual interface of other Wi-Fi band
		# idx = "": Wi-Fi interface does not exist in l1profile
		wifi1_dbdc_idx=`l1dat if2dbdcidx $wifi1`
		wifi2_dbdc_idx=`l1dat if2dbdcidx $wifi2`
		wifi3_dbdc_idx=`l1dat if2dbdcidx $wifi3`
	fi

	dbg2 "# Wi-Fi interface list"
	dbg2 "\$wifi1=$wifi1"
	dbg2 "\$wifi2=$wifi2"
	dbg2 "\$wifi3=$wifi3"

	RPS_IF_LIST="$RPS_IF_LIST $wifi1 $wifi2 $wifi3"

	gen_vifs_to_rps_if "wifi1_apcli" 1
	gen_vifs_to_rps_if "wifi2_apcli" 1
	gen_vifs_to_rps_if "wifi3_apcli" 1
	gen_vifs_to_rps_if "wifi1_mesh" 1
	gen_vifs_to_rps_if "wifi2_mesh" 1
	gen_vifs_to_rps_if "wifi3_mesh" 1
	gen_vifs_to_rps_if "wifi1_wds" 4
	gen_vifs_to_rps_if "wifi2_wds" 4
	gen_vifs_to_rps_if "wifi3_wds" 4

	scan_wifi_num
}

scan_wifi_num()
{
	NUM_OF_WIFI=0
	if [ -n $wifi1 -a -d "/sys/class/net/$wifi1" ]; then
		NUM_OF_WIFI=`expr $NUM_OF_WIFI + 1`
	fi

	if [ -n $wifi2 -a -d "/sys/class/net/$wifi2" ];then
		NUM_OF_WIFI=`expr $NUM_OF_WIFI + 1`
	fi

	if [ -n $wifi3 -a -d "/sys/class/net/$wifi3" ];then
		NUM_OF_WIFI=`expr $NUM_OF_WIFI + 1`
	fi

	dbg "# NUM_OF_WIFI=$NUM_OF_WIFI band(s)"
}

get_wifi_num()
{
	echo $NUM_OF_WIFI
}

# $1: module name
# return value
#    1: if the module named $1 is built-in or inserted.
#    0: if the module exists but has not been inserted.
#   -1: if the module does not exist.
module_exist()
{
	mpath="/lib/modules/`uname -r`"
	retval=-1

	mod_in_lib=`find $mpath -name "$1".ko > /dev/null 2>&1`
	#echo "find $mpath -name "$1".ko" > /dev/console
	if [ ! -z $mod_in_lib ]; then
		retval=0
	fi

	# TODO find out a way in OpenWRT
	mod_builtin=`grep $1 $mpath/modules.builtin 2>/dev/null`
	if [ ! -z "$mod_builtin" ]; then
		retval=1
	fi

	mod_inserted=`lsmod | grep $1 2>/dev/null`
	if [ ! -z "$mod_inserted" ]; then
		retval=1
	fi

	echo $retval
}

setup_model()
{
	num_of_wifi=$(get_wifi_num)

	if [ "$NUM_OF_CPU" = "4" ]; then
		dbg "setup_model:MT7621 wifi#=$num_of_wifi"
		MT7621 $num_of_wifi
	fi
}

set_rps_cpu_bitmap()
{
	dbg2 "# Scan binding interfaces of each cpu"
	# suppose the value of interface_var is null or hex
	num=0
	while [ "$num" -lt "$NUM_OF_CPU" ];do
		cpu_bit=$((2 ** $num))
		eval rps_list=\$CPU${num}_RPS
		dbg2 "# CPU$num: rps_list=$rps_list"
		for i in $rps_list; do
			var=${VAR_PREFIX}_${i//-/_}
			eval ifval=\$$var
			dbg2 "[var val before] \$$var=$ifval"
			if [ -z "$ifval" ]; then
				eval $var=$cpu_bit
			else
				eval $var=`expr $ifval + $cpu_bit`
			fi
			eval ifval=\$$var
			dbg2 "[rps val after]$i=$ifval"
		done
		num=`expr $num + 1`
	done
}

# $1: The default rps value. If rps of the interface is not setup, set $1 to it
set_rps_cpus()
{
	dbg2 "# Setup rps of the interfaces, $RPS_IF_LIST."
	for i in $RPS_IF_LIST; do
		var=${VAR_PREFIX}_${i//-/_}
		eval cpu_map=\$$var
		if [ -d /sys/class/net/$i ]; then
			if [ ! -z $cpu_map ]; then
				cpu_map=`printf '%x' $cpu_map`
				dbg "echo $cpu_map > /sys/class/net/$i/queues/rx-0/rps_cpus"
				echo $cpu_map > /sys/class/net/$i/queues/rx-0/rps_cpus
			elif [ ! -z $1 ]; then
				dbg "echo $1 > /sys/class/net/$i/queues/rx-0/rps_cpus"
				echo $1 > /sys/class/net/$i/queues/rx-0/rps_cpus
			fi
		fi
	done
}

set_smp_affinity()
{
	dbg2 "# Setup affinity of each physical irq."
	num=0
	while [ "$num" -lt "$NUM_OF_CPU" ];do
		eval smp_list=\$CPU${num}_AFFINITY
		for i in $smp_list; do
			cpu_bit=$((2 ** $num))
			virq=$i
			dbg2 "irq p2v $i --> $virq"
			if [ ! -z $virq ]; then
				dbg "echo $cpu_bit > /proc/irq/$virq/smp_affinity"
				echo $cpu_bit > /proc/irq/$virq/smp_affinity
			fi
		done
		num=`expr $num + 1`
	done
}

if [ "$1" = "dbg" ]; then
	DBG=1
elif [ "$1" = "dbg2" ]; then
	DBG=2
else
	DBG=0
fi

# Usage: dbg "the output string"
dbg()
{
	if [ "$DBG" -ge "1" ]; then
		echo -e $1
	fi
}

# Usage: dbg2 "the output string"
dbg2()
{
	if [ "$DBG" -ge "2" ]; then
		echo -e $1
	fi
}

if [ $1 == "usb0" ]; then
	dbg "echo 5 > /sys/class/net/$1/queues/rx-0/rps_cpus"
	echo 5 > /sys/class/net/$1/queues/rx-0/rps_cpus
else
#NUM_OF_CPU=4	#7621
dbg "# RPS and AFFINITY Setting"
dbg "# NUM_OF_CPU=$NUM_OF_CPU"
VAR_PREFIX="autogen"
#IRQ_LIST=""	# setup by every model
RPS_IF_LIST=""	# setup by getEthIfName/getWiFiIfName/every model
get_eth_if_name
get_wifi_if_name	# It will add all wifi interfaces into $RPS_IF_LIST
dbg2 "# default RPS_IF_LIST=$RPS_IF_LIST"
setup_model
set_rps_cpu_bitmap
set_rps_cpus $DEFAULT_RPS
set_smp_affinity
fi

#end of file