Linux Kernel Selftest development
 help / color / mirror / Atom feed
From: Andrew Lunn <andrew@lunn.ch>
To: Mohan Prasad J <mohan.prasad@microchip.com>
Cc: netdev@vger.kernel.org, davem@davemloft.net, kuba@kernel.org,
	edumazet@google.com, pabeni@redhat.com, shuah@kernel.org,
	linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org,
	horms@kernel.org, brett.creeley@amd.com, rosenp@gmail.com,
	UNGLinuxDriver@microchip.com, willemb@google.com
Subject: Re: [PATCH net-next v2 1/3] selftests: nic_basic_tests: Add selftest file for basic tests of NIC
Date: Tue, 17 Sep 2024 17:35:40 +0200	[thread overview]
Message-ID: <5c8779db-31c4-4b93-986a-bd489720fa4b@lunn.ch> (raw)
In-Reply-To: <20240917023525.2571082-2-mohan.prasad@microchip.com>

On Tue, Sep 17, 2024 at 08:04:07AM +0530, Mohan Prasad J wrote:
> Add selftest file to test basic features of a NIC driver.
> Tests for link modes, auto-negotiation are placed.
> Selftest makes use of ksft modules and ethtool.
> Add selftest file in the Makefile.

Thanks for reworking this.

> +++ b/tools/testing/selftests/drivers/net/hw/nic_basic_tests.py
> @@ -0,0 +1,145 @@
> +#!/usr/bin/env python3
> +# SPDX-License-Identifier: GPL-2.0
> +
> +#Introduction:
> +#This file has basic tests for generic NIC drivers.
> +#The test comprises of auto-negotiation, speed and duplex checks.
> +#Also has tests to check the throughput
> +#
> +#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:
> +# Change the below configuration based on your hw needs.
> +# """Default values"""
> +sleep_time = 5 #time taken to wait for transitions to happen, in seconds.
> +test_duration = 5  #performance test duration for the throughput check, in seconds.
> +throughput_threshold = 0.8 #percentage of throughput required to pass the throughput
> +
> +import time
> +import os
> +import re
> +import configparser
> +import json
> +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 cmd
> +from lib.py import ethtool
> +
> +"""Global variables"""
> +common_link_modes = []
> +
> +def get_ethtool_content(ifname: str, field: str):
> +    capture = False
> +    content = []
> +
> +    """Get the ethtool content for the interface"""
> +    process = ethtool(f"{ifname}")
> +    if process.ret != 0:
> +        raise KsftSkipEx(f"Error while getting the ethtool content for interface {ifname}")
> +    lines = process.stdout.splitlines()
> +
> +    """Retrieve the content of the field"""
> +    for line in lines:
> +        if field in line:
> +            capture = True
> +            data = line.split(":")[1].strip()
> +            content.extend(data.split())
> +            continue

Since you have batteries included python:

ethtool --json enp2s0
[sudo] password for andrew: 
[ {
        "ifname": "enp2s0",
        "supported-ports": [ "TP","MII" ],
        "supported-link-modes": [ "10baseT/Half","10baseT/Full","100baseT/Half","100baseT/Full","1000baseT/Full" ],
        "supported-pause-frame-use": "Symmetric Receive-only",
        "supports-auto-negotiation": true,
        "supported-fec-modes": [ ],
        "advertised-link-modes": [ "10baseT/Half","10baseT/Full","100baseT/Half","100baseT/Full","1000baseT/Full" ],
        "advertised-pause-frame-use": "Symmetric Receive-only",
        "advertised-auto-negotiation": true,
        "advertised-fec-modes": [ ],
        "auto-negotiation": false,
        "master-slave-cfg": "preferred slave",
        "master-slave-status": "unknown",
        "port": "Twisted Pair",
        "phyad": 0,
        "transceiver": "external",
        "supports-wake-on": "pumbg",
        "wake-on": "d",
        "link-detected": false
    } ]

You can use a json library to do all the parsing for you.

> +def get_speed_duplex(content):
> +    speed = []
> +    duplex = []
> +    """Check the link modes"""
> +    for data in content:
> +        parts = data.split('/')
> +        speed_value = re.match(r'\d+', parts[0])
> +        if speed_value:
> +            speed.append(speed_value.group())
> +        else:
> +            raise KsftSkipEx(f"No speed value found for interface {ifname}")
> +        duplex.append(parts[1].lower())
> +    return speed, duplex
> +
> +def verify_link_up(ifname: str) -> None:
> +    """Verify whether the link is up"""
> +    with open(f"/sys/class/net/{ifname}/operstate", "r") as fp:
> +        link_state = fp.read().strip()
> +
> +    if link_state == "down":
> +        raise KsftSkipEx(f"Link state of interface {ifname} is DOWN")
> +
> +def set_autonegotiation_state(ifname: str, state: str) -> None:
> +    content = get_ethtool_content(ifname, "Supported link modes:")
> +    speeds, duplex_modes = get_speed_duplex(content)
> +    speed = speeds[0]
> +    duplex = duplex_modes[0]
> +    if not speed or not duplex:
> +        KsftSkipEx("No speed or duplex modes found")
> +    """Set the autonegotiation state for the interface"""
> +    process = ethtool(f"-s {ifname} speed {speed} duplex {duplex} autoneg {state}")
> +    if process.ret != 0:
> +        raise KsftFailEx(f"Not able to set autoneg parameter for {ifname}")
> +    ksft_pr(f"Autoneg set as {state} for {ifname}")
> +
> +def verify_autonegotiation(ifname: str, expected_state: str) -> None:
> +    verify_link_up(ifname)
> +    """Verifying the autonegotiation state"""
> +    output = get_ethtool_content(ifname, "Auto-negotiation:")
> +    actual_state = output[0]
> +
> +    ksft_eq(actual_state, expected_state)
> +
> +def test_link_modes(cfg) -> None:
> +    global common_link_modes
> +    link_modes = get_ethtool_content(cfg.ifname, "Supported link modes:")
> +    partner_link_modes = get_ethtool_content(cfg.ifname, "Link partner advertised link modes:")
> +
> +    if link_modes and partner_link_modes:
> +        for idx1 in range(len(link_modes)):
> +            for idx2 in range(len(partner_link_modes)):
> +                if link_modes[idx1] == partner_link_modes[idx2]:
> +                    common_link_modes.append(link_modes[idx1])
> +                    break
> +    else:
> +        raise KsftFailEx("No link modes available")
> +
> +def test_autonegotiation(cfg) -> None:
> +    autoneg = get_ethtool_content(cfg.ifname, "Supports auto-negotiation:")
> +    if autoneg[0] == "Yes":
> +        for state in ["off", "on"]:
> +            set_autonegotiation_state(cfg.ifname, state)
> +            time.sleep(sleep_time)

One thing you could do here is look at "advertised-link-modes". You
would expect it to list a single mode, matching the speed/duplex
you requested.

	Andrew

  reply	other threads:[~2024-09-17 15:35 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-17  2:34 [PATCH net-next v2 0/3] nic_basic_tests: Add selftest for doing basic tests of NIC driver Mohan Prasad J
2024-09-17  2:34 ` [PATCH net-next v2 1/3] selftests: nic_basic_tests: Add selftest file for basic tests of NIC Mohan Prasad J
2024-09-17 15:35   ` Andrew Lunn [this message]
2024-09-18 10:30     ` Mohan.Prasad
2024-09-18 12:05       ` Andrew Lunn
2024-09-19 10:44         ` Mohan.Prasad
2024-09-19 14:51           ` Andrew Lunn
2024-09-17 15:48   ` Andrew Lunn
2024-09-18 10:32     ` Mohan.Prasad
2024-09-18 12:11       ` Andrew Lunn
2024-09-17 15:56   ` Andrew Lunn
2024-09-18 10:35     ` Mohan.Prasad
2024-09-17  2:34 ` [PATCH net-next v2 2/3] selftests: nic_basic_tests: Add selftest case for speed and duplex state checks Mohan Prasad J
2024-09-18 12:38   ` Willem de Bruijn
2024-09-20  4:56     ` Mohan.Prasad
2024-09-17  2:34 ` [PATCH net-next v2 3/3] selftests: nic_basic_tests: Add selftest case for throughput check Mohan Prasad J

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5c8779db-31c4-4b93-986a-bd489720fa4b@lunn.ch \
    --to=andrew@lunn.ch \
    --cc=UNGLinuxDriver@microchip.com \
    --cc=brett.creeley@amd.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=mohan.prasad@microchip.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=rosenp@gmail.com \
    --cc=shuah@kernel.org \
    --cc=willemb@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox