1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#
4# This test sends many small packets (size is less than cell size) through the
5# switch. A shaper is used in $swp2, so the traffic is limited there. Packets
6# are queued till they will be sent.
7#
8# The idea is to verify that the switch can handle at least 85% of maximum
9# supported descrpitors by hardware. Then, we verify that the driver configures
10# firmware to allow infinite size of egress descriptor pool, and does not use a
11# lower limitation. Increase the size of the relevant pools such that the pool's
12# size does not limit the traffic.
13
14# +-----------------------+
15# | H1                    |
16# |   + $h1.111           |
17# |   | 192.0.2.33/28     |
18# |   |                   |
19# |   + $h1               |
20# +---|-------------------+
21#     |
22# +---|-----------------------------+
23# |   + $swp1                       |
24# |   | iPOOL1                      |
25# |   |                             |
26# | +-|------------------------+    |
27# | | + $swp1.111              |    |
28# | |                          |    |
29# | | BR1                      |    |
30# | |                          |    |
31# | | + $swp2.111              |    |
32# | +-|------------------------+    |
33# |   |                             |
34# |   + $swp2                       |
35# |   | ePOOL6                      |
36# |   | 1mbit                       |
37# +---+-----------------------------+
38#     |
39# +---|-------------------+
40# |   + $h2            H2 |
41# |   |                   |
42# |   + $h2.111           |
43# |     192.0.2.34/28     |
44# +-----------------------+
45#
46
47ALL_TESTS="
48	ping_ipv4
49	max_descriptors
50"
51
52lib_dir=$(dirname $0)/../../../net/forwarding
53
54NUM_NETIFS=4
55source $lib_dir/lib.sh
56source $lib_dir/devlink_lib.sh
57source mlxsw_lib.sh
58
59MAX_POOL_SIZE=$(devlink_pool_size_get)
60SHAPER_RATE=1mbit
61
62# The current TBF qdisc interface does not allow us to configure the shaper to
63# flat zero. The ASIC shaper is guaranteed to work with a granularity of
64# 200Mbps. On Spectrum-2, writing a value close to zero instead of zero works
65# well, but the performance on Spectrum-1 is unpredictable. Thus, do not run the
66# test on Spectrum-1.
67mlxsw_only_on_spectrum 2+ || exit
68
69h1_create()
70{
71	simple_if_init $h1
72	defer simple_if_fini $h1
73
74	vlan_create $h1 111 v$h1 192.0.2.33/28
75	defer vlan_destroy $h1 111
76	ip link set dev $h1.111 type vlan egress-qos-map 0:1
77}
78
79h2_create()
80{
81	simple_if_init $h2
82	defer simple_if_fini $h2
83
84	vlan_create $h2 111 v$h2 192.0.2.34/28
85	defer vlan_destroy $h2 111
86}
87
88switch_create()
89{
90	# pools
91	# -----
92	# devlink_pool_size_thtype_restore needs to be done first so that we can
93	# reset the various limits to values that are only valid for the
94	# original static / dynamic setting.
95
96	devlink_pool_size_thtype_save 1
97	devlink_pool_size_thtype_set 1 dynamic $MAX_POOL_SIZE
98	defer_prio devlink_pool_size_thtype_restore 1
99
100	devlink_pool_size_thtype_save 6
101	devlink_pool_size_thtype_set 6 static $MAX_POOL_SIZE
102	defer_prio devlink_pool_size_thtype_restore 6
103
104	# $swp1
105	# -----
106
107	ip link set dev $swp1 up
108	defer ip link set dev $swp1 down
109
110	vlan_create $swp1 111
111	defer vlan_destroy $swp1 111
112	ip link set dev $swp1.111 type vlan ingress-qos-map 0:0 1:1
113
114	devlink_port_pool_th_save $swp1 1
115	devlink_port_pool_th_set $swp1 1 16
116	defer devlink_tc_bind_pool_th_restore $swp1 1 ingress
117
118	devlink_tc_bind_pool_th_save $swp1 1 ingress
119	devlink_tc_bind_pool_th_set $swp1 1 ingress 1 16
120	defer devlink_port_pool_th_restore $swp1 1
121
122	tc qdisc replace dev $swp1 root handle 1: \
123	   ets bands 8 strict 8 priomap 7 6
124	defer tc qdisc del dev $swp1 root
125
126	dcb buffer set dev $swp1 prio-buffer all:0 1:1
127	defer dcb buffer set dev $swp1 prio-buffer all:0
128
129	# $swp2
130	# -----
131
132	ip link set dev $swp2 up
133	defer ip link set dev $swp2 down
134
135	vlan_create $swp2 111
136	defer vlan_destroy $swp2 111
137	ip link set dev $swp2.111 type vlan egress-qos-map 0:0 1:1
138
139	devlink_port_pool_th_save $swp2 6
140	devlink_port_pool_th_set $swp2 6 $MAX_POOL_SIZE
141	defer devlink_tc_bind_pool_th_restore $swp2 1 egress
142
143	devlink_tc_bind_pool_th_save $swp2 1 egress
144	devlink_tc_bind_pool_th_set $swp2 1 egress 6 $MAX_POOL_SIZE
145	defer devlink_port_pool_th_restore $swp2 6
146
147	tc qdisc replace dev $swp2 root handle 1: tbf rate $SHAPER_RATE \
148		burst 128K limit 500M
149	defer tc qdisc del dev $swp2 root
150
151	tc qdisc replace dev $swp2 parent 1:1 handle 11: \
152		ets bands 8 strict 8 priomap 7 6
153	defer tc qdisc del dev $swp2 parent 1:1 handle 11:
154
155	# bridge
156	# ------
157
158	ip link add name br1 type bridge vlan_filtering 0
159	defer ip link del dev br1
160
161	ip link set dev $swp1.111 master br1
162	defer ip link set dev $swp1.111 nomaster
163
164	ip link set dev br1 up
165	defer ip link set dev br1 down
166
167	ip link set dev $swp2.111 master br1
168	defer ip link set dev $swp2.111 nomaster
169}
170
171setup_prepare()
172{
173	h1=${NETIFS[p1]}
174	swp1=${NETIFS[p2]}
175
176	swp2=${NETIFS[p3]}
177	h2=${NETIFS[p4]}
178
179	h2mac=$(mac_get $h2)
180
181	vrf_prepare
182	defer vrf_cleanup
183
184	h1_create
185	h2_create
186	switch_create
187}
188
189ping_ipv4()
190{
191	ping_test $h1 192.0.2.34 " h1->h2"
192}
193
194percentage_used()
195{
196	local num_packets=$1; shift
197	local max_packets=$1; shift
198
199	bc <<< "
200	    scale=2
201	    100 * $num_packets / $max_packets
202	"
203}
204
205max_descriptors()
206{
207	local cell_size=$(devlink_cell_size_get)
208	local exp_perc_used=85
209	local max_descriptors
210	local pktsize=30
211
212	RET=0
213
214	max_descriptors=$(mlxsw_max_descriptors_get) || exit 1
215
216	local d0=$(ethtool_stats_get $swp2 tc_no_buffer_discard_uc_tc_1)
217
218	log_info "Send many small packets, packet size = $pktsize bytes"
219	start_traffic_pktsize $pktsize $h1.111 192.0.2.33 192.0.2.34 $h2mac
220	defer stop_traffic $!
221
222	# Sleep to wait for congestion.
223	sleep 5
224
225	local d1=$(ethtool_stats_get $swp2 tc_no_buffer_discard_uc_tc_1)
226	((d1 == d0))
227	check_err $? "Drops seen on egress port: $d0 -> $d1 ($((d1 - d0)))"
228
229	# Check how many packets the switch can handle, the limitation is
230	# maximum descriptors.
231	local pkts_bytes=$(ethtool_stats_get $swp2 tc_transmit_queue_tc_1)
232	local pkts_num=$((pkts_bytes / cell_size))
233	local perc_used=$(percentage_used $pkts_num $max_descriptors)
234
235	check_err $(bc <<< "$perc_used < $exp_perc_used") \
236		"Expected > $exp_perc_used% of descriptors, handle $perc_used%"
237
238	log_test "Maximum descriptors usage. The percentage used is $perc_used%"
239}
240
241trap cleanup EXIT
242setup_prepare
243setup_wait
244tests_run
245
246exit $EXIT_STATUS
247