diff options
author | David S. Miller <davem@davemloft.net> | 2020-01-03 02:40:14 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-01-03 02:40:14 +0300 |
commit | f5e5d27248ffbb8bc86706efa4717eb41c114718 (patch) | |
tree | c337153cb6d0cf836bd5d74e57f21373d7974b14 | |
parent | c9a2069b1dbadf7cb85da0fd9df62d25e3642f03 (diff) | |
parent | c5341bcc337ca762faa58790c2065c76cd05f2e6 (diff) | |
download | linux-f5e5d27248ffbb8bc86706efa4717eb41c114718.tar.xz |
Merge branch 'mlxsw-Allow-setting-default-port-priority'
Ido Schimmel says:
====================
mlxsw: Allow setting default port priority
Petr says:
When LLDP APP TLV selector 1 (EtherType) is used with PID of 0, the
corresponding entry specifies "default application priority [...] when
application priority is not otherwise specified."
mlxsw currently supports this type of APP entry, but uses it only as a
fallback for unspecified DSCP rules. However non-IP traffic is prioritized
according to port-default priority, not according to the DSCP-to-prio
tables, and thus it's currently not possible to prioritize such traffic
correctly.
This patchset extends the use of the abovementioned APP entry to also set
default port priority (in patches #1 and #2) and then (in patch #3) adds a
selftest.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/reg.h | 33 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c | 17 | ||||
-rwxr-xr-x | tools/testing/selftests/drivers/net/mlxsw/qos_defprio.sh | 176 | ||||
-rw-r--r-- | tools/testing/selftests/net/forwarding/lib.sh | 23 |
4 files changed, 249 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index 2b8b4ed6bbef..fd59280cf979 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -3748,6 +3748,38 @@ mlxsw_reg_qpdsm_prio_pack(char *payload, unsigned short prio, u8 dscp) mlxsw_reg_qpdsm_prio_entry_color2_dscp_set(payload, prio, dscp); } +/* QPDP - QoS Port DSCP to Priority Mapping Register + * ------------------------------------------------- + * This register controls the port default Switch Priority and Color. The + * default Switch Priority and Color are used for frames where the trust state + * uses default values. All member ports of a LAG should be configured with the + * same default values. + */ +#define MLXSW_REG_QPDP_ID 0x4007 +#define MLXSW_REG_QPDP_LEN 0x8 + +MLXSW_REG_DEFINE(qpdp, MLXSW_REG_QPDP_ID, MLXSW_REG_QPDP_LEN); + +/* reg_qpdp_local_port + * Local Port. Supported for data packets from CPU port. + * Access: Index + */ +MLXSW_ITEM32(reg, qpdp, local_port, 0x00, 16, 8); + +/* reg_qpdp_switch_prio + * Default port Switch Priority (default 0) + * Access: RW + */ +MLXSW_ITEM32(reg, qpdp, switch_prio, 0x04, 0, 4); + +static inline void mlxsw_reg_qpdp_pack(char *payload, u8 local_port, + u8 switch_prio) +{ + MLXSW_REG_ZERO(qpdp, payload); + mlxsw_reg_qpdp_local_port_set(payload, local_port); + mlxsw_reg_qpdp_switch_prio_set(payload, switch_prio); +} + /* QPDPM - QoS Port DSCP to Priority Mapping Register * -------------------------------------------------- * This register controls the mapping from DSCP field to @@ -10580,6 +10612,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = { MLXSW_REG(qeec), MLXSW_REG(qrwe), MLXSW_REG(qpdsm), + MLXSW_REG(qpdp), MLXSW_REG(qpdpm), MLXSW_REG(qtctm), MLXSW_REG(qpsc), diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c index fe3bbba90659..db66f2b56a6d 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c @@ -369,6 +369,17 @@ err_update_qrwe: } static int +mlxsw_sp_port_dcb_app_update_qpdp(struct mlxsw_sp_port *mlxsw_sp_port, + u8 default_prio) +{ + struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; + char qpdp_pl[MLXSW_REG_QPDP_LEN]; + + mlxsw_reg_qpdp_pack(qpdp_pl, mlxsw_sp_port->local_port, default_prio); + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qpdp), qpdp_pl); +} + +static int mlxsw_sp_port_dcb_app_update_qpdpm(struct mlxsw_sp_port *mlxsw_sp_port, struct dcb_ieee_app_dscp_map *map) { @@ -405,6 +416,12 @@ static int mlxsw_sp_port_dcb_app_update(struct mlxsw_sp_port *mlxsw_sp_port) int err; default_prio = mlxsw_sp_port_dcb_app_default_prio(mlxsw_sp_port); + err = mlxsw_sp_port_dcb_app_update_qpdp(mlxsw_sp_port, default_prio); + if (err) { + netdev_err(mlxsw_sp_port->dev, "Couldn't configure port default priority\n"); + return err; + } + have_dscp = mlxsw_sp_port_dcb_app_prio_dscp_map(mlxsw_sp_port, &prio_map); diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_defprio.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_defprio.sh new file mode 100755 index 000000000000..eff6393ce974 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/qos_defprio.sh @@ -0,0 +1,176 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +# Test for port-default priority. Non-IP packets ingress $swp1 and are +# prioritized according to the default priority specified at the port. +# rx_octets_prio_* counters are used to verify the prioritization. +# +# +-----------------------+ +# | H1 | +# | + $h1 | +# | | 192.0.2.1/28 | +# +----|------------------+ +# | +# +----|------------------+ +# | SW | | +# | + $swp1 | +# | 192.0.2.2/28 | +# | APP=<prio>,1,0 | +# +-----------------------+ + +ALL_TESTS=" + ping_ipv4 + test_defprio +" + +lib_dir=$(dirname $0)/../../../net/forwarding + +NUM_NETIFS=2 +: ${HIT_TIMEOUT:=1000} # ms +source $lib_dir/lib.sh + +declare -a APP + +defprio_install() +{ + local dev=$1; shift + local prio=$1; shift + local app="app=$prio,1,0" + + lldptool -T -i $dev -V APP $app >/dev/null + lldpad_app_wait_set $dev + APP[$prio]=$app +} + +defprio_uninstall() +{ + local dev=$1; shift + local prio=$1; shift + local app=${APP[$prio]} + + lldptool -T -i $dev -V APP -d $app >/dev/null + lldpad_app_wait_del + unset APP[$prio] +} + +defprio_flush() +{ + local dev=$1; shift + local prio + + if ((${#APP[@]})); then + lldptool -T -i $dev -V APP -d ${APP[@]} >/dev/null + fi + lldpad_app_wait_del + APP=() +} + +h1_create() +{ + simple_if_init $h1 192.0.2.1/28 +} + +h1_destroy() +{ + simple_if_fini $h1 192.0.2.1/28 +} + +switch_create() +{ + ip link set dev $swp1 up + ip addr add dev $swp1 192.0.2.2/28 +} + +switch_destroy() +{ + defprio_flush $swp1 + ip addr del dev $swp1 192.0.2.2/28 + ip link set dev $swp1 down +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + vrf_prepare + + h1_create + switch_create +} + +cleanup() +{ + pre_cleanup + + switch_destroy + h1_destroy + + vrf_cleanup +} + +ping_ipv4() +{ + ping_test $h1 192.0.2.2 +} + +wait_for_packets() +{ + local t0=$1; shift + local prio_observe=$1; shift + + local t1=$(ethtool_stats_get $swp1 rx_frames_prio_$prio_observe) + local delta=$((t1 - t0)) + echo $delta + ((delta >= 10)) +} + +__test_defprio() +{ + local prio_install=$1; shift + local prio_observe=$1; shift + local delta + local key + local i + + RET=0 + + defprio_install $swp1 $prio_install + + local t0=$(ethtool_stats_get $swp1 rx_frames_prio_$prio_observe) + mausezahn -q $h1 -d 100m -c 10 -t arp reply + delta=$(busywait "$HIT_TIMEOUT" wait_for_packets $t0 $prio_observe) + + check_err $? "Default priority $prio_install/$prio_observe: Expected to capture 10 packets, got $delta." + log_test "Default priority $prio_install/$prio_observe" + + defprio_uninstall $swp1 $prio_install +} + +test_defprio() +{ + local prio + + for prio in {0..7}; do + __test_defprio $prio $prio + done + + defprio_install $swp1 3 + __test_defprio 0 3 + __test_defprio 1 3 + __test_defprio 2 3 + __test_defprio 4 4 + __test_defprio 5 5 + __test_defprio 6 6 + __test_defprio 7 7 + defprio_uninstall $swp1 3 +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh index a0b09bb6995e..8dc5fac98cbc 100644 --- a/tools/testing/selftests/net/forwarding/lib.sh +++ b/tools/testing/selftests/net/forwarding/lib.sh @@ -225,6 +225,29 @@ log_info() echo "INFO: $msg" } +busywait() +{ + local timeout=$1; shift + + local start_time="$(date -u +%s%3N)" + while true + do + local out + out=$("$@") + local ret=$? + if ((!ret)); then + echo -n "$out" + return 0 + fi + + local current_time="$(date -u +%s%3N)" + if ((current_time - start_time > timeout)); then + echo -n "$out" + return 1 + fi + done +} + setup_wait_dev() { local dev=$1; shift |