Path: blob/master/tools/testing/selftests/drivers/net/hw/nic_timestamp.py
50904 views
#!/usr/bin/env python31# SPDX-License-Identifier: GPL-2.02# pylint: disable=locally-disabled, invalid-name, attribute-defined-outside-init, too-few-public-methods34"""5Tests related to configuration of HW timestamping6"""78import errno9import ctypes10import fcntl11import socket12from lib.py import ksft_run, ksft_exit, ksft_ge, ksft_eq, KsftSkipEx13from lib.py import NetDrvEnv, EthtoolFamily, NlError141516SIOCSHWTSTAMP = 0x89b017SIOCGHWTSTAMP = 0x89b118class hwtstamp_config(ctypes.Structure):19""" Python copy of struct hwtstamp_config """20_fields_ = [21("flags", ctypes.c_int),22("tx_type", ctypes.c_int),23("rx_filter", ctypes.c_int),24]252627class ifreq(ctypes.Structure):28""" Python copy of struct ifreq """29_fields_ = [30("ifr_name", ctypes.c_char * 16),31("ifr_data", ctypes.POINTER(hwtstamp_config)),32]333435def __get_hwtimestamp_support(cfg):36""" Retrieve supported configuration information """3738try:39tsinfo = cfg.ethnl.tsinfo_get({'header': {'dev-name': cfg.ifname}})40except NlError as e:41if e.error == errno.EOPNOTSUPP:42raise KsftSkipEx("timestamping configuration is not supported") from e43raise4445ctx = {}46tx = tsinfo.get('tx-types', {})47rx = tsinfo.get('rx-filters', {})4849bits = tx.get('bits', {})50ctx['tx'] = bits.get('bit', [])51bits = rx.get('bits', {})52ctx['rx'] = bits.get('bit', [])53return ctx545556def __get_hwtimestamp_config_ioctl(cfg):57""" Retrieve current TS configuration information (via ioctl) """5859config = hwtstamp_config()6061req = ifreq()62req.ifr_name = cfg.ifname.encode()63req.ifr_data = ctypes.pointer(config)6465try:66sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)67fcntl.ioctl(sock.fileno(), SIOCGHWTSTAMP, req)68sock.close()6970except OSError as e:71if e.errno == errno.EOPNOTSUPP:72raise KsftSkipEx("timestamping configuration is not supported via ioctl") from e73raise74return config757677def __get_hwtimestamp_config(cfg):78""" Retrieve current TS configuration information (via netLink) """7980try:81tscfg = cfg.ethnl.tsconfig_get({'header': {'dev-name': cfg.ifname}})82except NlError as e:83if e.error == errno.EOPNOTSUPP:84raise KsftSkipEx("timestamping configuration is not supported via netlink") from e85raise86return tscfg878889def __set_hwtimestamp_config_ioctl(cfg, ts):90""" Setup new TS configuration information (via ioctl) """91config = hwtstamp_config()92config.rx_filter = ts['rx-filters']['bits']['bit'][0]['index']93config.tx_type = ts['tx-types']['bits']['bit'][0]['index']94req = ifreq()95req.ifr_name = cfg.ifname.encode()96req.ifr_data = ctypes.pointer(config)97try:98sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)99fcntl.ioctl(sock.fileno(), SIOCSHWTSTAMP, req)100sock.close()101102except OSError as e:103if e.errno == errno.EOPNOTSUPP:104raise KsftSkipEx("timestamping configuration is not supported via ioctl") from e105raise106107108def __set_hwtimestamp_config(cfg, ts):109""" Setup new TS configuration information (via netlink) """110111ts['header'] = {'dev-name': cfg.ifname}112try:113res = cfg.ethnl.tsconfig_set(ts)114except NlError as e:115if e.error == errno.EOPNOTSUPP:116raise KsftSkipEx("timestamping configuration is not supported via netlink") from e117raise118return res119120121def __perform_hwtstamp_tx(cfg, is_ioctl):122"""123Test TX timestamp configuration via either netlink or ioctl.124The driver should apply provided config and report back proper state.125"""126127orig_tscfg = __get_hwtimestamp_config(cfg)128ts = __get_hwtimestamp_support(cfg)129tx = ts['tx']130for t in tx:131res = None132tscfg = orig_tscfg133tscfg['tx-types']['bits']['bit'] = [t]134if is_ioctl:135__set_hwtimestamp_config_ioctl(cfg, tscfg)136else:137res = __set_hwtimestamp_config(cfg, tscfg)138if res is None:139res = __get_hwtimestamp_config(cfg)140resioctl = __get_hwtimestamp_config_ioctl(cfg)141ksft_eq(res['tx-types']['bits']['bit'], [t])142ksft_eq(resioctl.tx_type, t['index'])143__set_hwtimestamp_config(cfg, orig_tscfg)144145def test_hwtstamp_tx_netlink(cfg):146"""147Test TX timestamp configuration setup via netlink.148The driver should apply provided config and report back proper state.149"""150__perform_hwtstamp_tx(cfg, False)151152153def test_hwtstamp_tx_ioctl(cfg):154"""155Test TX timestamp configuration setup via ioctl.156The driver should apply provided config and report back proper state.157"""158__perform_hwtstamp_tx(cfg, True)159160161def __perform_hwtstamp_rx(cfg, is_ioctl):162"""163Test RX timestamp configuration.164The filter configuration is taken from the list of supported filters.165The driver should apply the config without error and report back proper state.166Some extension of the timestamping scope is allowed for PTP filters.167"""168169orig_tscfg = __get_hwtimestamp_config(cfg)170ts = __get_hwtimestamp_support(cfg)171rx = ts['rx']172for r in rx:173res = None174tscfg = orig_tscfg175tscfg['rx-filters']['bits']['bit'] = [r]176if is_ioctl:177__set_hwtimestamp_config_ioctl(cfg, tscfg)178else:179res = __set_hwtimestamp_config(cfg, tscfg)180if res is None:181res = __get_hwtimestamp_config(cfg)182resioctl = __get_hwtimestamp_config_ioctl(cfg)183ksft_eq(resioctl.rx_filter, res['rx-filters']['bits']['bit'][0]['index'])184if r['index'] == 0 or r['index'] == 1:185ksft_eq(res['rx-filters']['bits']['bit'][0]['index'], r['index'])186else:187# the driver can fallback to some value which has higher coverage for timestamping188ksft_ge(res['rx-filters']['bits']['bit'][0]['index'], r['index'])189__set_hwtimestamp_config(cfg, orig_tscfg)190191192def test_hwtstamp_rx_netlink(cfg):193"""194Test RX timestamp configuration via netlink.195The filter configuration is taken from the list of supported filters.196The driver should apply the config without error and report back proper state.197Some extension of the timestamping scope is allowed for PTP filters.198"""199__perform_hwtstamp_rx(cfg, False)200201202def test_hwtstamp_rx_ioctl(cfg):203"""204Test RX timestamp configuration via ioctl.205The filter configuration is taken from the list of supported filters.206The driver should apply the config without error and report back proper state.207Some extension of the timestamping scope is allowed for PTP filters.208"""209__perform_hwtstamp_rx(cfg, True)210211212def main() -> None:213""" Ksft boiler plate main """214215with NetDrvEnv(__file__, nsim_test=False) as cfg:216cfg.ethnl = EthtoolFamily()217ksft_run([test_hwtstamp_tx_ioctl, test_hwtstamp_tx_netlink,218test_hwtstamp_rx_ioctl, test_hwtstamp_rx_netlink],219args=(cfg,))220ksft_exit()221222223if __name__ == "__main__":224main()225226227