mirror of
https://dev.iopsys.eu/feed/iopsys.git
synced 2025-12-10 07:44:50 +01:00
421 lines
12 KiB
Bash
Executable file
421 lines
12 KiB
Bash
Executable file
#!/bin/sh
|
|
# Implementation of QoS setup for Econet platform.
|
|
|
|
VALID_INTF=""
|
|
readonly ETHWAN="$(jsonfilter -i /etc/board.json -e @.network.wan.device)"
|
|
readonly LANPORTS="$(jsonfilter -i /etc/board.json -e @.network.lan.ports[*] -e @.network.lan.device | xargs)"
|
|
readonly OFFSET=32
|
|
|
|
get_wan_type_idx() {
|
|
case "$(cat "/proc/tc3162/${ETHWAN}_switch_hsgmii_lan")" in
|
|
pon) echo "3" ;;
|
|
usb) echo "2" ;;
|
|
pcie0) echo "0" ;;
|
|
pcie1) echo "1" ;;
|
|
eth) echo "4" ;;
|
|
*) echo "-1" ;;
|
|
esac
|
|
}
|
|
|
|
readonly WAN_TYPE_IDX="$(get_wan_type_idx)"
|
|
|
|
errmsg() {
|
|
echo "$@" >&2
|
|
return 0
|
|
}
|
|
|
|
get_var() {
|
|
local varname="$1"
|
|
eval echo \$\{${varname}\}
|
|
return 0
|
|
}
|
|
|
|
# Initialized queues
|
|
# (Not needed on Econet)
|
|
hw_queue_init_all() {
|
|
return 0
|
|
}
|
|
|
|
# populate interfaces available for rate limiting
|
|
init_valid_interface_list() {
|
|
local intf tmpintf
|
|
|
|
for intf in $(ifconfig -a | awk -F' ' '{if ($1 ~ "eth" ) print $1;}' | xargs); do
|
|
for tmpintf in $LANPORTS; do
|
|
if [ "$intf" = "$tmpintf" ]; then
|
|
[ -z "$VALID_INTF" ] && VALID_INTF="${intf}" || VALID_INTF="${VALID_INTF} ${intf}"
|
|
break
|
|
fi
|
|
done
|
|
done
|
|
|
|
for intf in $(ifconfig -a | awk -F' ' '{if ($1 ~ "rai" ) print $1;}' | xargs); do
|
|
[ "$(ls -d /sys/class/net/${intf}/lower* 2> /dev/null)" != "" ] && continue
|
|
[ -z "$VALID_INTF" ] && VALID_INTF="${intf}" || VALID_INTF="${VALID_INTF} ${intf}"
|
|
done
|
|
|
|
for intf in $(ifconfig -a | awk -F' ' '!/rai/ {if ($1 ~ "ra") print $1;}' | xargs); do
|
|
[ "$(ls -d /sys/class/net/${intf}/lower* 2> /dev/null)" != "" ] && continue
|
|
[ -z "$VALID_INTF" ] && VALID_INTF="${intf}" || VALID_INTF="${VALID_INTF} ${intf}"
|
|
done
|
|
}
|
|
|
|
# Initialize all interfaces
|
|
# (Not needed on Econet)
|
|
hw_intf_init() {
|
|
return 0
|
|
}
|
|
|
|
set_wan_ingress_rate() {
|
|
local ingress_rate="$1"
|
|
local pkt_type
|
|
local wanchannel="$(cat /proc/tc3162/eth_portmap | head -n1)"
|
|
wanchannel=$((wanchannel))
|
|
|
|
rm -rf "/tmp/qos/wan_ingress_shape_speed"
|
|
if [ "$wanchannel" = "-1" ]; then
|
|
[ "$WAN_TYPE_IDX" = "-1" -o -z "$ingress_rate" ] && return
|
|
|
|
echo "$ingress_rate" > "/tmp/qos/wan_ingress_shape_speed"
|
|
|
|
for pkt_type in $(seq 0 3); do
|
|
echo "$WAN_TYPE_IDX $pkt_type $ingress_rate 0" > "/proc/tc3162/${ETHWAN}_ratelimit"
|
|
done
|
|
fi
|
|
}
|
|
|
|
set_wan_egress_rate() {
|
|
local rate="$1"
|
|
local burstsize="$2"
|
|
local wanchannel="$(cat /proc/tc3162/eth_portmap | head -n1)"
|
|
wanchannel=$((wanchannel))
|
|
[ "$wanchannel" = "-1" ] && wanchannel=0
|
|
|
|
if [ "$rate" -gt 0 ]; then
|
|
/userfs/bin/qdmamgr_wan set general_tx_trtcm config "$wanchannel" enable byte slow enable byte fast
|
|
/userfs/bin/qdmamgr_wan set general_tx_trtcm value "$wanchannel" "$rate" "$rate"
|
|
|
|
if [ "$burstsize" -gt 1000 ]; then
|
|
/userfs/bin/qdmamgr_wan set general_tx_trtcm bsize "$wanchannel" "$burstsize" "$burstsize"
|
|
fi
|
|
else
|
|
/userfs/bin/qdmamgr_wan set general_tx_trtcm config "$wanchannel" disable byte slow disable byte fast
|
|
fi
|
|
}
|
|
|
|
# Initialize the hardware setup library
|
|
hw_init_all() {
|
|
local tc=0
|
|
local tsid=0
|
|
local channel
|
|
|
|
export TMP_HW_QUEUE_LIST=""
|
|
echo clear > /proc/ifc_debug
|
|
echo reinit > /proc/ifc_debug
|
|
|
|
for tc in $(seq 0 7); do
|
|
rm -rf "/tmp/qos/dscp_values_${tc}_4"
|
|
rm -rf "/tmp/qos/dscp_values_${tc}_6"
|
|
done
|
|
|
|
/userfs/bin/qdmamgr_lan set general_rx_init enable trtcm 8 125
|
|
/userfs/bin/qdmamgr_wan set general_rx_init enable trtcm 8 125
|
|
/userfs/bin/qdmamgr_wan set general_tx_init enable trtcm 40 25
|
|
|
|
for channel in $(seq 0 30); do
|
|
tsid=$((OFFSET+channel))
|
|
/userfs/bin/qdmamgr_lan set general_rx_trtcm config "$tsid" disable byte slow disable byte fast
|
|
/userfs/bin/qdmamgr_wan set general_rx_trtcm config "$tsid" disable byte slow disable byte fast
|
|
done
|
|
|
|
# set_wan_ingress_rate "0" - Not needed
|
|
set_wan_egress_rate "0" "0"
|
|
|
|
return 0
|
|
}
|
|
|
|
# Remember selected queue options. They will be committed
|
|
# during hw_commit_all()
|
|
hw_queue_set() {
|
|
local ifname="$1"
|
|
local q_count="$2"
|
|
local order="$3"
|
|
local qsize="$4"
|
|
local wgt="$5"
|
|
local sc_alg="$6"
|
|
local rate="$7"
|
|
local burstsize="$8"
|
|
local index="$((order - 1))"
|
|
|
|
#if [ "${ifname}" != "${ethwan}" ] ; then
|
|
# return 2
|
|
#fi
|
|
|
|
export TMP_HW_QUEUE_${order}_no="${q_count}"
|
|
export TMP_HW_QUEUE_${order}_ifname="${ifname}"
|
|
export TMP_HW_QUEUE_${order}_order="${order}"
|
|
export TMP_HW_QUEUE_${order}_qsize="${qsize}"
|
|
export TMP_HW_QUEUE_${order}_wgt="${wgt}"
|
|
export TMP_HW_QUEUE_${order}_sc_alg="${sc_alg}"
|
|
export TMP_HW_QUEUE_${order}_rate="${rate}"
|
|
export TMP_HW_QUEUE_${order}_burstsize="${burstsize}"
|
|
export TMP_HW_QUEUE_LIST="${TMP_HW_QUEUE_LIST} ${order}"
|
|
|
|
if [ "${rate}" != "" ] && [ $(($rate != 0)) ] ; then
|
|
errmsg "Per-queue shape rate is not implemented"
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
# Set policer options. In fact, they are not supported.
|
|
hw_policer_set() {
|
|
local action="$1"
|
|
local dir="$2"
|
|
local policer_no="$3"
|
|
|
|
shift 3
|
|
|
|
case "$action" in
|
|
add)
|
|
meter="$1"
|
|
cir="$2"
|
|
cbs="$3"
|
|
ebs="$4"
|
|
pir="$5"
|
|
pbs="$6"
|
|
|
|
;;
|
|
del)
|
|
;;
|
|
esac
|
|
return 0
|
|
}
|
|
|
|
# get tsid from ifname
|
|
get_tsid() {
|
|
if [ -z "$1" ]; then
|
|
echo "-1"
|
|
return
|
|
fi
|
|
|
|
local tmpintf
|
|
local intf="$1"
|
|
local idx=0
|
|
|
|
for tmpintf in $VALID_INTF; do
|
|
if [ "$tmpintf" = "$intf" ]; then
|
|
echo $((OFFSET+idx))
|
|
return
|
|
fi
|
|
|
|
idx=$((idx+1))
|
|
done
|
|
|
|
echo "-1"
|
|
}
|
|
|
|
get_numeric_value() {
|
|
local val="$1"
|
|
|
|
case $val in
|
|
''|*[!0-9]*) echo 0 ;;
|
|
*) echo "${val}" ;;
|
|
esac
|
|
}
|
|
|
|
set_lan_rate() {
|
|
local ifname="$1"
|
|
local rate="$(get_numeric_value "${2}")"
|
|
local burst_size="$(get_numeric_value "${3}")"
|
|
local direction="$4"
|
|
local qdma_exe=""
|
|
|
|
local tsid="$(get_tsid "${ifname}")"
|
|
|
|
if [ "$tsid" -lt 0 ]; then
|
|
errmsg "could not get tsid for ${ifname}"
|
|
return
|
|
fi
|
|
|
|
if [ "$direction" -eq 0 ]; then
|
|
qdma_exe="/userfs/bin/qdmamgr_wan"
|
|
else
|
|
qdma_exe="/userfs/bin/qdmamgr_lan"
|
|
fi
|
|
|
|
if [ "$rate" -eq 0 ]; then
|
|
return
|
|
else
|
|
"${qdma_exe}" set general_rx_trtcm config "$tsid" enable byte slow enable byte fast
|
|
"${qdma_exe}" set general_rx_trtcm value "$tsid" "$rate" "$rate"
|
|
|
|
if [ "$burst_size" -gt 0 ]; then
|
|
"${qdma_exe}" set general_rx_trtcm bsize "$tsid" "$burst_size" "$burst_size"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Set ingress rate. In fact, it is not supported
|
|
hw_policer_set_ingress_rate() {
|
|
local ifname="$1"
|
|
local ingress_rate="$2"
|
|
local in_burst_size="$3"
|
|
|
|
if [ "$ifname" = "$ETHWAN" ]; then
|
|
set_wan_ingress_rate "$ingress_rate"
|
|
else
|
|
set_lan_rate "$ifname" "$ingress_rate" "$in_burst_size" "0"
|
|
fi
|
|
}
|
|
|
|
# Configure shaper rate that will be committed during hw_commit_all()
|
|
hw_shaper_set() {
|
|
local ifname="$1"
|
|
local action="$2"
|
|
local rate="$3"
|
|
local burstsize="$4"
|
|
|
|
case "${action}" in
|
|
add)
|
|
if [ "$ifname" = "$ETHWAN" ]; then
|
|
export TMP_HW_SHAPE_RATE="$rate"
|
|
set_wan_egress_rate "$rate" "$burstsize"
|
|
else
|
|
set_lan_rate "$ifname" "$rate" "$burstsize" "1"
|
|
fi
|
|
;;
|
|
del)
|
|
if [ "$ifname" = "$ETHWAN" ]; then
|
|
export TMP_HW_SHAPE_RATE=""
|
|
set_wan_egress_rate "0" "0"
|
|
else
|
|
set_lan_rate "$ifname" "0" "0" "1"
|
|
fi
|
|
;;
|
|
*)
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
return 0
|
|
}
|
|
|
|
# Convert shaper in UCI terms to Econet terms
|
|
hw_sc_alg2str() {
|
|
local sc_alg="$1"
|
|
|
|
case "${sc_alg}" in
|
|
SP)
|
|
echo "PQ"
|
|
;;
|
|
WRR)
|
|
echo "WRR"
|
|
;;
|
|
*)
|
|
echo ""
|
|
return 1
|
|
esac
|
|
|
|
return 0
|
|
}
|
|
|
|
# Commit all options preserved during
|
|
hw_commit_all() {
|
|
local sorted_list="$(echo $TMP_HW_QUEUE_LIST | tr ' ' '\n' | sort | xargs)"
|
|
local weight_list=""
|
|
local glob_alg=""
|
|
local shape_rate="$TMP_HW_SHAPE_RATE"
|
|
local q_count="0"
|
|
local mac_qos_flag=""
|
|
local pbit=0
|
|
local tc=0
|
|
|
|
# Reorder queues
|
|
for q in ${sorted_list} ; do
|
|
local sc_alg="$(get_var TMP_HW_QUEUE_${q}_sc_alg)"
|
|
local wgt="$(get_var TMP_HW_QUEUE_${q}_wgt)"
|
|
|
|
if [ "$glob_alg" != "" ] && [ "$sc_alg" != "$glob_alg" ] ; then
|
|
errmsg "Not matching scheduling algorithm: $sc_alg vs $glob_alg"
|
|
return 1
|
|
fi
|
|
|
|
glob_alg="$sc_alg"
|
|
|
|
case "${sc_alg}" in
|
|
WRR)
|
|
if [ $(($q_count >= 8)) != 0 ] ; then
|
|
errmsg "Too many queues, next queues will be ignored"
|
|
else
|
|
weight_list="$weight_list $wgt"
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
q_count=$((q_count + 1))
|
|
done
|
|
|
|
case "${glob_alg}" in
|
|
WRR)
|
|
mac_qos_flag="8QWRR"
|
|
while [ $((q_count < 8)) != 0 ] ; do
|
|
weight_list="$weight_list 1"
|
|
q_count=$((q_count + 1))
|
|
done
|
|
|
|
echo ${mac_qos_flag} > /proc/qdma_wan/mac_qos_flag
|
|
echo "1 ${weight_list}" > /proc/qdma_wan/mac_qos
|
|
;;
|
|
SP)
|
|
mac_qos_flag="8QPQ"
|
|
q_count="8"
|
|
|
|
echo ${mac_qos_flag} > /proc/qdma_wan/mac_qos_flag
|
|
echo "0 0 0 0 0 0 0 0 0" > /proc/qdma_wan/mac_qos
|
|
;;
|
|
esac
|
|
|
|
echo 255 > /proc/qdma_wan/mac_default_queuemask
|
|
|
|
rm -f "/tmp/qos/wan_link_shape_rate"
|
|
rm -f "/tmp/qos/wan_link_speed"
|
|
if [ "${glob_alg}" != "" ] ; then
|
|
if [ -n "${shape_rate}" ]; then
|
|
echo "${shape_rate}" > "/tmp/qos/wan_link_shape_rate"
|
|
else
|
|
/usr/sbin/qos-uplink-bandwidth
|
|
fi
|
|
else
|
|
/userfs/bin/qosrule discpline Enable 0
|
|
fi
|
|
|
|
if [ -x /userfs/bin/blapi_cmd ]; then
|
|
echo 1 > /proc/ifc_send_to_ppe
|
|
for tc in $(seq 0 7); do
|
|
if [ -s "/tmp/qos/dscp_values_${tc}_4" ]; then
|
|
sort -un "/tmp/qos/dscp_values_${tc}_4" | awk 'NR==1{first=$1;last=$1;next}
|
|
$1 == last+1 {last=$1;next}
|
|
{system("/userfs/bin/blapi_cmd traffic set_traffic_class DSCP " first*4 " " or(last*4, 0x3) " 1");first=$1;last=first}
|
|
END{system("/userfs/bin/blapi_cmd traffic set_traffic_class DSCP " first*4 " " or(last*4, 0x3) " 1")}'
|
|
fi
|
|
if [ -s "/tmp/qos/dscp_values_${tc}_6" ]; then
|
|
[ -s "/tmp/qos/dscp_values_${tc}_4" ] && sort -un "/tmp/qos/dscp_values_${tc}_6" | awk 'NR==1{first=$1;last=$1;next}
|
|
$1 == last+1 {last=$1;next}
|
|
{system("/userfs/bin/blapi_cmd traffic set_traffic_class DSCP " first*4 " " or(last*4, 0x3) " 0");first=$1;last=first}
|
|
END{system("/userfs/bin/blapi_cmd traffic set_traffic_class DSCP " first*4 " " or(last*4, 0x3) " 0")}'
|
|
sort -un "/tmp/qos/dscp_values_${tc}_6" | awk 'NR==1{first=$1;last=$1;next}
|
|
$1 == last+1 {last=$1;next}
|
|
{system("/userfs/bin/blapi_cmd traffic set_traffic_class DSCP " first*4 " " or(last*4, 0x3) " 1");first=$1;last=first}
|
|
END{system("/userfs/bin/blapi_cmd traffic set_traffic_class DSCP " first*4 " " or(last*4, 0x3) " 1")}'
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if [ -x /userfs/bin/ifc ]; then
|
|
echo 1 > /proc/ifc_send_to_ppe
|
|
for pbit in $(seq 0 7); do
|
|
/userfs/bin/ifc add vip pbit $pbit
|
|
done
|
|
fi
|
|
}
|