summaryrefslogtreecommitdiffstats
path: root/tools/testing/selftests/drivers/net/hw/nic_link_layer.py
blob: efd92118053294a93afa5be6cb415a8e5b5ef432 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0

#Introduction:
#This file has basic link layer tests for generic NIC drivers.
#The test comprises of auto-negotiation, speed and duplex checks.
#
#Setup:
#Connect the DUT PC with NIC card to partner pc back via ethernet medium of your choice(RJ45, T1)
#
#        DUT PC                                              Partner PC
#┌───────────────────────┐                         ┌──────────────────────────┐
#│                       │                         │                          │
#│                       │                         │                          │
#│           ┌───────────┐                         │                          │
#│           │DUT NIC    │         Eth             │                          │
#│           │Interface ─┼─────────────────────────┼─    any eth Interface    │
#│           └───────────┘                         │                          │
#│                       │                         │                          │
#│                       │                         │                          │
#└───────────────────────┘                         └──────────────────────────┘
#
#Configurations:
#Required minimum ethtool version is 6.10 (supports json)
#Default values:
#time_delay = 8 #time taken to wait for transitions to happen, in seconds.

import time
import argparse
from lib.py import ksft_run, ksft_exit, ksft_pr, ksft_eq
from lib.py import KsftFailEx, KsftSkipEx
from lib.py import NetDrvEpEnv
from lib.py import LinkConfig

def _pre_test_checks(cfg: object, link_config: LinkConfig) -> None:
    if link_config.partner_netif is None:
        KsftSkipEx("Partner interface is not available")
    if not link_config.check_autoneg_supported() or not link_config.check_autoneg_supported(remote=True):
        KsftSkipEx(f"Auto-negotiation not supported for interface {cfg.ifname} or {link_config.partner_netif}")
    if not link_config.verify_link_up():
        raise KsftSkipEx(f"Link state of interface {cfg.ifname} is DOWN")

def verify_autonegotiation(cfg: object, expected_state: str, link_config: LinkConfig) -> None:
    if not link_config.verify_link_up():
        raise KsftSkipEx(f"Link state of interface {cfg.ifname} is DOWN")
    """Verifying the autonegotiation state in partner"""
    partner_autoneg_output = link_config.get_ethtool_field("auto-negotiation", remote=True)
    if partner_autoneg_output is None:
        KsftSkipEx(f"Auto-negotiation state not available for interface {link_config.partner_netif}")
    partner_autoneg_state = "on" if partner_autoneg_output is True else "off"

    ksft_eq(partner_autoneg_state, expected_state)

    """Verifying the autonegotiation state of local"""
    autoneg_output = link_config.get_ethtool_field("auto-negotiation")
    if autoneg_output is None:
        KsftSkipEx(f"Auto-negotiation state not available for interface {cfg.ifname}")
    actual_state = "on" if autoneg_output is True else "off"

    ksft_eq(actual_state, expected_state)

    """Verifying the link establishment"""
    link_available = link_config.get_ethtool_field("link-detected")
    if link_available is None:
        KsftSkipEx(f"Link status not available for interface {cfg.ifname}")
    if link_available != True:
        raise KsftSkipEx("Link not established at interface {cfg.ifname} after changing auto-negotiation")

def test_autonegotiation(cfg: object, link_config: LinkConfig, time_delay: int) -> None:
    _pre_test_checks(cfg, link_config)
    for state in ["off", "on"]:
        if not link_config.set_autonegotiation_state(state, remote=True):
            raise KsftSkipEx(f"Unable to set auto-negotiation state for interface {link_config.partner_netif}")
        if not link_config.set_autonegotiation_state(state):
            raise KsftSkipEx(f"Unable to set auto-negotiation state for interface {cfg.ifname}")
        time.sleep(time_delay)
        verify_autonegotiation(cfg, state, link_config)

def test_network_speed(cfg: object, link_config: LinkConfig, time_delay: int) -> None:
    _pre_test_checks(cfg, link_config)
    common_link_modes = link_config.common_link_modes
    if not common_link_modes:
        KsftSkipEx("No common link modes exist")
    speeds, duplex_modes = link_config.get_speed_duplex_values(common_link_modes)

    if speeds and duplex_modes and len(speeds) == len(duplex_modes):
        for idx in range(len(speeds)):
            speed = speeds[idx]
            duplex = duplex_modes[idx]
            if not link_config.set_speed_and_duplex(speed, duplex):
                raise KsftFailEx(f"Unable to set speed and duplex parameters for {cfg.ifname}")
            time.sleep(time_delay)
            if not link_config.verify_speed_and_duplex(speed, duplex):
                raise KsftSkipEx(f"Error occurred while verifying speed and duplex states for interface {cfg.ifname}")
    else:
        if not speeds or not duplex_modes:
            KsftSkipEx(f"No supported speeds or duplex modes found for interface {cfg.ifname}")
        else:
            KsftSkipEx("Mismatch in the number of speeds and duplex modes")

def main() -> None:
    parser = argparse.ArgumentParser(description="Run basic link layer tests for NIC driver")
    parser.add_argument('--time-delay', type=int, default=8, help='Time taken to wait for transitions to happen(in seconds). Default is 8 seconds.')
    args = parser.parse_args()
    time_delay = args.time_delay
    with NetDrvEpEnv(__file__, nsim_test=False) as cfg:
        link_config = LinkConfig(cfg)
        ksft_run(globs=globals(), case_pfx={"test_"}, args=(cfg, link_config, time_delay,))
        link_config.reset_interface()
    ksft_exit()

if __name__ == "__main__":
    main()