1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3#shellcheck disable=SC2034 # SC does not see the global variables 4#shellcheck disable=SC2317,SC2329 # unused functions 5 6ALL_TESTS=" 7 test_eth_ctrl_stats 8 test_eth_mac_stats 9 test_pause_stats 10" 11: "${DRIVER_TEST_CONFORMANT:=yes}" 12STABLE_MAC_ADDRS=yes 13NUM_NETIFS=2 14lib_dir=$(dirname "$0") 15# shellcheck source=./../../../net/forwarding/lib.sh 16source "$lib_dir"/../../../net/forwarding/lib.sh 17# shellcheck source=./../../../kselftest/ktap_helpers.sh 18source "$lib_dir"/../../../kselftest/ktap_helpers.sh 19 20UINT32_MAX=$((2**32 - 1)) 21SUBTESTS=0 22TEST_NAME=$(basename "$0" .sh) 23 24traffic_test() 25{ 26 local iface=$1; shift 27 local neigh=$1; shift 28 local num_tx=$1; shift 29 local pkt_format="$1"; shift 30 local -a counters=("$@") 31 local int grp cnt target exact_check 32 local before after delta 33 local num_rx=$((num_tx * 2)) 34 local xfail_message 35 local src="aggregate" 36 local i 37 38 for i in "${!counters[@]}"; do 39 read -r int grp cnt target exact_check xfail_message \ 40 <<< "${counters[$i]}" 41 42 before[i]=$(ethtool_std_stats_get "$int" "$grp" "$cnt" "$src") 43 done 44 45 # shellcheck disable=SC2086 # needs split options 46 run_on "$iface" "$MZ" "$iface" -q -c "$num_tx" $pkt_format 47 48 # shellcheck disable=SC2086 # needs split options 49 run_on "$neigh" "$MZ" "$neigh" -q -c "$num_rx" $pkt_format 50 51 for i in "${!counters[@]}"; do 52 read -r int grp cnt target exact_check xfail_message \ 53 <<< "${counters[$i]}" 54 55 after[i]=$(ethtool_std_stats_get "$int" "$grp" "$cnt" "$src") 56 if [[ "${after[$i]}" == "null" ]]; then 57 ktap_test_skip "$TEST_NAME.$grp-$cnt" 58 continue; 59 fi 60 61 delta=$((after[i] - before[i])) 62 63 if [ "$exact_check" -ne 0 ]; then 64 [ "$delta" -eq "$target" ] 65 else 66 [ "$delta" -ge "$target" ] && \ 67 [ "$delta" -le "$UINT32_MAX" ] 68 fi 69 err="$?" 70 71 if [[ $err != 0 ]] && [[ -n $xfail_message ]]; then 72 ktap_print_msg "$xfail_message" 73 ktap_test_xfail "$TEST_NAME.$grp-$cnt" 74 continue; 75 fi 76 77 if [[ $err != 0 ]]; then 78 ktap_print_msg "$grp-$cnt is not valid on $int (expected $target, got $delta)" 79 ktap_test_fail "$TEST_NAME.$grp-$cnt" 80 else 81 ktap_test_pass "$TEST_NAME.$grp-$cnt" 82 fi 83 done 84} 85 86test_eth_ctrl_stats() 87{ 88 local pkt_format="-a own -b bcast 88:08 -p 64" 89 local num_pkts=1000 90 local -a counters 91 92 counters=("$h1 eth-ctrl MACControlFramesTransmitted $num_pkts 0") 93 traffic_test "$h1" "$h2" "$num_pkts" "$pkt_format" \ 94 "${counters[@]}" 95 96 counters=("$h1 eth-ctrl MACControlFramesReceived $num_pkts 0") 97 traffic_test "$h2" "$h1" "$num_pkts" "$pkt_format" \ 98 "${counters[@]}" 99} 100SUBTESTS=$((SUBTESTS + 2)) 101 102test_eth_mac_stats() 103{ 104 local pkt_size=100 105 local pkt_size_fcs=$((pkt_size + 4)) 106 local bcast_pkt_format="-a own -b bcast -p $pkt_size" 107 local mcast_pkt_format="-a own -b 01:00:5E:00:00:01 -p $pkt_size" 108 local num_pkts=2000 109 local octets=$((pkt_size_fcs * num_pkts)) 110 local -a counters error_cnt collision_cnt 111 112 # Error counters should be exactly zero 113 counters=("$h1 eth-mac FrameCheckSequenceErrors 0 1" 114 "$h1 eth-mac AlignmentErrors 0 1" 115 "$h1 eth-mac FramesLostDueToIntMACXmitError 0 1" 116 "$h1 eth-mac CarrierSenseErrors 0 1" 117 "$h1 eth-mac FramesLostDueToIntMACRcvError 0 1" 118 "$h1 eth-mac InRangeLengthErrors 0 1" 119 "$h1 eth-mac OutOfRangeLengthField 0 1" 120 "$h1 eth-mac FrameTooLongErrors 0 1" 121 "$h1 eth-mac FramesAbortedDueToXSColls 0 1") 122 traffic_test "$h1" "$h2" "$num_pkts" "$bcast_pkt_format" \ 123 "${counters[@]}" 124 125 # Collision related counters should also be zero 126 counters=("$h1 eth-mac SingleCollisionFrames 0 1" 127 "$h1 eth-mac MultipleCollisionFrames 0 1" 128 "$h1 eth-mac FramesWithDeferredXmissions 0 1" 129 "$h1 eth-mac LateCollisions 0 1" 130 "$h1 eth-mac FramesWithExcessiveDeferral 0 1") 131 traffic_test "$h1" "$h2" "$num_pkts" "$bcast_pkt_format" \ 132 "${counters[@]}" 133 134 counters=("$h1 eth-mac BroadcastFramesXmittedOK $num_pkts 0" 135 "$h1 eth-mac OctetsTransmittedOK $octets 0") 136 traffic_test "$h1" "$h2" "$num_pkts" "$bcast_pkt_format" \ 137 "${counters[@]}" 138 139 counters=("$h1 eth-mac BroadcastFramesReceivedOK $num_pkts 0" 140 "$h1 eth-mac OctetsReceivedOK $octets 0") 141 traffic_test "$h2" "$h1" "$num_pkts" "$bcast_pkt_format" \ 142 "${counters[@]}" 143 144 counters=("$h1 eth-mac FramesTransmittedOK $num_pkts 0" 145 "$h1 eth-mac MulticastFramesXmittedOK $num_pkts 0") 146 traffic_test "$h1" "$h2" "$num_pkts" "$mcast_pkt_format" \ 147 "${counters[@]}" 148 149 counters=("$h1 eth-mac FramesReceivedOK $num_pkts 0" 150 "$h1 eth-mac MulticastFramesReceivedOK $num_pkts 0") 151 traffic_test "$h2" "$h1" "$num_pkts" "$mcast_pkt_format" \ 152 "${counters[@]}" 153} 154SUBTESTS=$((SUBTESTS + 22)) 155 156test_pause_stats() 157{ 158 local pkt_format="-a own -b 01:80:c2:00:00:01 88:08:00:01:00:01" 159 local xfail_message="software sent pause frames not detected" 160 local num_pkts=2000 161 local -a counters 162 local int 163 local i 164 165 # Check that there is pause frame support 166 for ((i = 1; i <= NUM_NETIFS; ++i)); do 167 int="${NETIFS[p$i]}" 168 if ! run_on "$int" ethtool -I --json -a "$int" > /dev/null 2>&1; then 169 ktap_test_skip "$TEST_NAME.tx_pause_frames" 170 ktap_test_skip "$TEST_NAME.rx_pause_frames" 171 return 172 fi 173 done 174 175 counters=("$h1 pause tx_pause_frames $num_pkts 0 $xfail_message") 176 traffic_test "$h1" "$h2" "$num_pkts" "$pkt_format" \ 177 "${counters[@]}" 178 179 counters=("$h1 pause rx_pause_frames $num_pkts 0") 180 traffic_test "$h2" "$h1" "$num_pkts" "$pkt_format" \ 181 "${counters[@]}" 182} 183SUBTESTS=$((SUBTESTS + 2)) 184 185setup_prepare() 186{ 187 local iface 188 189 h1=${NETIFS[p1]} 190 h2=${NETIFS[p2]} 191 192 h2_mac=$(mac_get "$h2") 193} 194 195ktap_print_header 196ktap_set_plan $SUBTESTS 197 198check_ethtool_counter_group_support 199trap cleanup EXIT 200 201setup_prepare 202setup_wait 203 204tests_run 205 206ktap_finished 207