13f6f8362SLouise Kilheeney#!/usr/bin/env python3 29d7c01f8SBruce Richardson# SPDX-License-Identifier: BSD-3-Clause 39d7c01f8SBruce Richardson# Copyright(c) 2010-2014 Intel Corporation 4c6dab2a8SThomas Monjalon# 5c6dab2a8SThomas Monjalon 6c6dab2a8SThomas Monjalonimport sys 7c6dab2a8SThomas Monjalonimport os 8c6dab2a8SThomas Monjalonimport getopt 9c6dab2a8SThomas Monjalonimport subprocess 10781eafc9SBruce Richardsonfrom glob import glob 11c6dab2a8SThomas Monjalonfrom os.path import exists, abspath, dirname, basename 12781eafc9SBruce Richardsonfrom os.path import join as path_join 13c6dab2a8SThomas Monjalon 148ad08a28SGuduri Prathyusha# The PCI base class for all devices 158ad08a28SGuduri Prathyushanetwork_class = {'Class': '02', 'Vendor': None, 'Device': None, 168ad08a28SGuduri Prathyusha 'SVendor': None, 'SDevice': None} 1707488e29SNicolas Chautruacceleration_class = {'Class': '12', 'Vendor': None, 'Device': None, 1807488e29SNicolas Chautru 'SVendor': None, 'SDevice': None} 19c01c748eSRosen Xuifpga_class = {'Class': '12', 'Vendor': '8086', 'Device': '0b30', 20c01c748eSRosen Xu 'SVendor': None, 'SDevice': None} 218ad08a28SGuduri Prathyushaencryption_class = {'Class': '10', 'Vendor': None, 'Device': None, 228ad08a28SGuduri Prathyusha 'SVendor': None, 'SDevice': None} 238ad08a28SGuduri Prathyushaintel_processor_class = {'Class': '0b', 'Vendor': '8086', 'Device': None, 248ad08a28SGuduri Prathyusha 'SVendor': None, 'SDevice': None} 2532a02dbfSGuduri Prathyushacavium_sso = {'Class': '08', 'Vendor': '177d', 'Device': 'a04b,a04d', 2632a02dbfSGuduri Prathyusha 'SVendor': None, 'SDevice': None} 2780a1858dSGuduri Prathyushacavium_fpa = {'Class': '08', 'Vendor': '177d', 'Device': 'a053', 2880a1858dSGuduri Prathyusha 'SVendor': None, 'SDevice': None} 29156c42eaSJerin Jacobcavium_pkx = {'Class': '08', 'Vendor': '177d', 'Device': 'a0dd,a049', 30156c42eaSJerin Jacob 'SVendor': None, 'SDevice': None} 31f4bc0010SPavan Nikhileshcavium_tim = {'Class': '08', 'Vendor': '177d', 'Device': 'a051', 32f4bc0010SPavan Nikhilesh 'SVendor': None, 'SDevice': None} 339d35895eSSunila Sahucavium_zip = {'Class': '12', 'Vendor': '177d', 'Device': 'a037', 349d35895eSSunila Sahu 'SVendor': None, 'SDevice': None} 3520526313SXiaohua Zhangavp_vnic = {'Class': '05', 'Vendor': '1af4', 'Device': '1110', 3620526313SXiaohua Zhang 'SVendor': None, 'SDevice': None} 378ad08a28SGuduri Prathyusha 380bcc6644SJerin Jacobocteontx2_sso = {'Class': '08', 'Vendor': '177d', 'Device': 'a0f9,a0fa', 390bcc6644SJerin Jacob 'SVendor': None, 'SDevice': None} 400bcc6644SJerin Jacobocteontx2_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc', 410bcc6644SJerin Jacob 'SVendor': None, 'SDevice': None} 42f5be5d99SJerin Jacobocteontx2_dma = {'Class': '08', 'Vendor': '177d', 'Device': 'a081', 43f5be5d99SJerin Jacob 'SVendor': None, 'SDevice': None} 440bcc6644SJerin Jacob 4512d4777aSBruce Richardsonintel_ioat_bdw = {'Class': '08', 'Vendor': '8086', 'Device': '6f20,6f21,6f22,6f23,6f24,6f25,6f26,6f27,6f2e,6f2f', 4612d4777aSBruce Richardson 'SVendor': None, 'SDevice': None} 4712d4777aSBruce Richardsonintel_ioat_skx = {'Class': '08', 'Vendor': '8086', 'Device': '2021', 4812d4777aSBruce Richardson 'SVendor': None, 'SDevice': None} 49299e282fSRadu Nicolauintel_ioat_icx = {'Class': '08', 'Vendor': '8086', 'Device': '0b00', 50299e282fSRadu Nicolau 'SVendor': None, 'SDevice': None} 51*43f9b521SKevin Laatzintel_idxd_spr = {'Class': '08', 'Vendor': '8086', 'Device': '0b25', 52*43f9b521SKevin Laatz 'SVendor': None, 'SDevice': None} 53034c328eSXiaoyun Liintel_ntb_skx = {'Class': '06', 'Vendor': '8086', 'Device': '201c', 54034c328eSXiaoyun Li 'SVendor': None, 'SDevice': None} 55f5057be3SXiaoyun Liintel_ntb_icx = {'Class': '06', 'Vendor': '8086', 'Device': '347e', 56f5057be3SXiaoyun Li 'SVendor': None, 'SDevice': None} 5712d4777aSBruce Richardson 58c01c748eSRosen Xunetwork_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class] 5907488e29SNicolas Chautrubaseband_devices = [acceleration_class] 608ad08a28SGuduri Prathyushacrypto_devices = [encryption_class, intel_processor_class] 610bcc6644SJerin Jacobeventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso] 620bcc6644SJerin Jacobmempool_devices = [cavium_fpa, octeontx2_npa] 639d35895eSSunila Sahucompress_devices = [cavium_zip] 64*43f9b521SKevin Laatzmisc_devices = [intel_ioat_bdw, intel_ioat_skx, intel_ioat_icx, intel_idxd_spr, 65*43f9b521SKevin Laatz intel_ntb_skx, intel_ntb_icx, 66*43f9b521SKevin Laatz octeontx2_dma] 67c6dab2a8SThomas Monjalon 68c6dab2a8SThomas Monjalon# global dict ethernet devices present. Dictionary indexed by PCI address. 69c6dab2a8SThomas Monjalon# Each device within this is itself a dictionary of device properties 70c6dab2a8SThomas Monjalondevices = {} 71c6dab2a8SThomas Monjalon# list of supported DPDK drivers 72c6dab2a8SThomas Monjalondpdk_drivers = ["igb_uio", "vfio-pci", "uio_pci_generic"] 73681a6728SAnatoly Burakov# list of currently loaded kernel modules 74681a6728SAnatoly Burakovloaded_modules = None 75c6dab2a8SThomas Monjalon 76c6dab2a8SThomas Monjalon# command-line arg flags 77c6dab2a8SThomas Monjalonb_flag = None 78c6dab2a8SThomas Monjalonstatus_flag = False 79c6dab2a8SThomas Monjalonforce_flag = False 80c6dab2a8SThomas Monjalonargs = [] 81c6dab2a8SThomas Monjalon 82c6dab2a8SThomas Monjalon 83c6dab2a8SThomas Monjalondef usage(): 84c6dab2a8SThomas Monjalon '''Print usage information for the program''' 85c6dab2a8SThomas Monjalon argv0 = basename(sys.argv[0]) 86c6dab2a8SThomas Monjalon print(""" 87c6dab2a8SThomas MonjalonUsage: 88c6dab2a8SThomas Monjalon------ 89c6dab2a8SThomas Monjalon 90c6dab2a8SThomas Monjalon %(argv0)s [options] DEVICE1 DEVICE2 .... 91c6dab2a8SThomas Monjalon 92c6dab2a8SThomas Monjalonwhere DEVICE1, DEVICE2 etc, are specified via PCI "domain:bus:slot.func" syntax 93c6dab2a8SThomas Monjalonor "bus:slot.func" syntax. For devices bound to Linux kernel drivers, they may 94c6dab2a8SThomas Monjalonalso be referred to by Linux interface name e.g. eth0, eth1, em0, em1, etc. 95781eafc9SBruce RichardsonIf devices are specified using PCI <domain:>bus:device:func format, then 96781eafc9SBruce Richardsonshell wildcards and ranges may be used, e.g. 80:04.*, 80:04.[0-3] 97c6dab2a8SThomas Monjalon 98c6dab2a8SThomas MonjalonOptions: 99c6dab2a8SThomas Monjalon --help, --usage: 100c6dab2a8SThomas Monjalon Display usage information and quit 101c6dab2a8SThomas Monjalon 102c6dab2a8SThomas Monjalon -s, --status: 103b153c00bSFerruh Yigit Print the current status of all known network, crypto, event 104b153c00bSFerruh Yigit and mempool devices. 105c6dab2a8SThomas Monjalon For each device, it displays the PCI domain, bus, slot and function, 106c6dab2a8SThomas Monjalon along with a text description of the device. Depending upon whether the 107c6dab2a8SThomas Monjalon device is being used by a kernel driver, the igb_uio driver, or no 108c6dab2a8SThomas Monjalon driver, other relevant information will be displayed: 109c6dab2a8SThomas Monjalon * the Linux interface name e.g. if=eth0 110c6dab2a8SThomas Monjalon * the driver being used e.g. drv=igb_uio 111c6dab2a8SThomas Monjalon * any suitable drivers not currently using that device 112c6dab2a8SThomas Monjalon e.g. unused=igb_uio 113c6dab2a8SThomas Monjalon NOTE: if this flag is passed along with a bind/unbind option, the 114c6dab2a8SThomas Monjalon status display will always occur after the other operations have taken 115c6dab2a8SThomas Monjalon place. 116c6dab2a8SThomas Monjalon 117b153c00bSFerruh Yigit --status-dev: 118b153c00bSFerruh Yigit Print the status of given device group. Supported device groups are: 11907488e29SNicolas Chautru "net", "baseband", "crypto", "event", "mempool" and "compress" 120b153c00bSFerruh Yigit 121c6dab2a8SThomas Monjalon -b driver, --bind=driver: 122c6dab2a8SThomas Monjalon Select the driver to use or \"none\" to unbind the device 123c6dab2a8SThomas Monjalon 124c6dab2a8SThomas Monjalon -u, --unbind: 125c6dab2a8SThomas Monjalon Unbind a device (Equivalent to \"-b none\") 126c6dab2a8SThomas Monjalon 127c6dab2a8SThomas Monjalon --force: 128c6dab2a8SThomas Monjalon By default, network devices which are used by Linux - as indicated by 129c6dab2a8SThomas Monjalon having routes in the routing table - cannot be modified. Using the 130c6dab2a8SThomas Monjalon --force flag overrides this behavior, allowing active links to be 131c6dab2a8SThomas Monjalon forcibly unbound. 132c6dab2a8SThomas Monjalon WARNING: This can lead to loss of network connection and should be used 133c6dab2a8SThomas Monjalon with caution. 134c6dab2a8SThomas Monjalon 135c6dab2a8SThomas MonjalonExamples: 136c6dab2a8SThomas Monjalon--------- 137c6dab2a8SThomas Monjalon 138c6dab2a8SThomas MonjalonTo display current device status: 139c6dab2a8SThomas Monjalon %(argv0)s --status 140c6dab2a8SThomas Monjalon 141b153c00bSFerruh YigitTo display current network device status: 142b153c00bSFerruh Yigit %(argv0)s --status-dev net 143b153c00bSFerruh Yigit 144c6dab2a8SThomas MonjalonTo bind eth1 from the current driver and move to use igb_uio 145c6dab2a8SThomas Monjalon %(argv0)s --bind=igb_uio eth1 146c6dab2a8SThomas Monjalon 147c6dab2a8SThomas MonjalonTo unbind 0000:01:00.0 from using any driver 148c6dab2a8SThomas Monjalon %(argv0)s -u 0000:01:00.0 149c6dab2a8SThomas Monjalon 150c6dab2a8SThomas MonjalonTo bind 0000:02:00.0 and 0000:02:00.1 to the ixgbe kernel driver 151c6dab2a8SThomas Monjalon %(argv0)s -b ixgbe 02:00.0 02:00.1 152c6dab2a8SThomas Monjalon 153781eafc9SBruce RichardsonTo bind all functions on device 0000:02:00 to ixgbe kernel driver 154781eafc9SBruce Richardson %(argv0)s -b ixgbe 02:00.* 155781eafc9SBruce Richardson 156c6dab2a8SThomas Monjalon """ % locals()) # replace items from local variables 157c6dab2a8SThomas Monjalon 158681a6728SAnatoly Burakov# check if a specific kernel module is loaded 159681a6728SAnatoly Burakovdef module_is_loaded(module): 160681a6728SAnatoly Burakov global loaded_modules 161681a6728SAnatoly Burakov 16243623124SPavan Nikhilesh if module == 'vfio_pci': 16343623124SPavan Nikhilesh module = 'vfio-pci' 16443623124SPavan Nikhilesh 165681a6728SAnatoly Burakov if loaded_modules: 166681a6728SAnatoly Burakov return module in loaded_modules 167681a6728SAnatoly Burakov 168681a6728SAnatoly Burakov # Get list of sysfs modules (both built-in and dynamically loaded) 169681a6728SAnatoly Burakov sysfs_path = '/sys/module/' 170681a6728SAnatoly Burakov 171681a6728SAnatoly Burakov # Get the list of directories in sysfs_path 172681a6728SAnatoly Burakov sysfs_mods = [m for m in os.listdir(sysfs_path) 173681a6728SAnatoly Burakov if os.path.isdir(os.path.join(sysfs_path, m))] 174681a6728SAnatoly Burakov 175681a6728SAnatoly Burakov # special case for vfio_pci (module is named vfio-pci, 176681a6728SAnatoly Burakov # but its .ko is named vfio_pci) 177681a6728SAnatoly Burakov sysfs_mods = [a if a != 'vfio_pci' else 'vfio-pci' for a in sysfs_mods] 178681a6728SAnatoly Burakov 179681a6728SAnatoly Burakov loaded_modules = sysfs_mods 180681a6728SAnatoly Burakov 181681a6728SAnatoly Burakov return module in sysfs_mods 182681a6728SAnatoly Burakov 183c6dab2a8SThomas Monjalon 184c6dab2a8SThomas Monjalondef check_modules(): 185c6dab2a8SThomas Monjalon '''Checks that igb_uio is loaded''' 186c6dab2a8SThomas Monjalon global dpdk_drivers 187c6dab2a8SThomas Monjalon 188c6dab2a8SThomas Monjalon # list of supported modules 189c6dab2a8SThomas Monjalon mods = [{"Name": driver, "Found": False} for driver in dpdk_drivers] 190c6dab2a8SThomas Monjalon 191c6dab2a8SThomas Monjalon # first check if module is loaded 192c6dab2a8SThomas Monjalon for mod in mods: 193681a6728SAnatoly Burakov if module_is_loaded(mod["Name"]): 194c6dab2a8SThomas Monjalon mod["Found"] = True 195c6dab2a8SThomas Monjalon 196c6dab2a8SThomas Monjalon # check if we have at least one loaded module 197c6dab2a8SThomas Monjalon if True not in [mod["Found"] for mod in mods] and b_flag is not None: 1982804529fSAnatoly Burakov print("Warning: no supported DPDK kernel modules are loaded", file=sys.stderr) 199c6dab2a8SThomas Monjalon 200c6dab2a8SThomas Monjalon # change DPDK driver list to only contain drivers that are loaded 201c6dab2a8SThomas Monjalon dpdk_drivers = [mod["Name"] for mod in mods if mod["Found"]] 202c6dab2a8SThomas Monjalon 203c6dab2a8SThomas Monjalon 204c6dab2a8SThomas Monjalondef has_driver(dev_id): 205c6dab2a8SThomas Monjalon '''return true if a device is assigned to a driver. False otherwise''' 206c6dab2a8SThomas Monjalon return "Driver_str" in devices[dev_id] 207c6dab2a8SThomas Monjalon 208c6dab2a8SThomas Monjalon 209c3ce205dSGuduri Prathyushadef get_pci_device_details(dev_id, probe_lspci): 210c6dab2a8SThomas Monjalon '''This function gets additional details for a PCI device''' 211c6dab2a8SThomas Monjalon device = {} 212c6dab2a8SThomas Monjalon 213c3ce205dSGuduri Prathyusha if probe_lspci: 2143f6f8362SLouise Kilheeney extra_info = subprocess.check_output(["lspci", "-vmmks", dev_id]).splitlines() 215c6dab2a8SThomas Monjalon # parse lspci details 216c6dab2a8SThomas Monjalon for line in extra_info: 217c6dab2a8SThomas Monjalon if len(line) == 0: 218c6dab2a8SThomas Monjalon continue 21908ab6cd3SChristos Ricudis name, value = line.decode("utf8").split("\t", 1) 220c6dab2a8SThomas Monjalon name = name.strip(":") + "_str" 221c6dab2a8SThomas Monjalon device[name] = value 222c6dab2a8SThomas Monjalon # check for a unix interface name 223c6dab2a8SThomas Monjalon device["Interface"] = "" 224c6dab2a8SThomas Monjalon for base, dirs, _ in os.walk("/sys/bus/pci/devices/%s/" % dev_id): 225c6dab2a8SThomas Monjalon if "net" in dirs: 226c6dab2a8SThomas Monjalon device["Interface"] = \ 227c6dab2a8SThomas Monjalon ",".join(os.listdir(os.path.join(base, "net"))) 228c6dab2a8SThomas Monjalon break 229c6dab2a8SThomas Monjalon # check if a port is used for ssh connection 230c6dab2a8SThomas Monjalon device["Ssh_if"] = False 231c6dab2a8SThomas Monjalon device["Active"] = "" 232c6dab2a8SThomas Monjalon 233c6dab2a8SThomas Monjalon return device 234c6dab2a8SThomas Monjalon 235ea9f00f7SGuduri Prathyushadef clear_data(): 236ea9f00f7SGuduri Prathyusha '''This function clears any old data''' 23793b93bebSTimothy Redaelli global devices 238ea9f00f7SGuduri Prathyusha devices = {} 239c6dab2a8SThomas Monjalon 240ea9f00f7SGuduri Prathyushadef get_device_details(devices_type): 241c6dab2a8SThomas Monjalon '''This function populates the "devices" dictionary. The keys used are 242c6dab2a8SThomas Monjalon the pci addresses (domain:bus:slot.func). The values are themselves 243c6dab2a8SThomas Monjalon dictionaries - one for each NIC.''' 244c6dab2a8SThomas Monjalon global devices 245c6dab2a8SThomas Monjalon global dpdk_drivers 246c6dab2a8SThomas Monjalon 247c6dab2a8SThomas Monjalon # first loop through and read details for all devices 248c3ce205dSGuduri Prathyusha # request machine readable format, with numeric IDs and String 249c6dab2a8SThomas Monjalon dev = {} 2503f6f8362SLouise Kilheeney dev_lines = subprocess.check_output(["lspci", "-Dvmmnnk"]).splitlines() 251c6dab2a8SThomas Monjalon for dev_line in dev_lines: 252c6dab2a8SThomas Monjalon if len(dev_line) == 0: 2538ad08a28SGuduri Prathyusha if device_type_match(dev, devices_type): 2548ad08a28SGuduri Prathyusha # Replace "Driver" with "Driver_str" to have consistency of 2558ad08a28SGuduri Prathyusha # of dictionary key names 256c3ce205dSGuduri Prathyusha if "Driver" in dev.keys(): 257c3ce205dSGuduri Prathyusha dev["Driver_str"] = dev.pop("Driver") 258c76a10ecSAnatoly Burakov if "Module" in dev.keys(): 259c76a10ecSAnatoly Burakov dev["Module_str"] = dev.pop("Module") 260c6dab2a8SThomas Monjalon # use dict to make copy of dev 261c6dab2a8SThomas Monjalon devices[dev["Slot"]] = dict(dev) 262c3ce205dSGuduri Prathyusha # Clear previous device's data 263c3ce205dSGuduri Prathyusha dev = {} 264c6dab2a8SThomas Monjalon else: 26508ab6cd3SChristos Ricudis name, value = dev_line.decode("utf8").split("\t", 1) 266c3ce205dSGuduri Prathyusha value_list = value.rsplit(' ', 1) 267c3ce205dSGuduri Prathyusha if len(value_list) > 1: 268c3ce205dSGuduri Prathyusha # String stored in <name>_str 269c3ce205dSGuduri Prathyusha dev[name.rstrip(":") + '_str'] = value_list[0] 270c3ce205dSGuduri Prathyusha # Numeric IDs 271c3ce205dSGuduri Prathyusha dev[name.rstrip(":")] = value_list[len(value_list) - 1] \ 272c3ce205dSGuduri Prathyusha .rstrip("]").lstrip("[") 273c6dab2a8SThomas Monjalon 2748ad08a28SGuduri Prathyusha if devices_type == network_devices: 275c6dab2a8SThomas Monjalon # check what is the interface if any for an ssh connection if 276c6dab2a8SThomas Monjalon # any to this host, so we can mark it later. 277c6dab2a8SThomas Monjalon ssh_if = [] 2783f6f8362SLouise Kilheeney route = subprocess.check_output(["ip", "-o", "route"]) 279c6dab2a8SThomas Monjalon # filter out all lines for 169.254 routes 280c6dab2a8SThomas Monjalon route = "\n".join(filter(lambda ln: not ln.startswith("169.254"), 281c6dab2a8SThomas Monjalon route.decode().splitlines())) 282c6dab2a8SThomas Monjalon rt_info = route.split() 283c6dab2a8SThomas Monjalon for i in range(len(rt_info) - 1): 284c6dab2a8SThomas Monjalon if rt_info[i] == "dev": 285c6dab2a8SThomas Monjalon ssh_if.append(rt_info[i+1]) 286c6dab2a8SThomas Monjalon 287c6dab2a8SThomas Monjalon # based on the basic info, get extended text details 288c6dab2a8SThomas Monjalon for d in devices.keys(): 2898ad08a28SGuduri Prathyusha if not device_type_match(devices[d], devices_type): 290617d9052SYoni Gilad continue 291617d9052SYoni Gilad 292c6dab2a8SThomas Monjalon # get additional info and add it to existing data 293c6dab2a8SThomas Monjalon devices[d] = devices[d].copy() 294c3ce205dSGuduri Prathyusha # No need to probe lspci 295c3ce205dSGuduri Prathyusha devices[d].update(get_pci_device_details(d, False).items()) 296c6dab2a8SThomas Monjalon 2978ad08a28SGuduri Prathyusha if devices_type == network_devices: 298ea9f00f7SGuduri Prathyusha for _if in ssh_if: 299ea9f00f7SGuduri Prathyusha if _if in devices[d]["Interface"].split(","): 300ea9f00f7SGuduri Prathyusha devices[d]["Ssh_if"] = True 301ea9f00f7SGuduri Prathyusha devices[d]["Active"] = "*Active*" 302ea9f00f7SGuduri Prathyusha break 303ea9f00f7SGuduri Prathyusha 304c6dab2a8SThomas Monjalon # add igb_uio to list of supporting modules if needed 305c6dab2a8SThomas Monjalon if "Module_str" in devices[d]: 306c6dab2a8SThomas Monjalon for driver in dpdk_drivers: 307c6dab2a8SThomas Monjalon if driver not in devices[d]["Module_str"]: 308c6dab2a8SThomas Monjalon devices[d]["Module_str"] = \ 309c6dab2a8SThomas Monjalon devices[d]["Module_str"] + ",%s" % driver 310c6dab2a8SThomas Monjalon else: 311c6dab2a8SThomas Monjalon devices[d]["Module_str"] = ",".join(dpdk_drivers) 312c6dab2a8SThomas Monjalon 313c6dab2a8SThomas Monjalon # make sure the driver and module strings do not have any duplicates 314c6dab2a8SThomas Monjalon if has_driver(d): 315c6dab2a8SThomas Monjalon modules = devices[d]["Module_str"].split(",") 316c6dab2a8SThomas Monjalon if devices[d]["Driver_str"] in modules: 317c6dab2a8SThomas Monjalon modules.remove(devices[d]["Driver_str"]) 318c6dab2a8SThomas Monjalon devices[d]["Module_str"] = ",".join(modules) 319c6dab2a8SThomas Monjalon 320c6dab2a8SThomas Monjalon 3218ad08a28SGuduri Prathyushadef device_type_match(dev, devices_type): 3228ad08a28SGuduri Prathyusha for i in range(len(devices_type)): 3238ad08a28SGuduri Prathyusha param_count = len( 3248ad08a28SGuduri Prathyusha [x for x in devices_type[i].values() if x is not None]) 3258ad08a28SGuduri Prathyusha match_count = 0 3268ad08a28SGuduri Prathyusha if dev["Class"][0:2] == devices_type[i]["Class"]: 3278ad08a28SGuduri Prathyusha match_count = match_count + 1 3288ad08a28SGuduri Prathyusha for key in devices_type[i].keys(): 3298ad08a28SGuduri Prathyusha if key != 'Class' and devices_type[i][key]: 3308ad08a28SGuduri Prathyusha value_list = devices_type[i][key].split(',') 3318ad08a28SGuduri Prathyusha for value in value_list: 3328ad08a28SGuduri Prathyusha if value.strip(' ') == dev[key]: 3338ad08a28SGuduri Prathyusha match_count = match_count + 1 3348ad08a28SGuduri Prathyusha # count must be the number of non None parameters to match 3358ad08a28SGuduri Prathyusha if match_count == param_count: 3368ad08a28SGuduri Prathyusha return True 3378ad08a28SGuduri Prathyusha return False 3388ad08a28SGuduri Prathyusha 339c6dab2a8SThomas Monjalondef dev_id_from_dev_name(dev_name): 340c6dab2a8SThomas Monjalon '''Take a device "name" - a string passed in by user to identify a NIC 341c6dab2a8SThomas Monjalon device, and determine the device id - i.e. the domain:bus:slot.func - for 342c6dab2a8SThomas Monjalon it, which can then be used to index into the devices array''' 343c6dab2a8SThomas Monjalon 344c6dab2a8SThomas Monjalon # check if it's already a suitable index 345c6dab2a8SThomas Monjalon if dev_name in devices: 346c6dab2a8SThomas Monjalon return dev_name 347c6dab2a8SThomas Monjalon # check if it's an index just missing the domain part 348c6dab2a8SThomas Monjalon elif "0000:" + dev_name in devices: 349c6dab2a8SThomas Monjalon return "0000:" + dev_name 350c6dab2a8SThomas Monjalon else: 351c6dab2a8SThomas Monjalon # check if it's an interface name, e.g. eth1 352c6dab2a8SThomas Monjalon for d in devices.keys(): 353c6dab2a8SThomas Monjalon if dev_name in devices[d]["Interface"].split(","): 354c6dab2a8SThomas Monjalon return devices[d]["Slot"] 355c6dab2a8SThomas Monjalon # if nothing else matches - error 35615f6aac7SAnatoly Burakov raise ValueError("Unknown device: %s. " 357c6dab2a8SThomas Monjalon "Please specify device in \"bus:slot.func\" format" % dev_name) 358c6dab2a8SThomas Monjalon 359c6dab2a8SThomas Monjalon 360c6dab2a8SThomas Monjalondef unbind_one(dev_id, force): 361c6dab2a8SThomas Monjalon '''Unbind the device identified by "dev_id" from its current driver''' 362c6dab2a8SThomas Monjalon dev = devices[dev_id] 363c6dab2a8SThomas Monjalon if not has_driver(dev_id): 3642804529fSAnatoly Burakov print("Notice: %s %s %s is not currently managed by any driver" % 3652804529fSAnatoly Burakov (dev["Slot"], dev["Device_str"], dev["Interface"]), file=sys.stderr) 366c6dab2a8SThomas Monjalon return 367c6dab2a8SThomas Monjalon 368c6dab2a8SThomas Monjalon # prevent us disconnecting ourselves 369c6dab2a8SThomas Monjalon if dev["Ssh_if"] and not force: 3702804529fSAnatoly Burakov print("Warning: routing table indicates that interface %s is active. " 3712804529fSAnatoly Burakov "Skipping unbind" % dev_id, file=sys.stderr) 372c6dab2a8SThomas Monjalon return 373c6dab2a8SThomas Monjalon 374c6dab2a8SThomas Monjalon # write to /sys to unbind 375c6dab2a8SThomas Monjalon filename = "/sys/bus/pci/drivers/%s/unbind" % dev["Driver_str"] 376c6dab2a8SThomas Monjalon try: 377c6dab2a8SThomas Monjalon f = open(filename, "a") 378c6dab2a8SThomas Monjalon except: 3792804529fSAnatoly Burakov sys.exit("Error: unbind failed for %s - Cannot open %s" % 3802804529fSAnatoly Burakov (dev_id, filename)) 381c6dab2a8SThomas Monjalon f.write(dev_id) 382c6dab2a8SThomas Monjalon f.close() 383c6dab2a8SThomas Monjalon 384c6dab2a8SThomas Monjalon 385c6dab2a8SThomas Monjalondef bind_one(dev_id, driver, force): 386c6dab2a8SThomas Monjalon '''Bind the device given by "dev_id" to the driver "driver". If the device 387c6dab2a8SThomas Monjalon is already bound to a different driver, it will be unbound first''' 388c6dab2a8SThomas Monjalon dev = devices[dev_id] 389c6dab2a8SThomas Monjalon saved_driver = None # used to rollback any unbind in case of failure 390c6dab2a8SThomas Monjalon 391c6dab2a8SThomas Monjalon # prevent disconnection of our ssh session 392c6dab2a8SThomas Monjalon if dev["Ssh_if"] and not force: 3932804529fSAnatoly Burakov print("Warning: routing table indicates that interface %s is active. " 3942804529fSAnatoly Burakov "Not modifying" % dev_id, file=sys.stderr) 395c6dab2a8SThomas Monjalon return 396c6dab2a8SThomas Monjalon 397c6dab2a8SThomas Monjalon # unbind any existing drivers we don't want 398c6dab2a8SThomas Monjalon if has_driver(dev_id): 399c6dab2a8SThomas Monjalon if dev["Driver_str"] == driver: 4002804529fSAnatoly Burakov print("Notice: %s already bound to driver %s, skipping" % 4012804529fSAnatoly Burakov (dev_id, driver), file=sys.stderr) 402c6dab2a8SThomas Monjalon return 403c6dab2a8SThomas Monjalon else: 404c6dab2a8SThomas Monjalon saved_driver = dev["Driver_str"] 405c6dab2a8SThomas Monjalon unbind_one(dev_id, force) 406c6dab2a8SThomas Monjalon dev["Driver_str"] = "" # clear driver string 407c6dab2a8SThomas Monjalon 4082fc35029SGuduri Prathyusha # For kernels >= 3.15 driver_override can be used to specify the driver 4092fc35029SGuduri Prathyusha # for a device rather than relying on the driver to provide a positive 4102fc35029SGuduri Prathyusha # match of the device. The existing process of looking up 4112fc35029SGuduri Prathyusha # the vendor and device ID, adding them to the driver new_id, 4122fc35029SGuduri Prathyusha # will erroneously bind other devices too which has the additional burden 4132fc35029SGuduri Prathyusha # of unbinding those devices 414c6dab2a8SThomas Monjalon if driver in dpdk_drivers: 4152fc35029SGuduri Prathyusha filename = "/sys/bus/pci/devices/%s/driver_override" % dev_id 4162fc35029SGuduri Prathyusha if os.path.exists(filename): 4172fc35029SGuduri Prathyusha try: 4182fc35029SGuduri Prathyusha f = open(filename, "w") 4192fc35029SGuduri Prathyusha except: 4202fc35029SGuduri Prathyusha print("Error: bind failed for %s - Cannot open %s" 4212804529fSAnatoly Burakov % (dev_id, filename), file=sys.stderr) 4222fc35029SGuduri Prathyusha return 4232fc35029SGuduri Prathyusha try: 4242fc35029SGuduri Prathyusha f.write("%s" % driver) 4252fc35029SGuduri Prathyusha f.close() 4262fc35029SGuduri Prathyusha except: 4272fc35029SGuduri Prathyusha print("Error: bind failed for %s - Cannot write driver %s to " 4282804529fSAnatoly Burakov "PCI ID " % (dev_id, driver), file=sys.stderr) 4292fc35029SGuduri Prathyusha return 4302fc35029SGuduri Prathyusha # For kernels < 3.15 use new_id to add PCI id's to the driver 4312fc35029SGuduri Prathyusha else: 432c6dab2a8SThomas Monjalon filename = "/sys/bus/pci/drivers/%s/new_id" % driver 433c6dab2a8SThomas Monjalon try: 434c6dab2a8SThomas Monjalon f = open(filename, "w") 435c6dab2a8SThomas Monjalon except: 436c6dab2a8SThomas Monjalon print("Error: bind failed for %s - Cannot open %s" 4372804529fSAnatoly Burakov % (dev_id, filename), file=sys.stderr) 438c6dab2a8SThomas Monjalon return 439c6dab2a8SThomas Monjalon try: 4408ad08a28SGuduri Prathyusha # Convert Device and Vendor Id to int to write to new_id 4418ad08a28SGuduri Prathyusha f.write("%04x %04x" % (int(dev["Vendor"],16), 4428ad08a28SGuduri Prathyusha int(dev["Device"], 16))) 443c6dab2a8SThomas Monjalon f.close() 444c6dab2a8SThomas Monjalon except: 445c6dab2a8SThomas Monjalon print("Error: bind failed for %s - Cannot write new PCI ID to " 4462804529fSAnatoly Burakov "driver %s" % (dev_id, driver), file=sys.stderr) 447c6dab2a8SThomas Monjalon return 448c6dab2a8SThomas Monjalon 449c6dab2a8SThomas Monjalon # do the bind by writing to /sys 450c6dab2a8SThomas Monjalon filename = "/sys/bus/pci/drivers/%s/bind" % driver 451c6dab2a8SThomas Monjalon try: 452c6dab2a8SThomas Monjalon f = open(filename, "a") 453c6dab2a8SThomas Monjalon except: 454c6dab2a8SThomas Monjalon print("Error: bind failed for %s - Cannot open %s" 4552804529fSAnatoly Burakov % (dev_id, filename), file=sys.stderr) 456c6dab2a8SThomas Monjalon if saved_driver is not None: # restore any previous driver 457c6dab2a8SThomas Monjalon bind_one(dev_id, saved_driver, force) 458c6dab2a8SThomas Monjalon return 459c6dab2a8SThomas Monjalon try: 460c6dab2a8SThomas Monjalon f.write(dev_id) 461c6dab2a8SThomas Monjalon f.close() 462c6dab2a8SThomas Monjalon except: 463c6dab2a8SThomas Monjalon # for some reason, closing dev_id after adding a new PCI ID to new_id 464c6dab2a8SThomas Monjalon # results in IOError. however, if the device was successfully bound, 465c6dab2a8SThomas Monjalon # we don't care for any errors and can safely ignore IOError 466c3ce205dSGuduri Prathyusha tmp = get_pci_device_details(dev_id, True) 467c6dab2a8SThomas Monjalon if "Driver_str" in tmp and tmp["Driver_str"] == driver: 468c6dab2a8SThomas Monjalon return 469c6dab2a8SThomas Monjalon print("Error: bind failed for %s - Cannot bind to driver %s" 4702804529fSAnatoly Burakov % (dev_id, driver), file=sys.stderr) 471c6dab2a8SThomas Monjalon if saved_driver is not None: # restore any previous driver 472c6dab2a8SThomas Monjalon bind_one(dev_id, saved_driver, force) 473c6dab2a8SThomas Monjalon return 474c6dab2a8SThomas Monjalon 475720b7a05SGuduri Prathyusha # For kernels > 3.15 driver_override is used to bind a device to a driver. 476720b7a05SGuduri Prathyusha # Before unbinding it, overwrite driver_override with empty string so that 477720b7a05SGuduri Prathyusha # the device can be bound to any other driver 478720b7a05SGuduri Prathyusha filename = "/sys/bus/pci/devices/%s/driver_override" % dev_id 479720b7a05SGuduri Prathyusha if os.path.exists(filename): 480720b7a05SGuduri Prathyusha try: 481720b7a05SGuduri Prathyusha f = open(filename, "w") 482720b7a05SGuduri Prathyusha except: 4832804529fSAnatoly Burakov sys.exit("Error: unbind failed for %s - Cannot open %s" 484720b7a05SGuduri Prathyusha % (dev_id, filename)) 485720b7a05SGuduri Prathyusha try: 486720b7a05SGuduri Prathyusha f.write("\00") 487720b7a05SGuduri Prathyusha f.close() 488720b7a05SGuduri Prathyusha except: 4892804529fSAnatoly Burakov sys.exit("Error: unbind failed for %s - Cannot open %s" 490720b7a05SGuduri Prathyusha % (dev_id, filename)) 491720b7a05SGuduri Prathyusha 492c6dab2a8SThomas Monjalon 493c6dab2a8SThomas Monjalondef unbind_all(dev_list, force=False): 494c6dab2a8SThomas Monjalon """Unbind method, takes a list of device locations""" 495657c7133SFerruh Yigit 496657c7133SFerruh Yigit if dev_list[0] == "dpdk": 497657c7133SFerruh Yigit for d in devices.keys(): 498657c7133SFerruh Yigit if "Driver_str" in devices[d]: 499657c7133SFerruh Yigit if devices[d]["Driver_str"] in dpdk_drivers: 500657c7133SFerruh Yigit unbind_one(devices[d]["Slot"], force) 501657c7133SFerruh Yigit return 502657c7133SFerruh Yigit 50315f6aac7SAnatoly Burakov try: 504c6dab2a8SThomas Monjalon dev_list = map(dev_id_from_dev_name, dev_list) 50515f6aac7SAnatoly Burakov except ValueError as ex: 50615f6aac7SAnatoly Burakov print(ex) 50715f6aac7SAnatoly Burakov sys.exit(1) 50815f6aac7SAnatoly Burakov 509c6dab2a8SThomas Monjalon for d in dev_list: 510c6dab2a8SThomas Monjalon unbind_one(d, force) 511c6dab2a8SThomas Monjalon 512c6dab2a8SThomas Monjalon 513c6dab2a8SThomas Monjalondef bind_all(dev_list, driver, force=False): 514c6dab2a8SThomas Monjalon """Bind method, takes a list of device locations""" 515c6dab2a8SThomas Monjalon global devices 516c6dab2a8SThomas Monjalon 51715f6aac7SAnatoly Burakov # a common user error is to forget to specify the driver the devices need to 51815f6aac7SAnatoly Burakov # be bound to. check if the driver is a valid device, and if it is, show 51915f6aac7SAnatoly Burakov # a meaningful error. 52015f6aac7SAnatoly Burakov try: 52115f6aac7SAnatoly Burakov dev_id_from_dev_name(driver) 52215f6aac7SAnatoly Burakov # if we've made it this far, this means that the "driver" was a valid 52315f6aac7SAnatoly Burakov # device string, so it's probably not a valid driver name. 52415f6aac7SAnatoly Burakov sys.exit("Error: Driver '%s' does not look like a valid driver. " \ 52515f6aac7SAnatoly Burakov "Did you forget to specify the driver to bind devices to?" % driver) 52615f6aac7SAnatoly Burakov except ValueError: 52715f6aac7SAnatoly Burakov # driver generated error - it's not a valid device ID, so all is well 52815f6aac7SAnatoly Burakov pass 52915f6aac7SAnatoly Burakov 530681a6728SAnatoly Burakov # check if we're attempting to bind to a driver that isn't loaded 53143623124SPavan Nikhilesh if not module_is_loaded(driver.replace('-','_')): 532681a6728SAnatoly Burakov sys.exit("Error: Driver '%s' is not loaded." % driver) 533681a6728SAnatoly Burakov 53415f6aac7SAnatoly Burakov try: 535c6dab2a8SThomas Monjalon dev_list = map(dev_id_from_dev_name, dev_list) 53615f6aac7SAnatoly Burakov except ValueError as ex: 53715f6aac7SAnatoly Burakov sys.exit(ex) 538c6dab2a8SThomas Monjalon 539c6dab2a8SThomas Monjalon for d in dev_list: 540c6dab2a8SThomas Monjalon bind_one(d, driver, force) 541c6dab2a8SThomas Monjalon 542e4839614SPavel Shirshov # For kernels < 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 58536f66d1cSBruce Richardsondef show_device_status(devices_type, device_name, if_field=False): 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 602109cb989SAnatoly Burakov n_devs = len(dpdk_drv) + len(kernel_drv) + len(no_drv) 603109cb989SAnatoly Burakov 604109cb989SAnatoly Burakov # don't bother displaying anything if there are no devices 605109cb989SAnatoly Burakov if n_devs == 0: 606109cb989SAnatoly Burakov msg = "No '%s' devices detected" % device_name 607109cb989SAnatoly Burakov print("") 608109cb989SAnatoly Burakov print(msg) 609109cb989SAnatoly Burakov print("".join('=' * len(msg))) 610109cb989SAnatoly Burakov return 611109cb989SAnatoly Burakov 612c6dab2a8SThomas Monjalon # print each category separately, so we can clearly see what's used by DPDK 613109cb989SAnatoly Burakov if len(dpdk_drv) != 0: 6148ad08a28SGuduri Prathyusha display_devices("%s devices using DPDK-compatible driver" % device_name, 6158ad08a28SGuduri Prathyusha dpdk_drv, "drv=%(Driver_str)s unused=%(Module_str)s") 616109cb989SAnatoly Burakov if len(kernel_drv) != 0: 61736f66d1cSBruce Richardson if_text = "" 61836f66d1cSBruce Richardson if if_field: 61936f66d1cSBruce Richardson if_text = "if=%(Interface)s " 620c7dd412bSGuduri Prathyusha display_devices("%s devices using kernel driver" % device_name, kernel_drv, 62136f66d1cSBruce Richardson if_text + "drv=%(Driver_str)s " 622c6dab2a8SThomas Monjalon "unused=%(Module_str)s %(Active)s") 623109cb989SAnatoly Burakov if len(no_drv) != 0: 6248ad08a28SGuduri Prathyusha display_devices("Other %s devices" % device_name, no_drv, 6258ad08a28SGuduri Prathyusha "unused=%(Module_str)s") 626c6dab2a8SThomas Monjalon 627c7dd412bSGuduri Prathyushadef show_status(): 628c7dd412bSGuduri Prathyusha '''Function called when the script is passed the "--status" option. 629c7dd412bSGuduri Prathyusha Displays to the user what devices are bound to the igb_uio driver, the 630c7dd412bSGuduri Prathyusha kernel driver or to no driver''' 631c6dab2a8SThomas Monjalon 632b153c00bSFerruh Yigit if status_dev == "net" or status_dev == "all": 63336f66d1cSBruce Richardson show_device_status(network_devices, "Network", if_field=True) 634b153c00bSFerruh Yigit 63507488e29SNicolas Chautru if status_dev == "baseband" or status_dev == "all": 63607488e29SNicolas Chautru show_device_status(baseband_devices, "Baseband") 63707488e29SNicolas Chautru 638b153c00bSFerruh Yigit if status_dev == "crypto" or status_dev == "all": 639c7dd412bSGuduri Prathyusha show_device_status(crypto_devices, "Crypto") 640b153c00bSFerruh Yigit 641b153c00bSFerruh Yigit if status_dev == "event" or status_dev == "all": 64232a02dbfSGuduri Prathyusha show_device_status(eventdev_devices, "Eventdev") 643b153c00bSFerruh Yigit 644b153c00bSFerruh Yigit if status_dev == "mempool" or status_dev == "all": 64580a1858dSGuduri Prathyusha show_device_status(mempool_devices, "Mempool") 646c6dab2a8SThomas Monjalon 6479d35895eSSunila Sahu if status_dev == "compress" or status_dev == "all": 6489d35895eSSunila Sahu show_device_status(compress_devices , "Compress") 6499d35895eSSunila Sahu 65012d4777aSBruce Richardson if status_dev == "misc" or status_dev == "all": 65112d4777aSBruce Richardson show_device_status(misc_devices, "Misc (rawdev)") 6529d35895eSSunila Sahu 653781eafc9SBruce Richardson 654781eafc9SBruce Richardsondef pci_glob(arg): 655781eafc9SBruce Richardson '''Returns a list containing either: 656781eafc9SBruce Richardson * List of PCI B:D:F matching arg, using shell wildcards e.g. 80:04.* 657781eafc9SBruce Richardson * Only the passed arg if matching list is empty''' 658781eafc9SBruce Richardson sysfs_path = "/sys/bus/pci/devices" 659781eafc9SBruce Richardson for _glob in [arg, '0000:' + arg]: 660781eafc9SBruce Richardson paths = [basename(path) for path in glob(path_join(sysfs_path, _glob))] 661781eafc9SBruce Richardson if paths: 662781eafc9SBruce Richardson return paths 663781eafc9SBruce Richardson return [arg] 664781eafc9SBruce Richardson 665781eafc9SBruce Richardson 666c6dab2a8SThomas Monjalondef parse_args(): 667c6dab2a8SThomas Monjalon '''Parses the command-line arguments given by the user and takes the 668c6dab2a8SThomas Monjalon appropriate action for each''' 669c6dab2a8SThomas Monjalon global b_flag 670c6dab2a8SThomas Monjalon global status_flag 671b153c00bSFerruh Yigit global status_dev 672c6dab2a8SThomas Monjalon global force_flag 673c6dab2a8SThomas Monjalon global args 674c6dab2a8SThomas Monjalon if len(sys.argv) <= 1: 675c6dab2a8SThomas Monjalon usage() 676c6dab2a8SThomas Monjalon sys.exit(0) 677c6dab2a8SThomas Monjalon 678c6dab2a8SThomas Monjalon try: 679c6dab2a8SThomas Monjalon opts, args = getopt.getopt(sys.argv[1:], "b:us", 680b153c00bSFerruh Yigit ["help", "usage", "status", "status-dev=", 681b153c00bSFerruh Yigit "force", "bind=", "unbind", ]) 682c6dab2a8SThomas Monjalon except getopt.GetoptError as error: 683c6dab2a8SThomas Monjalon print(str(error)) 684c6dab2a8SThomas Monjalon print("Run '%s --usage' for further information" % sys.argv[0]) 685c6dab2a8SThomas Monjalon sys.exit(1) 686c6dab2a8SThomas Monjalon 687c6dab2a8SThomas Monjalon for opt, arg in opts: 688c6dab2a8SThomas Monjalon if opt == "--help" or opt == "--usage": 689c6dab2a8SThomas Monjalon usage() 690c6dab2a8SThomas Monjalon sys.exit(0) 691b153c00bSFerruh Yigit if opt == "--status-dev": 692b153c00bSFerruh Yigit status_flag = True 693b153c00bSFerruh Yigit status_dev = arg 694c6dab2a8SThomas Monjalon if opt == "--status" or opt == "-s": 695c6dab2a8SThomas Monjalon status_flag = True 696b153c00bSFerruh Yigit status_dev = "all" 697c6dab2a8SThomas Monjalon if opt == "--force": 698c6dab2a8SThomas Monjalon force_flag = True 699c6dab2a8SThomas Monjalon if opt == "-b" or opt == "-u" or opt == "--bind" or opt == "--unbind": 700c6dab2a8SThomas Monjalon if b_flag is not None: 7012804529fSAnatoly Burakov sys.exit("Error: binding and unbinding are mutually exclusive") 702c6dab2a8SThomas Monjalon if opt == "-u" or opt == "--unbind": 703c6dab2a8SThomas Monjalon b_flag = "none" 704c6dab2a8SThomas Monjalon else: 705c6dab2a8SThomas Monjalon b_flag = arg 706c6dab2a8SThomas Monjalon 707781eafc9SBruce Richardson # resolve any PCI globs in the args 708781eafc9SBruce Richardson new_args = [] 709781eafc9SBruce Richardson for arg in args: 710781eafc9SBruce Richardson new_args.extend(pci_glob(arg)) 711781eafc9SBruce Richardson args = new_args 712c6dab2a8SThomas Monjalon 713c6dab2a8SThomas Monjalondef do_arg_actions(): 714c6dab2a8SThomas Monjalon '''do the actual action requested by the user''' 715c6dab2a8SThomas Monjalon global b_flag 716c6dab2a8SThomas Monjalon global status_flag 717c6dab2a8SThomas Monjalon global force_flag 718c6dab2a8SThomas Monjalon global args 719c6dab2a8SThomas Monjalon 720c6dab2a8SThomas Monjalon if b_flag is None and not status_flag: 721c6dab2a8SThomas Monjalon print("Error: No action specified for devices. " 7222804529fSAnatoly Burakov "Please give a -b or -u option", file=sys.stderr) 7232804529fSAnatoly Burakov usage() 724c6dab2a8SThomas Monjalon sys.exit(1) 725c6dab2a8SThomas Monjalon 726c6dab2a8SThomas Monjalon if b_flag is not None and len(args) == 0: 7272804529fSAnatoly Burakov print("Error: No devices specified.", file=sys.stderr) 7282804529fSAnatoly Burakov usage() 729c6dab2a8SThomas Monjalon sys.exit(1) 730c6dab2a8SThomas Monjalon 731c6dab2a8SThomas Monjalon if b_flag == "none" or b_flag == "None": 732c6dab2a8SThomas Monjalon unbind_all(args, force_flag) 733c6dab2a8SThomas Monjalon elif b_flag is not None: 734c6dab2a8SThomas Monjalon bind_all(args, b_flag, force_flag) 735c6dab2a8SThomas Monjalon if status_flag: 736c6dab2a8SThomas Monjalon if b_flag is not None: 737ea9f00f7SGuduri Prathyusha clear_data() 7388ad08a28SGuduri Prathyusha # refresh if we have changed anything 7398ad08a28SGuduri Prathyusha get_device_details(network_devices) 74007488e29SNicolas Chautru get_device_details(baseband_devices) 7418ad08a28SGuduri Prathyusha get_device_details(crypto_devices) 74232a02dbfSGuduri Prathyusha get_device_details(eventdev_devices) 74380a1858dSGuduri Prathyusha get_device_details(mempool_devices) 7449d35895eSSunila Sahu get_device_details(compress_devices) 74512d4777aSBruce Richardson get_device_details(misc_devices) 746c6dab2a8SThomas Monjalon show_status() 747c6dab2a8SThomas Monjalon 748c6dab2a8SThomas Monjalon 749c6dab2a8SThomas Monjalondef main(): 750c6dab2a8SThomas Monjalon '''program main function''' 7511a5a9cb3SAnatoly Burakov # check if lspci is installed, suppress any output 7521a5a9cb3SAnatoly Burakov with open(os.devnull, 'w') as devnull: 7531a5a9cb3SAnatoly Burakov ret = subprocess.call(['which', 'lspci'], 7541a5a9cb3SAnatoly Burakov stdout=devnull, stderr=devnull) 7551a5a9cb3SAnatoly Burakov if ret != 0: 7562804529fSAnatoly Burakov sys.exit("'lspci' not found - please install 'pciutils'") 757c6dab2a8SThomas Monjalon parse_args() 758c6dab2a8SThomas Monjalon check_modules() 759ea9f00f7SGuduri Prathyusha clear_data() 7608ad08a28SGuduri Prathyusha get_device_details(network_devices) 76107488e29SNicolas Chautru get_device_details(baseband_devices) 7628ad08a28SGuduri Prathyusha get_device_details(crypto_devices) 76332a02dbfSGuduri Prathyusha get_device_details(eventdev_devices) 76480a1858dSGuduri Prathyusha get_device_details(mempool_devices) 7659d35895eSSunila Sahu get_device_details(compress_devices) 76612d4777aSBruce Richardson get_device_details(misc_devices) 767c6dab2a8SThomas Monjalon do_arg_actions() 768c6dab2a8SThomas Monjalon 769c6dab2a8SThomas Monjalonif __name__ == "__main__": 770c6dab2a8SThomas Monjalon main() 771