1*f72e2f48SDanielle Ratson#!/bin/bash 2*f72e2f48SDanielle Ratson# SPDX-License-Identifier: GPL-2.0 3*f72e2f48SDanielle Ratson 4*f72e2f48SDanielle Ratsonlib_dir=$(dirname $0)/../../../net/forwarding 5*f72e2f48SDanielle Ratson 6*f72e2f48SDanielle RatsonALL_TESTS=" 7*f72e2f48SDanielle Ratson autoneg 8*f72e2f48SDanielle Ratson autoneg_force_mode 9*f72e2f48SDanielle Ratson" 10*f72e2f48SDanielle Ratson 11*f72e2f48SDanielle RatsonNUM_NETIFS=2 12*f72e2f48SDanielle Ratson: ${TIMEOUT:=30000} # ms 13*f72e2f48SDanielle Ratsonsource $lib_dir/lib.sh 14*f72e2f48SDanielle Ratsonsource $lib_dir/ethtool_lib.sh 15*f72e2f48SDanielle Ratson 16*f72e2f48SDanielle Ratsonsetup_prepare() 17*f72e2f48SDanielle Ratson{ 18*f72e2f48SDanielle Ratson swp1=${NETIFS[p1]} 19*f72e2f48SDanielle Ratson swp2=${NETIFS[p2]} 20*f72e2f48SDanielle Ratson 21*f72e2f48SDanielle Ratson ip link set dev $swp1 up 22*f72e2f48SDanielle Ratson ip link set dev $swp2 up 23*f72e2f48SDanielle Ratson 24*f72e2f48SDanielle Ratson busywait "$TIMEOUT" wait_for_port_up ethtool $swp2 25*f72e2f48SDanielle Ratson check_err $? "ports did not come up" 26*f72e2f48SDanielle Ratson 27*f72e2f48SDanielle Ratson local lanes_exist=$(ethtool $swp1 | grep 'Lanes:') 28*f72e2f48SDanielle Ratson if [[ -z $lanes_exist ]]; then 29*f72e2f48SDanielle Ratson log_test "SKIP: driver does not support lanes setting" 30*f72e2f48SDanielle Ratson exit 1 31*f72e2f48SDanielle Ratson fi 32*f72e2f48SDanielle Ratson 33*f72e2f48SDanielle Ratson ip link set dev $swp2 down 34*f72e2f48SDanielle Ratson ip link set dev $swp1 down 35*f72e2f48SDanielle Ratson} 36*f72e2f48SDanielle Ratson 37*f72e2f48SDanielle Ratsoncheck_lanes() 38*f72e2f48SDanielle Ratson{ 39*f72e2f48SDanielle Ratson local dev=$1; shift 40*f72e2f48SDanielle Ratson local lanes=$1; shift 41*f72e2f48SDanielle Ratson local max_speed=$1; shift 42*f72e2f48SDanielle Ratson local chosen_lanes 43*f72e2f48SDanielle Ratson 44*f72e2f48SDanielle Ratson chosen_lanes=$(ethtool $dev | grep 'Lanes:') 45*f72e2f48SDanielle Ratson chosen_lanes=${chosen_lanes#*"Lanes: "} 46*f72e2f48SDanielle Ratson 47*f72e2f48SDanielle Ratson ((chosen_lanes == lanes)) 48*f72e2f48SDanielle Ratson check_err $? "swp1 advertise $max_speed and $lanes, devs sync to $chosen_lanes" 49*f72e2f48SDanielle Ratson} 50*f72e2f48SDanielle Ratson 51*f72e2f48SDanielle Ratsoncheck_unsupported_lanes() 52*f72e2f48SDanielle Ratson{ 53*f72e2f48SDanielle Ratson local dev=$1; shift 54*f72e2f48SDanielle Ratson local max_speed=$1; shift 55*f72e2f48SDanielle Ratson local max_lanes=$1; shift 56*f72e2f48SDanielle Ratson local autoneg=$1; shift 57*f72e2f48SDanielle Ratson local autoneg_str="" 58*f72e2f48SDanielle Ratson 59*f72e2f48SDanielle Ratson local unsupported_lanes=$((max_lanes *= 2)) 60*f72e2f48SDanielle Ratson 61*f72e2f48SDanielle Ratson if [[ $autoneg -eq 0 ]]; then 62*f72e2f48SDanielle Ratson autoneg_str="autoneg off" 63*f72e2f48SDanielle Ratson fi 64*f72e2f48SDanielle Ratson 65*f72e2f48SDanielle Ratson ethtool -s $swp1 speed $max_speed lanes $unsupported_lanes $autoneg_str &> /dev/null 66*f72e2f48SDanielle Ratson check_fail $? "Unsuccessful $unsupported_lanes lanes setting was expected" 67*f72e2f48SDanielle Ratson} 68*f72e2f48SDanielle Ratson 69*f72e2f48SDanielle Ratsonmax_speed_and_lanes_get() 70*f72e2f48SDanielle Ratson{ 71*f72e2f48SDanielle Ratson local dev=$1; shift 72*f72e2f48SDanielle Ratson local arr=("$@") 73*f72e2f48SDanielle Ratson local max_lanes 74*f72e2f48SDanielle Ratson local max_speed 75*f72e2f48SDanielle Ratson local -a lanes_arr 76*f72e2f48SDanielle Ratson local -a speeds_arr 77*f72e2f48SDanielle Ratson local -a max_values 78*f72e2f48SDanielle Ratson 79*f72e2f48SDanielle Ratson for ((i=0; i<${#arr[@]}; i+=2)); do 80*f72e2f48SDanielle Ratson speeds_arr+=("${arr[$i]}") 81*f72e2f48SDanielle Ratson lanes_arr+=("${arr[i+1]}") 82*f72e2f48SDanielle Ratson done 83*f72e2f48SDanielle Ratson 84*f72e2f48SDanielle Ratson max_values+=($(get_max "${speeds_arr[@]}")) 85*f72e2f48SDanielle Ratson max_values+=($(get_max "${lanes_arr[@]}")) 86*f72e2f48SDanielle Ratson 87*f72e2f48SDanielle Ratson echo ${max_values[@]} 88*f72e2f48SDanielle Ratson} 89*f72e2f48SDanielle Ratson 90*f72e2f48SDanielle Ratsonsearch_linkmode() 91*f72e2f48SDanielle Ratson{ 92*f72e2f48SDanielle Ratson local speed=$1; shift 93*f72e2f48SDanielle Ratson local lanes=$1; shift 94*f72e2f48SDanielle Ratson local arr=("$@") 95*f72e2f48SDanielle Ratson 96*f72e2f48SDanielle Ratson for ((i=0; i<${#arr[@]}; i+=2)); do 97*f72e2f48SDanielle Ratson if [[ $speed -eq ${arr[$i]} && $lanes -eq ${arr[i+1]} ]]; then 98*f72e2f48SDanielle Ratson return 1 99*f72e2f48SDanielle Ratson fi 100*f72e2f48SDanielle Ratson done 101*f72e2f48SDanielle Ratson return 0 102*f72e2f48SDanielle Ratson} 103*f72e2f48SDanielle Ratson 104*f72e2f48SDanielle Ratsonautoneg() 105*f72e2f48SDanielle Ratson{ 106*f72e2f48SDanielle Ratson RET=0 107*f72e2f48SDanielle Ratson 108*f72e2f48SDanielle Ratson local lanes 109*f72e2f48SDanielle Ratson local max_speed 110*f72e2f48SDanielle Ratson local max_lanes 111*f72e2f48SDanielle Ratson 112*f72e2f48SDanielle Ratson local -a linkmodes_params=($(dev_linkmodes_params_get $swp1 1)) 113*f72e2f48SDanielle Ratson local -a max_values=($(max_speed_and_lanes_get $swp1 "${linkmodes_params[@]}")) 114*f72e2f48SDanielle Ratson max_speed=${max_values[0]} 115*f72e2f48SDanielle Ratson max_lanes=${max_values[1]} 116*f72e2f48SDanielle Ratson 117*f72e2f48SDanielle Ratson lanes=$max_lanes 118*f72e2f48SDanielle Ratson 119*f72e2f48SDanielle Ratson while [[ $lanes -ge 1 ]]; do 120*f72e2f48SDanielle Ratson search_linkmode $max_speed $lanes "${linkmodes_params[@]}" 121*f72e2f48SDanielle Ratson if [[ $? -eq 1 ]]; then 122*f72e2f48SDanielle Ratson ethtool_set $swp1 speed $max_speed lanes $lanes 123*f72e2f48SDanielle Ratson ip link set dev $swp1 up 124*f72e2f48SDanielle Ratson ip link set dev $swp2 up 125*f72e2f48SDanielle Ratson busywait "$TIMEOUT" wait_for_port_up ethtool $swp2 126*f72e2f48SDanielle Ratson check_err $? "ports did not come up" 127*f72e2f48SDanielle Ratson 128*f72e2f48SDanielle Ratson check_lanes $swp1 $lanes $max_speed 129*f72e2f48SDanielle Ratson log_test "$lanes lanes is autonegotiated" 130*f72e2f48SDanielle Ratson fi 131*f72e2f48SDanielle Ratson let $((lanes /= 2)) 132*f72e2f48SDanielle Ratson done 133*f72e2f48SDanielle Ratson 134*f72e2f48SDanielle Ratson check_unsupported_lanes $swp1 $max_speed $max_lanes 1 135*f72e2f48SDanielle Ratson log_test "Lanes number larger than max width is not set" 136*f72e2f48SDanielle Ratson 137*f72e2f48SDanielle Ratson ip link set dev $swp2 down 138*f72e2f48SDanielle Ratson ip link set dev $swp1 down 139*f72e2f48SDanielle Ratson} 140*f72e2f48SDanielle Ratson 141*f72e2f48SDanielle Ratsonautoneg_force_mode() 142*f72e2f48SDanielle Ratson{ 143*f72e2f48SDanielle Ratson RET=0 144*f72e2f48SDanielle Ratson 145*f72e2f48SDanielle Ratson local lanes 146*f72e2f48SDanielle Ratson local max_speed 147*f72e2f48SDanielle Ratson local max_lanes 148*f72e2f48SDanielle Ratson 149*f72e2f48SDanielle Ratson local -a linkmodes_params=($(dev_linkmodes_params_get $swp1 1)) 150*f72e2f48SDanielle Ratson local -a max_values=($(max_speed_and_lanes_get $swp1 "${linkmodes_params[@]}")) 151*f72e2f48SDanielle Ratson max_speed=${max_values[0]} 152*f72e2f48SDanielle Ratson max_lanes=${max_values[1]} 153*f72e2f48SDanielle Ratson 154*f72e2f48SDanielle Ratson lanes=$max_lanes 155*f72e2f48SDanielle Ratson 156*f72e2f48SDanielle Ratson while [[ $lanes -ge 1 ]]; do 157*f72e2f48SDanielle Ratson search_linkmode $max_speed $lanes "${linkmodes_params[@]}" 158*f72e2f48SDanielle Ratson if [[ $? -eq 1 ]]; then 159*f72e2f48SDanielle Ratson ethtool_set $swp1 speed $max_speed lanes $lanes autoneg off 160*f72e2f48SDanielle Ratson ethtool_set $swp2 speed $max_speed lanes $lanes autoneg off 161*f72e2f48SDanielle Ratson ip link set dev $swp1 up 162*f72e2f48SDanielle Ratson ip link set dev $swp2 up 163*f72e2f48SDanielle Ratson busywait "$TIMEOUT" wait_for_port_up ethtool $swp2 164*f72e2f48SDanielle Ratson check_err $? "ports did not come up" 165*f72e2f48SDanielle Ratson 166*f72e2f48SDanielle Ratson check_lanes $swp1 $lanes $max_speed 167*f72e2f48SDanielle Ratson log_test "Autoneg off, $lanes lanes detected during force mode" 168*f72e2f48SDanielle Ratson fi 169*f72e2f48SDanielle Ratson let $((lanes /= 2)) 170*f72e2f48SDanielle Ratson done 171*f72e2f48SDanielle Ratson 172*f72e2f48SDanielle Ratson check_unsupported_lanes $swp1 $max_speed $max_lanes 0 173*f72e2f48SDanielle Ratson log_test "Lanes number larger than max width is not set" 174*f72e2f48SDanielle Ratson 175*f72e2f48SDanielle Ratson ip link set dev $swp2 down 176*f72e2f48SDanielle Ratson ip link set dev $swp1 down 177*f72e2f48SDanielle Ratson 178*f72e2f48SDanielle Ratson ethtool -s $swp2 autoneg on 179*f72e2f48SDanielle Ratson ethtool -s $swp1 autoneg on 180*f72e2f48SDanielle Ratson} 181*f72e2f48SDanielle Ratson 182*f72e2f48SDanielle Ratsoncheck_ethtool_lanes_support 183*f72e2f48SDanielle Ratsonsetup_prepare 184*f72e2f48SDanielle Ratson 185*f72e2f48SDanielle Ratsontests_run 186*f72e2f48SDanielle Ratson 187*f72e2f48SDanielle Ratsonexit $EXIT_STATUS 188