1c6dab2a8SThomas Monjalon#! /usr/bin/env python 2c6dab2a8SThomas Monjalon# 3c6dab2a8SThomas Monjalon# BSD LICENSE 4c6dab2a8SThomas Monjalon# 5c6dab2a8SThomas Monjalon# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. 6c6dab2a8SThomas Monjalon# All rights reserved. 7c6dab2a8SThomas Monjalon# 8c6dab2a8SThomas Monjalon# Redistribution and use in source and binary forms, with or without 9c6dab2a8SThomas Monjalon# modification, are permitted provided that the following conditions 10c6dab2a8SThomas Monjalon# are met: 11c6dab2a8SThomas Monjalon# 12c6dab2a8SThomas Monjalon# * Redistributions of source code must retain the above copyright 13c6dab2a8SThomas Monjalon# notice, this list of conditions and the following disclaimer. 14c6dab2a8SThomas Monjalon# * Redistributions in binary form must reproduce the above copyright 15c6dab2a8SThomas Monjalon# notice, this list of conditions and the following disclaimer in 16c6dab2a8SThomas Monjalon# the documentation and/or other materials provided with the 17c6dab2a8SThomas Monjalon# distribution. 18c6dab2a8SThomas Monjalon# * Neither the name of Intel Corporation nor the names of its 19c6dab2a8SThomas Monjalon# contributors may be used to endorse or promote products derived 20c6dab2a8SThomas Monjalon# from this software without specific prior written permission. 21c6dab2a8SThomas Monjalon# 22c6dab2a8SThomas Monjalon# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23c6dab2a8SThomas Monjalon# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24c6dab2a8SThomas Monjalon# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25c6dab2a8SThomas Monjalon# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26c6dab2a8SThomas Monjalon# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27c6dab2a8SThomas Monjalon# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28c6dab2a8SThomas Monjalon# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29c6dab2a8SThomas Monjalon# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30c6dab2a8SThomas Monjalon# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31c6dab2a8SThomas Monjalon# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32c6dab2a8SThomas Monjalon# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33c6dab2a8SThomas Monjalon# 34c6dab2a8SThomas Monjalon 35c6dab2a8SThomas Monjalonimport sys 36c6dab2a8SThomas Monjalonimport os 37c6dab2a8SThomas Monjalonimport getopt 38c6dab2a8SThomas Monjalonimport subprocess 39c6dab2a8SThomas Monjalonfrom os.path import exists, abspath, dirname, basename 40c6dab2a8SThomas Monjalon 418ad08a28SGuduri Prathyusha# The PCI base class for all devices 428ad08a28SGuduri Prathyushanetwork_class = {'Class': '02', 'Vendor': None, 'Device': None, 438ad08a28SGuduri Prathyusha 'SVendor': None, 'SDevice': None} 448ad08a28SGuduri Prathyushaencryption_class = {'Class': '10', 'Vendor': None, 'Device': None, 458ad08a28SGuduri Prathyusha 'SVendor': None, 'SDevice': None} 468ad08a28SGuduri Prathyushaintel_processor_class = {'Class': '0b', 'Vendor': '8086', 'Device': None, 478ad08a28SGuduri Prathyusha 'SVendor': None, 'SDevice': None} 4832a02dbfSGuduri Prathyushacavium_sso = {'Class': '08', 'Vendor': '177d', 'Device': 'a04b,a04d', 4932a02dbfSGuduri Prathyusha 'SVendor': None, 'SDevice': None} 5080a1858dSGuduri Prathyushacavium_fpa = {'Class': '08', 'Vendor': '177d', 'Device': 'a053', 5180a1858dSGuduri Prathyusha 'SVendor': None, 'SDevice': None} 52156c42eaSJerin Jacobcavium_pkx = {'Class': '08', 'Vendor': '177d', 'Device': 'a0dd,a049', 53156c42eaSJerin Jacob 'SVendor': None, 'SDevice': None} 548ad08a28SGuduri Prathyusha 55156c42eaSJerin Jacobnetwork_devices = [network_class, cavium_pkx] 568ad08a28SGuduri Prathyushacrypto_devices = [encryption_class, intel_processor_class] 5732a02dbfSGuduri Prathyushaeventdev_devices = [cavium_sso] 5880a1858dSGuduri Prathyushamempool_devices = [cavium_fpa] 59c6dab2a8SThomas Monjalon 60c6dab2a8SThomas Monjalon# global dict ethernet devices present. Dictionary indexed by PCI address. 61c6dab2a8SThomas Monjalon# Each device within this is itself a dictionary of device properties 62c6dab2a8SThomas Monjalondevices = {} 63c6dab2a8SThomas Monjalon# list of supported DPDK drivers 64c6dab2a8SThomas Monjalondpdk_drivers = ["igb_uio", "vfio-pci", "uio_pci_generic"] 65c6dab2a8SThomas Monjalon 66c6dab2a8SThomas Monjalon# command-line arg flags 67c6dab2a8SThomas Monjalonb_flag = None 68c6dab2a8SThomas Monjalonstatus_flag = False 69c6dab2a8SThomas Monjalonforce_flag = False 70c6dab2a8SThomas Monjalonargs = [] 71c6dab2a8SThomas Monjalon 72c6dab2a8SThomas Monjalon 73c6dab2a8SThomas Monjalondef usage(): 74c6dab2a8SThomas Monjalon '''Print usage information for the program''' 75c6dab2a8SThomas Monjalon argv0 = basename(sys.argv[0]) 76c6dab2a8SThomas Monjalon print(""" 77c6dab2a8SThomas MonjalonUsage: 78c6dab2a8SThomas Monjalon------ 79c6dab2a8SThomas Monjalon 80c6dab2a8SThomas Monjalon %(argv0)s [options] DEVICE1 DEVICE2 .... 81c6dab2a8SThomas Monjalon 82c6dab2a8SThomas Monjalonwhere DEVICE1, DEVICE2 etc, are specified via PCI "domain:bus:slot.func" syntax 83c6dab2a8SThomas Monjalonor "bus:slot.func" syntax. For devices bound to Linux kernel drivers, they may 84c6dab2a8SThomas Monjalonalso be referred to by Linux interface name e.g. eth0, eth1, em0, em1, etc. 85c6dab2a8SThomas Monjalon 86c6dab2a8SThomas MonjalonOptions: 87c6dab2a8SThomas Monjalon --help, --usage: 88c6dab2a8SThomas Monjalon Display usage information and quit 89c6dab2a8SThomas Monjalon 90c6dab2a8SThomas Monjalon -s, --status: 91b153c00bSFerruh Yigit Print the current status of all known network, crypto, event 92b153c00bSFerruh Yigit and mempool devices. 93c6dab2a8SThomas Monjalon For each device, it displays the PCI domain, bus, slot and function, 94c6dab2a8SThomas Monjalon along with a text description of the device. Depending upon whether the 95c6dab2a8SThomas Monjalon device is being used by a kernel driver, the igb_uio driver, or no 96c6dab2a8SThomas Monjalon driver, other relevant information will be displayed: 97c6dab2a8SThomas Monjalon * the Linux interface name e.g. if=eth0 98c6dab2a8SThomas Monjalon * the driver being used e.g. drv=igb_uio 99c6dab2a8SThomas Monjalon * any suitable drivers not currently using that device 100c6dab2a8SThomas Monjalon e.g. unused=igb_uio 101c6dab2a8SThomas Monjalon NOTE: if this flag is passed along with a bind/unbind option, the 102c6dab2a8SThomas Monjalon status display will always occur after the other operations have taken 103c6dab2a8SThomas Monjalon place. 104c6dab2a8SThomas Monjalon 105b153c00bSFerruh Yigit --status-dev: 106b153c00bSFerruh Yigit Print the status of given device group. Supported device groups are: 107b153c00bSFerruh Yigit "net", "crypto", "event" and "mempool" 108b153c00bSFerruh Yigit 109c6dab2a8SThomas Monjalon -b driver, --bind=driver: 110c6dab2a8SThomas Monjalon Select the driver to use or \"none\" to unbind the device 111c6dab2a8SThomas Monjalon 112c6dab2a8SThomas Monjalon -u, --unbind: 113c6dab2a8SThomas Monjalon Unbind a device (Equivalent to \"-b none\") 114c6dab2a8SThomas Monjalon 115c6dab2a8SThomas Monjalon --force: 116c6dab2a8SThomas Monjalon By default, network devices which are used by Linux - as indicated by 117c6dab2a8SThomas Monjalon having routes in the routing table - cannot be modified. Using the 118c6dab2a8SThomas Monjalon --force flag overrides this behavior, allowing active links to be 119c6dab2a8SThomas Monjalon forcibly unbound. 120c6dab2a8SThomas Monjalon WARNING: This can lead to loss of network connection and should be used 121c6dab2a8SThomas Monjalon with caution. 122c6dab2a8SThomas Monjalon 123c6dab2a8SThomas MonjalonExamples: 124c6dab2a8SThomas Monjalon--------- 125c6dab2a8SThomas Monjalon 126c6dab2a8SThomas MonjalonTo display current device status: 127c6dab2a8SThomas Monjalon %(argv0)s --status 128c6dab2a8SThomas Monjalon 129b153c00bSFerruh YigitTo display current network device status: 130b153c00bSFerruh Yigit %(argv0)s --status-dev net 131b153c00bSFerruh Yigit 132c6dab2a8SThomas MonjalonTo bind eth1 from the current driver and move to use igb_uio 133c6dab2a8SThomas Monjalon %(argv0)s --bind=igb_uio eth1 134c6dab2a8SThomas Monjalon 135c6dab2a8SThomas MonjalonTo unbind 0000:01:00.0 from using any driver 136c6dab2a8SThomas Monjalon %(argv0)s -u 0000:01:00.0 137c6dab2a8SThomas Monjalon 138c6dab2a8SThomas MonjalonTo bind 0000:02:00.0 and 0000:02:00.1 to the ixgbe kernel driver 139c6dab2a8SThomas Monjalon %(argv0)s -b ixgbe 02:00.0 02:00.1 140c6dab2a8SThomas Monjalon 141c6dab2a8SThomas Monjalon """ % locals()) # replace items from local variables 142c6dab2a8SThomas Monjalon 143c6dab2a8SThomas Monjalon 144c6dab2a8SThomas Monjalon# This is roughly compatible with check_output function in subprocess module 145c6dab2a8SThomas Monjalon# which is only available in python 2.7. 146c6dab2a8SThomas Monjalondef check_output(args, stderr=None): 147c6dab2a8SThomas Monjalon '''Run a command and capture its output''' 148c6dab2a8SThomas Monjalon return subprocess.Popen(args, stdout=subprocess.PIPE, 149c6dab2a8SThomas Monjalon stderr=stderr).communicate()[0] 150c6dab2a8SThomas Monjalon 151c6dab2a8SThomas Monjalon 152c6dab2a8SThomas Monjalondef find_module(mod): 153c6dab2a8SThomas Monjalon '''find the .ko file for kernel module named mod. 154c6dab2a8SThomas Monjalon Searches the $RTE_SDK/$RTE_TARGET directory, the kernel 155c6dab2a8SThomas Monjalon modules directory and finally under the parent directory of 156c6dab2a8SThomas Monjalon the script ''' 157c6dab2a8SThomas Monjalon # check $RTE_SDK/$RTE_TARGET directory 158c6dab2a8SThomas Monjalon if 'RTE_SDK' in os.environ and 'RTE_TARGET' in os.environ: 159c6dab2a8SThomas Monjalon path = "%s/%s/kmod/%s.ko" % (os.environ['RTE_SDK'], 160c6dab2a8SThomas Monjalon os.environ['RTE_TARGET'], mod) 161c6dab2a8SThomas Monjalon if exists(path): 162c6dab2a8SThomas Monjalon return path 163c6dab2a8SThomas Monjalon 164c6dab2a8SThomas Monjalon # check using depmod 165c6dab2a8SThomas Monjalon try: 166df86b009SMark Asselstine with open(os.devnull, "w") as fnull: 167df86b009SMark Asselstine path = check_output(["modinfo", "-n", mod], stderr=fnull).strip() 168df86b009SMark Asselstine 169df86b009SMark Asselstine if path and exists(path): 170c6dab2a8SThomas Monjalon return path 171c6dab2a8SThomas Monjalon except: # if modinfo can't find module, it fails, so continue 172c6dab2a8SThomas Monjalon pass 173c6dab2a8SThomas Monjalon 174c6dab2a8SThomas Monjalon # check for a copy based off current path 175c6dab2a8SThomas Monjalon tools_dir = dirname(abspath(sys.argv[0])) 176c6dab2a8SThomas Monjalon if tools_dir.endswith("tools"): 177c6dab2a8SThomas Monjalon base_dir = dirname(tools_dir) 178c6dab2a8SThomas Monjalon find_out = check_output(["find", base_dir, "-name", mod + ".ko"]) 179c6dab2a8SThomas Monjalon if len(find_out) > 0: # something matched 180c6dab2a8SThomas Monjalon path = find_out.splitlines()[0] 181c6dab2a8SThomas Monjalon if exists(path): 182c6dab2a8SThomas Monjalon return path 183c6dab2a8SThomas Monjalon 184c6dab2a8SThomas Monjalon 185c6dab2a8SThomas Monjalondef check_modules(): 186c6dab2a8SThomas Monjalon '''Checks that igb_uio is loaded''' 187c6dab2a8SThomas Monjalon global dpdk_drivers 188c6dab2a8SThomas Monjalon 189c6dab2a8SThomas Monjalon # list of supported modules 190c6dab2a8SThomas Monjalon mods = [{"Name": driver, "Found": False} for driver in dpdk_drivers] 191c6dab2a8SThomas Monjalon 192c6dab2a8SThomas Monjalon # first check if module is loaded 193c6dab2a8SThomas Monjalon try: 194c6dab2a8SThomas Monjalon # Get list of sysfs modules (both built-in and dynamically loaded) 195c6dab2a8SThomas Monjalon sysfs_path = '/sys/module/' 196c6dab2a8SThomas Monjalon 197c6dab2a8SThomas Monjalon # Get the list of directories in sysfs_path 198c6dab2a8SThomas Monjalon sysfs_mods = [os.path.join(sysfs_path, o) for o 199c6dab2a8SThomas Monjalon in os.listdir(sysfs_path) 200c6dab2a8SThomas Monjalon if os.path.isdir(os.path.join(sysfs_path, o))] 201c6dab2a8SThomas Monjalon 202c6dab2a8SThomas Monjalon # Extract the last element of '/sys/module/abc' in the array 203c6dab2a8SThomas Monjalon sysfs_mods = [a.split('/')[-1] for a in sysfs_mods] 204c6dab2a8SThomas Monjalon 205c6dab2a8SThomas Monjalon # special case for vfio_pci (module is named vfio-pci, 206c6dab2a8SThomas Monjalon # but its .ko is named vfio_pci) 207*8fab26f8SOmri Mor sysfs_mods = [a if a != 'vfio_pci' else 'vfio-pci' for a in sysfs_mods] 208c6dab2a8SThomas Monjalon 209c6dab2a8SThomas Monjalon for mod in mods: 210c6dab2a8SThomas Monjalon if mod["Name"] in sysfs_mods: 211c6dab2a8SThomas Monjalon mod["Found"] = True 212c6dab2a8SThomas Monjalon except: 213c6dab2a8SThomas Monjalon pass 214c6dab2a8SThomas Monjalon 215c6dab2a8SThomas Monjalon # check if we have at least one loaded module 216c6dab2a8SThomas Monjalon if True not in [mod["Found"] for mod in mods] and b_flag is not None: 217c6dab2a8SThomas Monjalon if b_flag in dpdk_drivers: 218c6dab2a8SThomas Monjalon print("Error - no supported modules(DPDK driver) are loaded") 219c6dab2a8SThomas Monjalon sys.exit(1) 220c6dab2a8SThomas Monjalon else: 221c6dab2a8SThomas Monjalon print("Warning - no supported modules(DPDK driver) are loaded") 222c6dab2a8SThomas Monjalon 223c6dab2a8SThomas Monjalon # change DPDK driver list to only contain drivers that are loaded 224c6dab2a8SThomas Monjalon dpdk_drivers = [mod["Name"] for mod in mods if mod["Found"]] 225c6dab2a8SThomas Monjalon 226c6dab2a8SThomas Monjalon 227c6dab2a8SThomas Monjalondef has_driver(dev_id): 228c6dab2a8SThomas Monjalon '''return true if a device is assigned to a driver. False otherwise''' 229c6dab2a8SThomas Monjalon return "Driver_str" in devices[dev_id] 230c6dab2a8SThomas Monjalon 231c6dab2a8SThomas Monjalon 232c3ce205dSGuduri Prathyushadef get_pci_device_details(dev_id, probe_lspci): 233c6dab2a8SThomas Monjalon '''This function gets additional details for a PCI device''' 234c6dab2a8SThomas Monjalon device = {} 235c6dab2a8SThomas Monjalon 236c3ce205dSGuduri Prathyusha if probe_lspci: 237c6dab2a8SThomas Monjalon extra_info = check_output(["lspci", "-vmmks", dev_id]).splitlines() 238c6dab2a8SThomas Monjalon 239c6dab2a8SThomas Monjalon # parse lspci details 240c6dab2a8SThomas Monjalon for line in extra_info: 241c6dab2a8SThomas Monjalon if len(line) == 0: 242c6dab2a8SThomas Monjalon continue 243c6dab2a8SThomas Monjalon name, value = line.decode().split("\t", 1) 244c6dab2a8SThomas Monjalon name = name.strip(":") + "_str" 245c6dab2a8SThomas Monjalon device[name] = value 246c6dab2a8SThomas Monjalon # check for a unix interface name 247c6dab2a8SThomas Monjalon device["Interface"] = "" 248c6dab2a8SThomas Monjalon for base, dirs, _ in os.walk("/sys/bus/pci/devices/%s/" % dev_id): 249c6dab2a8SThomas Monjalon if "net" in dirs: 250c6dab2a8SThomas Monjalon device["Interface"] = \ 251c6dab2a8SThomas Monjalon ",".join(os.listdir(os.path.join(base, "net"))) 252c6dab2a8SThomas Monjalon break 253c6dab2a8SThomas Monjalon # check if a port is used for ssh connection 254c6dab2a8SThomas Monjalon device["Ssh_if"] = False 255c6dab2a8SThomas Monjalon device["Active"] = "" 256c6dab2a8SThomas Monjalon 257c6dab2a8SThomas Monjalon return device 258c6dab2a8SThomas Monjalon 259ea9f00f7SGuduri Prathyushadef clear_data(): 260ea9f00f7SGuduri Prathyusha '''This function clears any old data''' 261ea9f00f7SGuduri Prathyusha devices = {} 262c6dab2a8SThomas Monjalon 263ea9f00f7SGuduri Prathyushadef get_device_details(devices_type): 264c6dab2a8SThomas Monjalon '''This function populates the "devices" dictionary. The keys used are 265c6dab2a8SThomas Monjalon the pci addresses (domain:bus:slot.func). The values are themselves 266c6dab2a8SThomas Monjalon dictionaries - one for each NIC.''' 267c6dab2a8SThomas Monjalon global devices 268c6dab2a8SThomas Monjalon global dpdk_drivers 269c6dab2a8SThomas Monjalon 270c6dab2a8SThomas Monjalon # first loop through and read details for all devices 271c3ce205dSGuduri Prathyusha # request machine readable format, with numeric IDs and String 272c6dab2a8SThomas Monjalon dev = {} 273c3ce205dSGuduri Prathyusha dev_lines = check_output(["lspci", "-Dvmmnnk"]).splitlines() 274c6dab2a8SThomas Monjalon for dev_line in dev_lines: 275c6dab2a8SThomas Monjalon if len(dev_line) == 0: 2768ad08a28SGuduri Prathyusha if device_type_match(dev, devices_type): 2778ad08a28SGuduri Prathyusha # Replace "Driver" with "Driver_str" to have consistency of 2788ad08a28SGuduri Prathyusha # of dictionary key names 279c3ce205dSGuduri Prathyusha if "Driver" in dev.keys(): 280c3ce205dSGuduri Prathyusha dev["Driver_str"] = dev.pop("Driver") 281c6dab2a8SThomas Monjalon # use dict to make copy of dev 282c6dab2a8SThomas Monjalon devices[dev["Slot"]] = dict(dev) 283c3ce205dSGuduri Prathyusha # Clear previous device's data 284c3ce205dSGuduri Prathyusha dev = {} 285c6dab2a8SThomas Monjalon else: 286c6dab2a8SThomas Monjalon name, value = dev_line.decode().split("\t", 1) 287c3ce205dSGuduri Prathyusha value_list = value.rsplit(' ', 1) 288c3ce205dSGuduri Prathyusha if len(value_list) > 1: 289c3ce205dSGuduri Prathyusha # String stored in <name>_str 290c3ce205dSGuduri Prathyusha dev[name.rstrip(":") + '_str'] = value_list[0] 291c3ce205dSGuduri Prathyusha # Numeric IDs 292c3ce205dSGuduri Prathyusha dev[name.rstrip(":")] = value_list[len(value_list) - 1] \ 293c3ce205dSGuduri Prathyusha .rstrip("]").lstrip("[") 294c6dab2a8SThomas Monjalon 2958ad08a28SGuduri Prathyusha if devices_type == network_devices: 296c6dab2a8SThomas Monjalon # check what is the interface if any for an ssh connection if 297c6dab2a8SThomas Monjalon # any to this host, so we can mark it later. 298c6dab2a8SThomas Monjalon ssh_if = [] 299c6dab2a8SThomas Monjalon route = check_output(["ip", "-o", "route"]) 300c6dab2a8SThomas Monjalon # filter out all lines for 169.254 routes 301c6dab2a8SThomas Monjalon route = "\n".join(filter(lambda ln: not ln.startswith("169.254"), 302c6dab2a8SThomas Monjalon route.decode().splitlines())) 303c6dab2a8SThomas Monjalon rt_info = route.split() 304c6dab2a8SThomas Monjalon for i in range(len(rt_info) - 1): 305c6dab2a8SThomas Monjalon if rt_info[i] == "dev": 306c6dab2a8SThomas Monjalon ssh_if.append(rt_info[i+1]) 307c6dab2a8SThomas Monjalon 308c6dab2a8SThomas Monjalon # based on the basic info, get extended text details 309c6dab2a8SThomas Monjalon for d in devices.keys(): 3108ad08a28SGuduri Prathyusha if not device_type_match(devices[d], devices_type): 311617d9052SYoni Gilad continue 312617d9052SYoni Gilad 313c6dab2a8SThomas Monjalon # get additional info and add it to existing data 314c6dab2a8SThomas Monjalon devices[d] = devices[d].copy() 315c3ce205dSGuduri Prathyusha # No need to probe lspci 316c3ce205dSGuduri Prathyusha devices[d].update(get_pci_device_details(d, False).items()) 317c6dab2a8SThomas Monjalon 3188ad08a28SGuduri Prathyusha if devices_type == network_devices: 319ea9f00f7SGuduri Prathyusha for _if in ssh_if: 320ea9f00f7SGuduri Prathyusha if _if in devices[d]["Interface"].split(","): 321ea9f00f7SGuduri Prathyusha devices[d]["Ssh_if"] = True 322ea9f00f7SGuduri Prathyusha devices[d]["Active"] = "*Active*" 323ea9f00f7SGuduri Prathyusha break 324ea9f00f7SGuduri Prathyusha 325c6dab2a8SThomas Monjalon # add igb_uio to list of supporting modules if needed 326c6dab2a8SThomas Monjalon if "Module_str" in devices[d]: 327c6dab2a8SThomas Monjalon for driver in dpdk_drivers: 328c6dab2a8SThomas Monjalon if driver not in devices[d]["Module_str"]: 329c6dab2a8SThomas Monjalon devices[d]["Module_str"] = \ 330c6dab2a8SThomas Monjalon devices[d]["Module_str"] + ",%s" % driver 331c6dab2a8SThomas Monjalon else: 332c6dab2a8SThomas Monjalon devices[d]["Module_str"] = ",".join(dpdk_drivers) 333c6dab2a8SThomas Monjalon 334c6dab2a8SThomas Monjalon # make sure the driver and module strings do not have any duplicates 335c6dab2a8SThomas Monjalon if has_driver(d): 336c6dab2a8SThomas Monjalon modules = devices[d]["Module_str"].split(",") 337c6dab2a8SThomas Monjalon if devices[d]["Driver_str"] in modules: 338c6dab2a8SThomas Monjalon modules.remove(devices[d]["Driver_str"]) 339c6dab2a8SThomas Monjalon devices[d]["Module_str"] = ",".join(modules) 340c6dab2a8SThomas Monjalon 341c6dab2a8SThomas Monjalon 3428ad08a28SGuduri Prathyushadef device_type_match(dev, devices_type): 3438ad08a28SGuduri Prathyusha for i in range(len(devices_type)): 3448ad08a28SGuduri Prathyusha param_count = len( 3458ad08a28SGuduri Prathyusha [x for x in devices_type[i].values() if x is not None]) 3468ad08a28SGuduri Prathyusha match_count = 0 3478ad08a28SGuduri Prathyusha if dev["Class"][0:2] == devices_type[i]["Class"]: 3488ad08a28SGuduri Prathyusha match_count = match_count + 1 3498ad08a28SGuduri Prathyusha for key in devices_type[i].keys(): 3508ad08a28SGuduri Prathyusha if key != 'Class' and devices_type[i][key]: 3518ad08a28SGuduri Prathyusha value_list = devices_type[i][key].split(',') 3528ad08a28SGuduri Prathyusha for value in value_list: 3538ad08a28SGuduri Prathyusha if value.strip(' ') == dev[key]: 3548ad08a28SGuduri Prathyusha match_count = match_count + 1 3558ad08a28SGuduri Prathyusha # count must be the number of non None parameters to match 3568ad08a28SGuduri Prathyusha if match_count == param_count: 3578ad08a28SGuduri Prathyusha return True 3588ad08a28SGuduri Prathyusha return False 3598ad08a28SGuduri Prathyusha 360c6dab2a8SThomas Monjalondef dev_id_from_dev_name(dev_name): 361c6dab2a8SThomas Monjalon '''Take a device "name" - a string passed in by user to identify a NIC 362c6dab2a8SThomas Monjalon device, and determine the device id - i.e. the domain:bus:slot.func - for 363c6dab2a8SThomas Monjalon it, which can then be used to index into the devices array''' 364c6dab2a8SThomas Monjalon 365c6dab2a8SThomas Monjalon # check if it's already a suitable index 366c6dab2a8SThomas Monjalon if dev_name in devices: 367c6dab2a8SThomas Monjalon return dev_name 368c6dab2a8SThomas Monjalon # check if it's an index just missing the domain part 369c6dab2a8SThomas Monjalon elif "0000:" + dev_name in devices: 370c6dab2a8SThomas Monjalon return "0000:" + dev_name 371c6dab2a8SThomas Monjalon else: 372c6dab2a8SThomas Monjalon # check if it's an interface name, e.g. eth1 373c6dab2a8SThomas Monjalon for d in devices.keys(): 374c6dab2a8SThomas Monjalon if dev_name in devices[d]["Interface"].split(","): 375c6dab2a8SThomas Monjalon return devices[d]["Slot"] 376c6dab2a8SThomas Monjalon # if nothing else matches - error 377c6dab2a8SThomas Monjalon print("Unknown device: %s. " 378c6dab2a8SThomas Monjalon "Please specify device in \"bus:slot.func\" format" % dev_name) 379c6dab2a8SThomas Monjalon sys.exit(1) 380c6dab2a8SThomas Monjalon 381c6dab2a8SThomas Monjalon 382c6dab2a8SThomas Monjalondef unbind_one(dev_id, force): 383c6dab2a8SThomas Monjalon '''Unbind the device identified by "dev_id" from its current driver''' 384c6dab2a8SThomas Monjalon dev = devices[dev_id] 385c6dab2a8SThomas Monjalon if not has_driver(dev_id): 386c6dab2a8SThomas Monjalon print("%s %s %s is not currently managed by any driver\n" % 387c6dab2a8SThomas Monjalon (dev["Slot"], dev["Device_str"], dev["Interface"])) 388c6dab2a8SThomas Monjalon return 389c6dab2a8SThomas Monjalon 390c6dab2a8SThomas Monjalon # prevent us disconnecting ourselves 391c6dab2a8SThomas Monjalon if dev["Ssh_if"] and not force: 392c6dab2a8SThomas Monjalon print("Routing table indicates that interface %s is active. " 393c6dab2a8SThomas Monjalon "Skipping unbind" % (dev_id)) 394c6dab2a8SThomas Monjalon return 395c6dab2a8SThomas Monjalon 396c6dab2a8SThomas Monjalon # write to /sys to unbind 397c6dab2a8SThomas Monjalon filename = "/sys/bus/pci/drivers/%s/unbind" % dev["Driver_str"] 398c6dab2a8SThomas Monjalon try: 399c6dab2a8SThomas Monjalon f = open(filename, "a") 400c6dab2a8SThomas Monjalon except: 401c6dab2a8SThomas Monjalon print("Error: unbind failed for %s - Cannot open %s" 402c6dab2a8SThomas Monjalon % (dev_id, filename)) 403c6dab2a8SThomas Monjalon sys.exit(1) 404c6dab2a8SThomas Monjalon f.write(dev_id) 405c6dab2a8SThomas Monjalon f.close() 406c6dab2a8SThomas Monjalon 407c6dab2a8SThomas Monjalon 408c6dab2a8SThomas Monjalondef bind_one(dev_id, driver, force): 409c6dab2a8SThomas Monjalon '''Bind the device given by "dev_id" to the driver "driver". If the device 410c6dab2a8SThomas Monjalon is already bound to a different driver, it will be unbound first''' 411c6dab2a8SThomas Monjalon dev = devices[dev_id] 412c6dab2a8SThomas Monjalon saved_driver = None # used to rollback any unbind in case of failure 413c6dab2a8SThomas Monjalon 414c6dab2a8SThomas Monjalon # prevent disconnection of our ssh session 415c6dab2a8SThomas Monjalon if dev["Ssh_if"] and not force: 416c6dab2a8SThomas Monjalon print("Routing table indicates that interface %s is active. " 417c6dab2a8SThomas Monjalon "Not modifying" % (dev_id)) 418c6dab2a8SThomas Monjalon return 419c6dab2a8SThomas Monjalon 420c6dab2a8SThomas Monjalon # unbind any existing drivers we don't want 421c6dab2a8SThomas Monjalon if has_driver(dev_id): 422c6dab2a8SThomas Monjalon if dev["Driver_str"] == driver: 423c6dab2a8SThomas Monjalon print("%s already bound to driver %s, skipping\n" 424c6dab2a8SThomas Monjalon % (dev_id, driver)) 425c6dab2a8SThomas Monjalon return 426c6dab2a8SThomas Monjalon else: 427c6dab2a8SThomas Monjalon saved_driver = dev["Driver_str"] 428c6dab2a8SThomas Monjalon unbind_one(dev_id, force) 429c6dab2a8SThomas Monjalon dev["Driver_str"] = "" # clear driver string 430c6dab2a8SThomas Monjalon 4312fc35029SGuduri Prathyusha # For kernels >= 3.15 driver_override can be used to specify the driver 4322fc35029SGuduri Prathyusha # for a device rather than relying on the driver to provide a positive 4332fc35029SGuduri Prathyusha # match of the device. The existing process of looking up 4342fc35029SGuduri Prathyusha # the vendor and device ID, adding them to the driver new_id, 4352fc35029SGuduri Prathyusha # will erroneously bind other devices too which has the additional burden 4362fc35029SGuduri Prathyusha # of unbinding those devices 437c6dab2a8SThomas Monjalon if driver in dpdk_drivers: 4382fc35029SGuduri Prathyusha filename = "/sys/bus/pci/devices/%s/driver_override" % dev_id 4392fc35029SGuduri Prathyusha if os.path.exists(filename): 4402fc35029SGuduri Prathyusha try: 4412fc35029SGuduri Prathyusha f = open(filename, "w") 4422fc35029SGuduri Prathyusha except: 4432fc35029SGuduri Prathyusha print("Error: bind failed for %s - Cannot open %s" 4442fc35029SGuduri Prathyusha % (dev_id, filename)) 4452fc35029SGuduri Prathyusha return 4462fc35029SGuduri Prathyusha try: 4472fc35029SGuduri Prathyusha f.write("%s" % driver) 4482fc35029SGuduri Prathyusha f.close() 4492fc35029SGuduri Prathyusha except: 4502fc35029SGuduri Prathyusha print("Error: bind failed for %s - Cannot write driver %s to " 4512fc35029SGuduri Prathyusha "PCI ID " % (dev_id, driver)) 4522fc35029SGuduri Prathyusha return 4532fc35029SGuduri Prathyusha # For kernels < 3.15 use new_id to add PCI id's to the driver 4542fc35029SGuduri Prathyusha else: 455c6dab2a8SThomas Monjalon filename = "/sys/bus/pci/drivers/%s/new_id" % driver 456c6dab2a8SThomas Monjalon try: 457c6dab2a8SThomas Monjalon f = open(filename, "w") 458c6dab2a8SThomas Monjalon except: 459c6dab2a8SThomas Monjalon print("Error: bind failed for %s - Cannot open %s" 460c6dab2a8SThomas Monjalon % (dev_id, filename)) 461c6dab2a8SThomas Monjalon return 462c6dab2a8SThomas Monjalon try: 4638ad08a28SGuduri Prathyusha # Convert Device and Vendor Id to int to write to new_id 4648ad08a28SGuduri Prathyusha f.write("%04x %04x" % (int(dev["Vendor"],16), 4658ad08a28SGuduri Prathyusha int(dev["Device"], 16))) 466c6dab2a8SThomas Monjalon f.close() 467c6dab2a8SThomas Monjalon except: 468c6dab2a8SThomas Monjalon print("Error: bind failed for %s - Cannot write new PCI ID to " 469c6dab2a8SThomas Monjalon "driver %s" % (dev_id, driver)) 470c6dab2a8SThomas Monjalon return 471c6dab2a8SThomas Monjalon 472c6dab2a8SThomas Monjalon # do the bind by writing to /sys 473c6dab2a8SThomas Monjalon filename = "/sys/bus/pci/drivers/%s/bind" % driver 474c6dab2a8SThomas Monjalon try: 475c6dab2a8SThomas Monjalon f = open(filename, "a") 476c6dab2a8SThomas Monjalon except: 477c6dab2a8SThomas Monjalon print("Error: bind failed for %s - Cannot open %s" 478c6dab2a8SThomas Monjalon % (dev_id, filename)) 479c6dab2a8SThomas Monjalon if saved_driver is not None: # restore any previous driver 480c6dab2a8SThomas Monjalon bind_one(dev_id, saved_driver, force) 481c6dab2a8SThomas Monjalon return 482c6dab2a8SThomas Monjalon try: 483c6dab2a8SThomas Monjalon f.write(dev_id) 484c6dab2a8SThomas Monjalon f.close() 485c6dab2a8SThomas Monjalon except: 486c6dab2a8SThomas Monjalon # for some reason, closing dev_id after adding a new PCI ID to new_id 487c6dab2a8SThomas Monjalon # results in IOError. however, if the device was successfully bound, 488c6dab2a8SThomas Monjalon # we don't care for any errors and can safely ignore IOError 489c3ce205dSGuduri Prathyusha tmp = get_pci_device_details(dev_id, True) 490c6dab2a8SThomas Monjalon if "Driver_str" in tmp and tmp["Driver_str"] == driver: 491c6dab2a8SThomas Monjalon return 492c6dab2a8SThomas Monjalon print("Error: bind failed for %s - Cannot bind to driver %s" 493c6dab2a8SThomas Monjalon % (dev_id, driver)) 494c6dab2a8SThomas Monjalon if saved_driver is not None: # restore any previous driver 495c6dab2a8SThomas Monjalon bind_one(dev_id, saved_driver, force) 496c6dab2a8SThomas Monjalon return 497c6dab2a8SThomas Monjalon 498720b7a05SGuduri Prathyusha # For kernels > 3.15 driver_override is used to bind a device to a driver. 499720b7a05SGuduri Prathyusha # Before unbinding it, overwrite driver_override with empty string so that 500720b7a05SGuduri Prathyusha # the device can be bound to any other driver 501720b7a05SGuduri Prathyusha filename = "/sys/bus/pci/devices/%s/driver_override" % dev_id 502720b7a05SGuduri Prathyusha if os.path.exists(filename): 503720b7a05SGuduri Prathyusha try: 504720b7a05SGuduri Prathyusha f = open(filename, "w") 505720b7a05SGuduri Prathyusha except: 506720b7a05SGuduri Prathyusha print("Error: unbind failed for %s - Cannot open %s" 507720b7a05SGuduri Prathyusha % (dev_id, filename)) 508720b7a05SGuduri Prathyusha sys.exit(1) 509720b7a05SGuduri Prathyusha try: 510720b7a05SGuduri Prathyusha f.write("\00") 511720b7a05SGuduri Prathyusha f.close() 512720b7a05SGuduri Prathyusha except: 513720b7a05SGuduri Prathyusha print("Error: unbind failed for %s - Cannot open %s" 514720b7a05SGuduri Prathyusha % (dev_id, filename)) 515720b7a05SGuduri Prathyusha sys.exit(1) 516720b7a05SGuduri Prathyusha 517c6dab2a8SThomas Monjalon 518c6dab2a8SThomas Monjalondef unbind_all(dev_list, force=False): 519c6dab2a8SThomas Monjalon """Unbind method, takes a list of device locations""" 520657c7133SFerruh Yigit 521657c7133SFerruh Yigit if dev_list[0] == "dpdk": 522657c7133SFerruh Yigit for d in devices.keys(): 523657c7133SFerruh Yigit if "Driver_str" in devices[d]: 524657c7133SFerruh Yigit if devices[d]["Driver_str"] in dpdk_drivers: 525657c7133SFerruh Yigit unbind_one(devices[d]["Slot"], force) 526657c7133SFerruh Yigit return 527657c7133SFerruh Yigit 528c6dab2a8SThomas Monjalon dev_list = map(dev_id_from_dev_name, dev_list) 529c6dab2a8SThomas Monjalon for d in dev_list: 530c6dab2a8SThomas Monjalon unbind_one(d, force) 531c6dab2a8SThomas Monjalon 532c6dab2a8SThomas Monjalon 533c6dab2a8SThomas Monjalondef bind_all(dev_list, driver, force=False): 534c6dab2a8SThomas Monjalon """Bind method, takes a list of device locations""" 535c6dab2a8SThomas Monjalon global devices 536c6dab2a8SThomas Monjalon 537c6dab2a8SThomas Monjalon dev_list = map(dev_id_from_dev_name, dev_list) 538c6dab2a8SThomas Monjalon 539c6dab2a8SThomas Monjalon for d in dev_list: 540c6dab2a8SThomas Monjalon bind_one(d, driver, force) 541c6dab2a8SThomas Monjalon 5422fc35029SGuduri Prathyusha # For kenels < 3.15 when binding devices to a generic driver 5432fc35029SGuduri Prathyusha # (i.e. one that doesn't have a PCI ID table) using new_id, some devices 5442fc35029SGuduri Prathyusha # that are not bound to any other driver could be bound even if no one has 5452fc35029SGuduri Prathyusha # asked them to. hence, we check the list of drivers again, and see if 5462fc35029SGuduri Prathyusha # some of the previously-unbound devices were erroneously bound. 5472fc35029SGuduri Prathyusha if not os.path.exists("/sys/bus/pci/devices/%s/driver_override" % d): 548c6dab2a8SThomas Monjalon for d in devices.keys(): 549c6dab2a8SThomas Monjalon # skip devices that were already bound or that we know should be bound 550c6dab2a8SThomas Monjalon if "Driver_str" in devices[d] or d in dev_list: 551c6dab2a8SThomas Monjalon continue 552c6dab2a8SThomas Monjalon 553c6dab2a8SThomas Monjalon # update information about this device 554c6dab2a8SThomas Monjalon devices[d] = dict(devices[d].items() + 555c3ce205dSGuduri Prathyusha get_pci_device_details(d, True).items()) 556c6dab2a8SThomas Monjalon 557c6dab2a8SThomas Monjalon # check if updated information indicates that the device was bound 558c6dab2a8SThomas Monjalon if "Driver_str" in devices[d]: 559c6dab2a8SThomas Monjalon unbind_one(d, force) 560c6dab2a8SThomas Monjalon 561c6dab2a8SThomas Monjalon 562c6dab2a8SThomas Monjalondef display_devices(title, dev_list, extra_params=None): 563c6dab2a8SThomas Monjalon '''Displays to the user the details of a list of devices given in 564c6dab2a8SThomas Monjalon "dev_list". The "extra_params" parameter, if given, should contain a string 565c6dab2a8SThomas Monjalon with %()s fields in it for replacement by the named fields in each 566c6dab2a8SThomas Monjalon device's dictionary.''' 567c6dab2a8SThomas Monjalon strings = [] # this holds the strings to print. We sort before printing 568c6dab2a8SThomas Monjalon print("\n%s" % title) 569c6dab2a8SThomas Monjalon print("="*len(title)) 570c6dab2a8SThomas Monjalon if len(dev_list) == 0: 571c6dab2a8SThomas Monjalon strings.append("<none>") 572c6dab2a8SThomas Monjalon else: 573c6dab2a8SThomas Monjalon for dev in dev_list: 574c6dab2a8SThomas Monjalon if extra_params is not None: 575c3ce205dSGuduri Prathyusha strings.append("%s '%s %s' %s" % (dev["Slot"], 576c6dab2a8SThomas Monjalon dev["Device_str"], 577c3ce205dSGuduri Prathyusha dev["Device"], 578c6dab2a8SThomas Monjalon extra_params % dev)) 579c6dab2a8SThomas Monjalon else: 580c6dab2a8SThomas Monjalon strings.append("%s '%s'" % (dev["Slot"], dev["Device_str"])) 581c6dab2a8SThomas Monjalon # sort before printing, so that the entries appear in PCI order 582c6dab2a8SThomas Monjalon strings.sort() 583c6dab2a8SThomas Monjalon print("\n".join(strings)) # print one per line 584c6dab2a8SThomas Monjalon 585c7dd412bSGuduri Prathyushadef show_device_status(devices_type, device_name): 586c6dab2a8SThomas Monjalon global dpdk_drivers 587c6dab2a8SThomas Monjalon kernel_drv = [] 588c6dab2a8SThomas Monjalon dpdk_drv = [] 589c6dab2a8SThomas Monjalon no_drv = [] 590c6dab2a8SThomas Monjalon 591c6dab2a8SThomas Monjalon # split our list of network devices into the three categories above 592c6dab2a8SThomas Monjalon for d in devices.keys(): 5938ad08a28SGuduri Prathyusha if device_type_match(devices[d], devices_type): 594c6dab2a8SThomas Monjalon if not has_driver(d): 595c6dab2a8SThomas Monjalon no_drv.append(devices[d]) 596c6dab2a8SThomas Monjalon continue 597c6dab2a8SThomas Monjalon if devices[d]["Driver_str"] in dpdk_drivers: 598c6dab2a8SThomas Monjalon dpdk_drv.append(devices[d]) 599c6dab2a8SThomas Monjalon else: 600c6dab2a8SThomas Monjalon kernel_drv.append(devices[d]) 601c6dab2a8SThomas Monjalon 602c6dab2a8SThomas Monjalon # print each category separately, so we can clearly see what's used by DPDK 6038ad08a28SGuduri Prathyusha display_devices("%s devices using DPDK-compatible driver" % device_name, 6048ad08a28SGuduri Prathyusha dpdk_drv, "drv=%(Driver_str)s unused=%(Module_str)s") 605c7dd412bSGuduri Prathyusha display_devices("%s devices using kernel driver" % device_name, kernel_drv, 606c6dab2a8SThomas Monjalon "if=%(Interface)s drv=%(Driver_str)s " 607c6dab2a8SThomas Monjalon "unused=%(Module_str)s %(Active)s") 6088ad08a28SGuduri Prathyusha display_devices("Other %s devices" % device_name, no_drv, 6098ad08a28SGuduri Prathyusha "unused=%(Module_str)s") 610c6dab2a8SThomas Monjalon 611c7dd412bSGuduri Prathyushadef show_status(): 612c7dd412bSGuduri Prathyusha '''Function called when the script is passed the "--status" option. 613c7dd412bSGuduri Prathyusha Displays to the user what devices are bound to the igb_uio driver, the 614c7dd412bSGuduri Prathyusha kernel driver or to no driver''' 615c6dab2a8SThomas Monjalon 616b153c00bSFerruh Yigit if status_dev == "net" or status_dev == "all": 617c7dd412bSGuduri Prathyusha show_device_status(network_devices, "Network") 618b153c00bSFerruh Yigit 619b153c00bSFerruh Yigit if status_dev == "crypto" or status_dev == "all": 620c7dd412bSGuduri Prathyusha show_device_status(crypto_devices, "Crypto") 621b153c00bSFerruh Yigit 622b153c00bSFerruh Yigit if status_dev == "event" or status_dev == "all": 62332a02dbfSGuduri Prathyusha show_device_status(eventdev_devices, "Eventdev") 624b153c00bSFerruh Yigit 625b153c00bSFerruh Yigit if status_dev == "mempool" or status_dev == "all": 62680a1858dSGuduri Prathyusha show_device_status(mempool_devices, "Mempool") 627c6dab2a8SThomas Monjalon 628c6dab2a8SThomas Monjalondef parse_args(): 629c6dab2a8SThomas Monjalon '''Parses the command-line arguments given by the user and takes the 630c6dab2a8SThomas Monjalon appropriate action for each''' 631c6dab2a8SThomas Monjalon global b_flag 632c6dab2a8SThomas Monjalon global status_flag 633b153c00bSFerruh Yigit global status_dev 634c6dab2a8SThomas Monjalon global force_flag 635c6dab2a8SThomas Monjalon global args 636c6dab2a8SThomas Monjalon if len(sys.argv) <= 1: 637c6dab2a8SThomas Monjalon usage() 638c6dab2a8SThomas Monjalon sys.exit(0) 639c6dab2a8SThomas Monjalon 640c6dab2a8SThomas Monjalon try: 641c6dab2a8SThomas Monjalon opts, args = getopt.getopt(sys.argv[1:], "b:us", 642b153c00bSFerruh Yigit ["help", "usage", "status", "status-dev=", 643b153c00bSFerruh Yigit "force", "bind=", "unbind", ]) 644c6dab2a8SThomas Monjalon except getopt.GetoptError as error: 645c6dab2a8SThomas Monjalon print(str(error)) 646c6dab2a8SThomas Monjalon print("Run '%s --usage' for further information" % sys.argv[0]) 647c6dab2a8SThomas Monjalon sys.exit(1) 648c6dab2a8SThomas Monjalon 649c6dab2a8SThomas Monjalon for opt, arg in opts: 650c6dab2a8SThomas Monjalon if opt == "--help" or opt == "--usage": 651c6dab2a8SThomas Monjalon usage() 652c6dab2a8SThomas Monjalon sys.exit(0) 653b153c00bSFerruh Yigit if opt == "--status-dev": 654b153c00bSFerruh Yigit status_flag = True 655b153c00bSFerruh Yigit status_dev = arg 656c6dab2a8SThomas Monjalon if opt == "--status" or opt == "-s": 657c6dab2a8SThomas Monjalon status_flag = True 658b153c00bSFerruh Yigit status_dev = "all" 659c6dab2a8SThomas Monjalon if opt == "--force": 660c6dab2a8SThomas Monjalon force_flag = True 661c6dab2a8SThomas Monjalon if opt == "-b" or opt == "-u" or opt == "--bind" or opt == "--unbind": 662c6dab2a8SThomas Monjalon if b_flag is not None: 663c6dab2a8SThomas Monjalon print("Error - Only one bind or unbind may be specified\n") 664c6dab2a8SThomas Monjalon sys.exit(1) 665c6dab2a8SThomas Monjalon if opt == "-u" or opt == "--unbind": 666c6dab2a8SThomas Monjalon b_flag = "none" 667c6dab2a8SThomas Monjalon else: 668c6dab2a8SThomas Monjalon b_flag = arg 669c6dab2a8SThomas Monjalon 670c6dab2a8SThomas Monjalon 671c6dab2a8SThomas Monjalondef do_arg_actions(): 672c6dab2a8SThomas Monjalon '''do the actual action requested by the user''' 673c6dab2a8SThomas Monjalon global b_flag 674c6dab2a8SThomas Monjalon global status_flag 675c6dab2a8SThomas Monjalon global force_flag 676c6dab2a8SThomas Monjalon global args 677c6dab2a8SThomas Monjalon 678c6dab2a8SThomas Monjalon if b_flag is None and not status_flag: 679c6dab2a8SThomas Monjalon print("Error: No action specified for devices." 680c6dab2a8SThomas Monjalon "Please give a -b or -u option") 681c6dab2a8SThomas Monjalon print("Run '%s --usage' for further information" % sys.argv[0]) 682c6dab2a8SThomas Monjalon sys.exit(1) 683c6dab2a8SThomas Monjalon 684c6dab2a8SThomas Monjalon if b_flag is not None and len(args) == 0: 685c6dab2a8SThomas Monjalon print("Error: No devices specified.") 686c6dab2a8SThomas Monjalon print("Run '%s --usage' for further information" % sys.argv[0]) 687c6dab2a8SThomas Monjalon sys.exit(1) 688c6dab2a8SThomas Monjalon 689c6dab2a8SThomas Monjalon if b_flag == "none" or b_flag == "None": 690c6dab2a8SThomas Monjalon unbind_all(args, force_flag) 691c6dab2a8SThomas Monjalon elif b_flag is not None: 692c6dab2a8SThomas Monjalon bind_all(args, b_flag, force_flag) 693c6dab2a8SThomas Monjalon if status_flag: 694c6dab2a8SThomas Monjalon if b_flag is not None: 695ea9f00f7SGuduri Prathyusha clear_data() 6968ad08a28SGuduri Prathyusha # refresh if we have changed anything 6978ad08a28SGuduri Prathyusha get_device_details(network_devices) 6988ad08a28SGuduri Prathyusha get_device_details(crypto_devices) 69932a02dbfSGuduri Prathyusha get_device_details(eventdev_devices) 70080a1858dSGuduri Prathyusha get_device_details(mempool_devices) 701c6dab2a8SThomas Monjalon show_status() 702c6dab2a8SThomas Monjalon 703c6dab2a8SThomas Monjalon 704c6dab2a8SThomas Monjalondef main(): 705c6dab2a8SThomas Monjalon '''program main function''' 706c6dab2a8SThomas Monjalon parse_args() 707c6dab2a8SThomas Monjalon check_modules() 708ea9f00f7SGuduri Prathyusha clear_data() 7098ad08a28SGuduri Prathyusha get_device_details(network_devices) 7108ad08a28SGuduri Prathyusha get_device_details(crypto_devices) 71132a02dbfSGuduri Prathyusha get_device_details(eventdev_devices) 71280a1858dSGuduri Prathyusha get_device_details(mempool_devices) 713c6dab2a8SThomas Monjalon do_arg_actions() 714c6dab2a8SThomas Monjalon 715c6dab2a8SThomas Monjalonif __name__ == "__main__": 716c6dab2a8SThomas Monjalon main() 717