1#!/usr/bin/env python3 2# SPDX-License-Identifier: GPL-2.0 3 4import re 5from os import path 6from lib.py import ksft_run, ksft_exit 7from lib.py import NetDrvEpEnv 8from lib.py import bkg, cmd, defer, ethtool, wait_port_listen 9 10 11def _get_current_settings(cfg): 12 output = ethtool(f"-g {cfg.ifname}", host=cfg.remote).stdout 13 rx_ring = re.findall(r'RX:\s+(\d+)', output) 14 hds_thresh = re.findall(r'HDS thresh:\s+(\d+)', output) 15 return (int(rx_ring[1]), int(hds_thresh[1])) 16 17 18def _get_combined_channels(cfg): 19 output = ethtool(f"-l {cfg.ifname}", host=cfg.remote).stdout 20 values = re.findall(r'Combined:\s+(\d+)', output) 21 return int(values[1]) 22 23 24def _create_rss_ctx(cfg, chans): 25 output = ethtool(f"-X {cfg.ifname} context new start {chans - 1} equal 1", host=cfg.remote).stdout 26 values = re.search(r'New RSS context is (\d+)', output).group(1) 27 ctx_id = int(values) 28 return (ctx_id, defer(ethtool, f"-X {cfg.ifname} delete context {ctx_id}", host=cfg.remote)) 29 30 31def _set_flow_rule(cfg, chan): 32 output = ethtool(f"-N {cfg.ifname} flow-type tcp6 dst-port 9999 action {chan}", host=cfg.remote).stdout 33 values = re.search(r'ID (\d+)', output).group(1) 34 return int(values) 35 36 37def _set_flow_rule_rss(cfg, chan): 38 output = ethtool(f"-N {cfg.ifname} flow-type tcp6 dst-port 9999 action {chan}", host=cfg.remote).stdout 39 values = re.search(r'ID (\d+)', output).group(1) 40 return int(values) 41 42 43def test_zcrx(cfg) -> None: 44 cfg.require_ipver('6') 45 46 combined_chans = _get_combined_channels(cfg) 47 if combined_chans < 2: 48 raise KsftSkipEx('at least 2 combined channels required') 49 (rx_ring, hds_thresh) = _get_current_settings(cfg) 50 51 ethtool(f"-G {cfg.ifname} tcp-data-split on", host=cfg.remote) 52 defer(ethtool, f"-G {cfg.ifname} tcp-data-split auto", host=cfg.remote) 53 ethtool(f"-G {cfg.ifname} hds-thresh 0", host=cfg.remote) 54 defer(ethtool, f"-G {cfg.ifname} hds-thresh {hds_thresh}", host=cfg.remote) 55 ethtool(f"-G {cfg.ifname} rx 64", host=cfg.remote) 56 defer(ethtool, f"-G {cfg.ifname} rx {rx_ring}", host=cfg.remote) 57 ethtool(f"-X {cfg.ifname} equal {combined_chans - 1}", host=cfg.remote) 58 defer(ethtool, f"-X {cfg.ifname} default", host=cfg.remote) 59 flow_rule_id = _set_flow_rule(cfg, combined_chans - 1) 60 defer(ethtool, f"-N {cfg.ifname} delete {flow_rule_id}", host=cfg.remote) 61 62 rx_cmd = f"{cfg.bin_remote} -s -p 9999 -i {cfg.ifname} -q {combined_chans - 1}" 63 tx_cmd = f"{cfg.bin_local} -c -h {cfg.remote_addr_v['6']} -p 9999 -l 12840" 64 with bkg(rx_cmd, host=cfg.remote, exit_wait=True): 65 wait_port_listen(9999, proto="tcp", host=cfg.remote) 66 cmd(tx_cmd) 67 68 69def test_zcrx_oneshot(cfg) -> None: 70 cfg.require_ipver('6') 71 72 combined_chans = _get_combined_channels(cfg) 73 if combined_chans < 2: 74 raise KsftSkipEx('at least 2 combined channels required') 75 (rx_ring, hds_thresh) = _get_current_settings(cfg) 76 77 ethtool(f"-G {cfg.ifname} tcp-data-split on", host=cfg.remote) 78 defer(ethtool, f"-G {cfg.ifname} tcp-data-split auto", host=cfg.remote) 79 ethtool(f"-G {cfg.ifname} hds-thresh 0", host=cfg.remote) 80 defer(ethtool, f"-G {cfg.ifname} hds-thresh {hds_thresh}", host=cfg.remote) 81 ethtool(f"-G {cfg.ifname} rx 64", host=cfg.remote) 82 defer(ethtool, f"-G {cfg.ifname} rx {rx_ring}", host=cfg.remote) 83 ethtool(f"-X {cfg.ifname} equal {combined_chans - 1}", host=cfg.remote) 84 defer(ethtool, f"-X {cfg.ifname} default", host=cfg.remote) 85 flow_rule_id = _set_flow_rule(cfg, combined_chans - 1) 86 defer(ethtool, f"-N {cfg.ifname} delete {flow_rule_id}", host=cfg.remote) 87 88 rx_cmd = f"{cfg.bin_remote} -s -p 9999 -i {cfg.ifname} -q {combined_chans - 1} -o 4" 89 tx_cmd = f"{cfg.bin_local} -c -h {cfg.remote_addr_v['6']} -p 9999 -l 4096 -z 16384" 90 with bkg(rx_cmd, host=cfg.remote, exit_wait=True): 91 wait_port_listen(9999, proto="tcp", host=cfg.remote) 92 cmd(tx_cmd) 93 94 95def test_zcrx_rss(cfg) -> None: 96 cfg.require_ipver('6') 97 98 combined_chans = _get_combined_channels(cfg) 99 if combined_chans < 2: 100 raise KsftSkipEx('at least 2 combined channels required') 101 (rx_ring, hds_thresh) = _get_current_settings(cfg) 102 103 ethtool(f"-G {cfg.ifname} tcp-data-split on", host=cfg.remote) 104 defer(ethtool, f"-G {cfg.ifname} tcp-data-split auto", host=cfg.remote) 105 ethtool(f"-G {cfg.ifname} hds-thresh 0", host=cfg.remote) 106 defer(ethtool, f"-G {cfg.ifname} hds-thresh {hds_thresh}", host=cfg.remote) 107 ethtool(f"-G {cfg.ifname} rx 64", host=cfg.remote) 108 defer(ethtool, f"-G {cfg.ifname} rx {rx_ring}", host=cfg.remote) 109 ethtool(f"-X {cfg.ifname} equal {combined_chans - 1}", host=cfg.remote) 110 defer(ethtool, f"-X {cfg.ifname} default", host=cfg.remote) 111 112 (ctx_id, delete_ctx) = _create_rss_ctx(cfg, combined_chans) 113 flow_rule_id = _set_flow_rule_rss(cfg, ctx_id) 114 defer(ethtool, f"-N {cfg.ifname} delete {flow_rule_id}", host=cfg.remote) 115 116 rx_cmd = f"{cfg.bin_remote} -s -p 9999 -i {cfg.ifname} -q {combined_chans - 1}" 117 tx_cmd = f"{cfg.bin_local} -c -h {cfg.remote_addr_v['6']} -p 9999 -l 12840" 118 with bkg(rx_cmd, host=cfg.remote, exit_wait=True): 119 wait_port_listen(9999, proto="tcp", host=cfg.remote) 120 cmd(tx_cmd) 121 122 123def main() -> None: 124 with NetDrvEpEnv(__file__) as cfg: 125 cfg.bin_local = path.abspath(path.dirname(__file__) + "/../../../drivers/net/hw/iou-zcrx") 126 cfg.bin_remote = cfg.remote.deploy(cfg.bin_local) 127 128 ksft_run(globs=globals(), case_pfx={"test_"}, args=(cfg, )) 129 ksft_exit() 130 131 132if __name__ == "__main__": 133 main() 134