summaryrefslogtreecommitdiffstats
path: root/pethtool.py
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2008-08-26 14:03:28 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2008-08-26 14:03:28 -0300
commit330c8c4fa727547528b1e33612a417b84fa27458 (patch)
tree071f6a43537e82990fe085cc2c43581025e9a191 /pethtool.py
parentf33ca0371bf6b07963b97f047f7b86775f1041de (diff)
downloadpython-ethtool-330c8c4fa727547528b1e33612a417b84fa27458.tar.gz
python-ethtool-330c8c4fa727547528b1e33612a417b84fa27458.tar.xz
python-ethtool-330c8c4fa727547528b1e33612a417b84fa27458.zip
pethtool: rename ethtool-cmd.py to pethtool.py
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'pethtool.py')
-rwxr-xr-xpethtool.py380
1 files changed, 380 insertions, 0 deletions
diff --git a/pethtool.py b/pethtool.py
new file mode 100755
index 0000000..49d667e
--- /dev/null
+++ b/pethtool.py
@@ -0,0 +1,380 @@
+#! /usr/bin/python
+# -*- python -*-
+# -*- coding: utf-8 -*-
+# Copyright (C) 2008 Red Hat Inc.
+#
+# This application is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; version 2.
+#
+# This application is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+
+import getopt, ethtool, sys
+
+def usage():
+ print '''Usage: ethtool [OPTIONS] [<interface>]
+ -h|--help Give this help list
+ -c|--show-coalesce Show coalesce options
+ -C|--coalesce Set coalesce options
+ [adaptive-rx on|off]
+ [adaptive-tx on|off]
+ [rx-usecs N]
+ [rx-frames N]
+ [rx-usecs-irq N]
+ [rx-frames-irq N]
+ [tx-usecs N]
+ [tx-frames N]
+ [tx-usecs-irq N]
+ [tx-frames-irq N]
+ [stats-block-usecs N]
+ [pkt-rate-low N]
+ [rx-usecs-low N]
+ [rx-frames-low N]
+ [tx-usecs-low N]
+ [tx-frames-low N]
+ [pkt-rate-high N]
+ [rx-usecs-high N]
+ [rx-frames-high N]
+ [tx-usecs-high N]
+ [tx-frames-high N]
+ [sample-interval N]
+ -i|--driver Show driver information
+ -k|--show-offload Get protocol offload information
+ -K|--offload Set protocol offload
+ [ tso on|off ]'''
+
+tab = ""
+
+def printtab(msg):
+ print tab + msg
+
+all_devices = []
+
+ethtool_coalesce_msgs = (
+ ( "stats-block-usecs",
+ "stats_block_coalesce_usecs" ),
+ ( "sample-interval",
+ "rate_sample_interval" ),
+ ( "pkt-rate-low",
+ "pkt_rate_low"),
+ ( "pkt-rate-high",
+ "pkt_rate_high"),
+ ( "\n" ),
+ ( "rx-usecs",
+ "rx_coalesce_usecs"),
+ ( "rx-frames",
+ "rx_max_coalesced_frames"),
+ ( "rx-usecs-irq",
+ "rx_coalesce_usecs_irq"),
+ ( "rx-frames-irq",
+ "rx_max_coalesced_frames_irq"),
+ ( "\n" ),
+ ( "tx-usecs",
+ "tx_coalesce_usecs"),
+ ( "tx-frames",
+ "tx_max_coalesced_frames"),
+ ( "tx-usecs-irq",
+ "tx_coalesce_usecs_irq"),
+ ( "tx-frames-irq",
+ "tx_max_coalesced_frames_irq"),
+ ( "\n" ),
+ ( "rx-usecs-low",
+ "rx_coalesce_usecs_low"),
+ ( "rx-frame-low",
+ "rx_max_coalesced_frames_low"),
+ ( "tx-usecs-low",
+ "tx_coalesce_usecs_low"),
+ ( "tx-frame-low",
+ "tx_max_coalesced_frames_low"),
+ ( "\n" ),
+ ( "rx-usecs-high",
+ "rx_coalesce_usecs_high"),
+ ( "rx-frame-high",
+ "rx_max_coalesced_frames_high"),
+ ( "tx-usecs-high",
+ "tx_coalesce_usecs_high"),
+ ( "tx-frame-high",
+ "tx_max_coalesced_frames_high"),
+)
+
+def get_coalesce_dict_entry(ethtool_name):
+ if ethtool_name == "adaptive-rx":
+ return "use_adaptive_rx_coalesce"
+
+ if ethtool_name == "adaptive-tx":
+ return "use_adaptive_tx_coalesce"
+
+ for name in ethtool_coalesce_msgs:
+ if name[0] == ethtool_name:
+ return name[1]
+
+ return None
+
+def show_coalesce(interface, args = None):
+ printtab("Coalesce parameters for %s:" % interface)
+ try:
+ coal = ethtool.get_coalesce(interface)
+ except IOError:
+ printtab(" NOT supported!")
+ return
+
+ printtab("Adaptive RX: %s TX: %s" % (coal["use_adaptive_rx_coalesce"] and "on" or "off",
+ coal["use_adaptive_tx_coalesce"] and "on" or "off"))
+
+ printed = [ "use_adaptive_rx_coalesce",
+ "use_adaptive_tx_coalesce" ]
+ for tunable in ethtool_coalesce_msgs:
+ if tunable[0] == '\n':
+ print
+ else:
+ printtab("%s: %s" % (tunable[0], coal[tunable[1]]))
+ printed.append(tunable[1])
+
+ coalkeys = coal.keys()
+ if len(coalkeys) != len(printed):
+ print
+ for tunable in coalkeys:
+ if tunable not in printed:
+ printtab("%s %s" % (tunable, coal[tunable]))
+
+def set_coalesce(interface, args):
+ try:
+ coal = ethtool.get_coalesce(interface)
+ except IOError:
+ printtab("Interrupt coalescing NOT supported on %s!" % interface)
+ return
+
+ changed = False
+ args = [a.lower() for a in args]
+ for arg, value in [ ( args[i], args[i + 1] ) for i in range(0, len(args), 2) ]:
+ real_arg = get_coalesce_dict_entry(arg)
+ if not real_arg:
+ continue
+ if value == "on":
+ value = 1
+ elif value == "off":
+ value = 0
+ else:
+ try:
+ value = int(value)
+ except:
+ continue
+ if coal[real_arg] != value:
+ coal[real_arg] = value
+ changed = True
+
+ if not changed:
+ return
+
+ ethtool.set_coalesce(interface, coal)
+
+def show_offload(interface, args = None):
+ try:
+ sg = ethtool.get_sg(interface) and "on" or "off"
+ except IOError:
+ sg = "not supported"
+
+ try:
+ tso = ethtool.get_tso(interface) and "on" or "off"
+ except IOError:
+ tso = "not supported"
+
+ try:
+ ufo = ethtool.get_ufo(interface) and "on" or "off"
+ except IOError:
+ ufo = "not supported"
+
+ try:
+ gso = ethtool.get_gso(interface) and "on" or "off"
+ except IOError:
+ gso = "not supported"
+
+ printtab("scatter-gather: %s" % sg)
+ printtab("tcp segmentation offload: %s" % tso)
+ printtab("udp fragmentation offload: %s" % ufo)
+ printtab("generic segmentation offload: %s" % gso)
+
+def set_offload(interface, args):
+ cmd, value = [a.lower() for a in args]
+
+ if cmd == "tso":
+ value = value == "on" and 1 or 0
+ try:
+ ethtool.set_tso(interface, value)
+ except:
+ pass
+
+ethtool_ringparam_msgs = (
+ ( "Pre-set maximums", ),
+ ( "RX:\t\t", "rx_max_pending" ),
+ ( "RX Mini:\t", "rx_mini_max_pending" ),
+ ( "RX Jumbo:\t", "rx_jumbo_max_pending" ),
+ ( "TX:\t\t", "tx_max_pending" ),
+ ( "Current hardware settings", ),
+ ( "RX:\t\t", "rx_pending" ),
+ ( "RX Mini:\t", "rx_mini_pending" ),
+ ( "RX Jumbo:\t", "rx_jumbo_pending" ),
+ ( "TX:\t\t", "tx_pending" ),
+)
+
+def show_ring(interface, args = None):
+ printtab("Ring parameters for %s:" % interface)
+ try:
+ ring = ethtool.get_ringparam(interface)
+ except IOError:
+ printtab(" NOT supported!")
+ return
+
+ printed = []
+ for tunable in ethtool_ringparam_msgs:
+ if len(tunable) == 1:
+ printtab("%s:" % tunable[0])
+ else:
+ printtab("%s %s" % (tunable[0], ring[tunable[1]]))
+ printed.append(tunable[1])
+
+ ringkeys = ring.keys()
+ if len(ringkeys) != len(printed):
+ print
+ for tunable in ringkeys:
+ if tunable not in printed:
+ printtab("%s %s" % (tunable, ring[tunable]))
+
+ethtool_ringparam_map = {
+ "rx": "rx_pending",
+ "rx-mini": "rx_mini_pending",
+ "rx-jumbo": "rx_jumbo_pending",
+ "tx": "tx_pending",
+}
+
+def set_ringparam(interface, args):
+ try:
+ ring = ethtool.get_ringparam(interface)
+ except IOError:
+ printtab("ring parameters NOT supported on %s!" % interface)
+ return
+
+ changed = False
+ args = [a.lower() for a in args]
+ for arg, value in [ ( args[i], args[i + 1] ) for i in range(0, len(args), 2) ]:
+ if not ethtool_ringparam_map.has_key(arg):
+ continue
+ try:
+ value = int(value)
+ except:
+ continue
+ real_arg = ethtool_ringparam_map[arg]
+ if ring[real_arg] != value:
+ ring[real_arg] = value
+ changed = True
+
+ if not changed:
+ return
+
+ ethtool.set_ringparam(interface, ring)
+
+def show_driver(interface, args = None):
+ try:
+ driver = ethtool.get_module(interface)
+ except IOError:
+ driver = "not implemented"
+
+ try:
+ bus = ethtool.get_businfo(interface)
+ except IOError:
+ bus = "not available"
+
+ printtab("driver: %s" % driver)
+ printtab("bus-info: %s" % bus)
+
+def run_cmd(cmd, interface, args):
+ global tab, all_devices
+
+ active_devices = ethtool.get_active_devices()
+ if not interface:
+ tab = " "
+ for interface in all_devices:
+ inactive = " (not active)"
+ if interface in active_devices:
+ inactive = ""
+ print "%s%s:" % (interface, inactive)
+ cmd(interface, args)
+ else:
+ cmd(interface, args)
+
+def run_cmd_noargs(cmd, args):
+ if args:
+ run_cmd(cmd, args[0], None)
+ else:
+ global all_devices
+ all_devices = ethtool.get_devices()
+ run_cmd(cmd, None, None)
+
+def main():
+ global all_devices
+
+ try:
+ opts, args = getopt.getopt(sys.argv[1:],
+ "hcCgGikK",
+ ("help",
+ "show-coalesce",
+ "coalesce",
+ "show-ring",
+ "set-ring",
+ "driver",
+ "show-offload",
+ "offload"))
+ except getopt.GetoptError, err:
+ usage()
+ print str(err)
+ sys.exit(2)
+
+ if not opts:
+ usage()
+ sys.exit(0)
+
+ for o, a in opts:
+ if o in ("-h", "--help"):
+ usage()
+ return
+ elif o in ("-c", "--show-coalesce"):
+ run_cmd_noargs(show_coalesce, args)
+ break
+ elif o in ("-i", "--driver"):
+ run_cmd_noargs(show_driver, args)
+ break
+ elif o in ("-k", "--show-offload"):
+ run_cmd_noargs(show_offload, args)
+ break
+ elif o in ("-g", "--show-ring"):
+ run_cmd_noargs(show_ring, args)
+ break
+ elif o in ("-K", "--offload",
+ "-C", "--coalesce",
+ "-G", "--set-ring"):
+ all_devices = ethtool.get_devices()
+ if len(args) < 2:
+ usage()
+ sys.exit(1)
+
+ if args[0] not in all_devices:
+ interface = None
+ else:
+ interface = args[0]
+ args = args[1:]
+
+ if o in ("-K", "--offload"):
+ cmd = set_offload
+ elif o in ("-C", "--coalesce"):
+ cmd = set_coalesce
+ elif o in ("-G", "--set-ring"):
+ cmd = set_ringparam
+
+ run_cmd(cmd, interface, args)
+ break
+
+if __name__ == '__main__':
+ main()