Skip to content

Commit

Permalink
Merge branch 'master' into tswhison/uio_plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
tswhison committed Jul 13, 2023
2 parents b751689 + f477f11 commit 6369874
Show file tree
Hide file tree
Showing 13 changed files with 474 additions and 114 deletions.
24 changes: 24 additions & 0 deletions binaries/opae.io/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

#pragma once

#include <iostream>
#include <sys/ioctl.h>
#include <opae/vfio.h>


Expand Down Expand Up @@ -215,6 +217,28 @@ struct vfio_device {

return b;
}

#define VFIO_VF_TOKEN_LEN (16)
int set_vf_token(const char *vf_token)
{
struct vfio_device_feature *df;
int ret;

df = (struct vfio_device_feature *)
new uint8_t[sizeof(struct vfio_device_feature) + VFIO_VF_TOKEN_LEN];

df->argsz = sizeof(df) + VFIO_VF_TOKEN_LEN;
df->flags = VFIO_DEVICE_FEATURE_SET | VFIO_DEVICE_FEATURE_PCI_VF_TOKEN;
memcpy(df->data, vf_token, VFIO_VF_TOKEN_LEN);

ret = ioctl(v_->device.device_fd, VFIO_DEVICE_FEATURE, df);
delete[] df;

if (ret)
std::cerr << "ioctl failed " << errno << std::endl;

return ret;
}
private:
opae_vfio *v_;
vfio_device(opae_vfio *v)
Expand Down
26 changes: 26 additions & 0 deletions binaries/opae.io/pymain.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import os
import pdb
import sys
import libvfio
import uuid
from opae.io import utils, pci
from opae.io.utils import Path
Expand Down Expand Up @@ -148,6 +149,29 @@ class poke_action(base_action):
wr(args.offset, args.value)
raise SystemExit(0)
class vf_token_action(base_action):
open_device = True
def add_args(self):
self.parser.add_argument('vftoken', default=None)
def execute(self, args):
if not self.device:
raise SystemExit('Need device for poke.')
try:
token_uuid = uuid.UUID(args.vftoken)
ret = self.device.set_vf_token(token_uuid.bytes)
if ret:
print('Failed to set token')
raise SystemExit(1)
print(f'Successfully set vf token to {str(token_uuid)}')
except ValueError:
print('Invalid vf_token')
raise SystemExit(1)
raise SystemExit(0)
class script_action(base_action):
open_device = True
Expand Down Expand Up @@ -218,6 +242,7 @@ actions = {
'poke': poke_action,
'walk': walk_action,
'dump': dump_action,
'vf_token': vf_token_action,
}
def do_action(action, args):
Expand All @@ -244,6 +269,7 @@ def show_help():
"opae.io init [-d <PCI_ADDRESS>] <USER>[:<GROUP>]"
"opae.io release [-d <PCI_ADDRESS>]"
"opae.io [-d <PCI_ADDRESS>]"
"opae.io [-d <PCI_ADDRESS>] vf_token <GUID>"
"opae.io [-d <PCI_ADDRESS>] [-r <REGION_NUMBER>] [-a <ACCESS_MODE>]"
"opae.io [-d <PCI_ADDRESS>] [-r <REGION_NUMBER>] [-a <ACCESS_MODE>] walk [<OFFSET>] [-u | --show-uuid]"
"opae.io [-d <PCI_ADDRESS>] [-r <REGION_NUMBER>] [-a <ACCESS_MODE>] dump [<OFFSET>] [-o | --output <FILE>] [-f | --format (hex, bin)] [ -c | --count <WORD COUNT>]
Expand Down
1 change: 1 addition & 0 deletions binaries/opae.io/vfiobindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ PYBIND11_MODULE(libvfio, m)
.def("config_write8", &vfio_device::config_write<uint8_t>)
.def("__repr__", &vfio_device::address)
.def("allocate", &vfio_device::buffer_allocate)
.def("set_vf_token", &vfio_device::set_vf_token)
.def_property_readonly("pci_address", &vfio_device::address)
.def_property_readonly("num_regions", &vfio_device::num_regions)
.def_property_readonly("regions", &vfio_device::regions);
Expand Down
4 changes: 2 additions & 2 deletions opae.spec.fedora
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ done

# Make rpmlint happy about install permissions
# admin tools
for file in %{buildroot}%{python3_sitelib}/opae/admin/tools/{fpgaflash,fpgaotsu,fpgaport,fpgasupdate,ihex2ipmi,rsu,super_rsu,bitstream_info,opaevfio,pci_device,fpgareg}.py; do
for file in %{buildroot}%{python3_sitelib}/opae/admin/tools/{fpgaflash,fpgaotsu,fpgaport,fpgasupdate,ihex2ipmi,rsu,super_rsu,bitstream_info,opaevfio,pci_device,fpgareg,n5010tool}.py; do
chmod a+x $file
done
# ethernet
Expand Down Expand Up @@ -314,7 +314,7 @@ done
%{_bindir}/nlb3
%{_bindir}/nlb7
%{_bindir}/vabtool

%{_bindir}/n5010tool

%{_usr}/share/opae/*
%{python3_sitelib}/ethernet*
Expand Down
23 changes: 18 additions & 5 deletions opae.spec.rhel
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,18 @@ OPAE headers, tools, sample source, and documentation
%cmake -DOPAE_MINIMAL_BUILD=ON \
-DFETCHCONTENT_FULLY_DISCONNECTED=ON \
-DFETCHCONTENT_BASE_DIR=_build/_deps
%if 0%{rhel} > 8

%if 0%{?rhel}
%if 0%{rhel} <= 8
echo "Building for RHEL <= 8"
%make_build
%else
echo "Building for RHEL >= 9"
%cmake_build
%endif
%else
%make_build
echo "Building for non-RHEL"
%cmake_build
%endif

%install
Expand Down Expand Up @@ -107,10 +115,14 @@ cp binaries/opae.io/*.{cpp,h,py} %{buildroot}%{_usr}/src/opae/samples/opae.io/
cp binaries/opae.io/opae/io/*.py %{buildroot}%{_usr}/src/opae/samples/opae.io/opae/io
cp binaries/opae.io/scripts/*.py %{buildroot}%{_usr}/src/opae/samples/opae.io/scripts

%if 0%{rhel} > 8
%if 0%{?rhel}
%if 0%{rhel} <= 8
%make_install
%else
%cmake_install
%endif
%else
%make_install
%cmake_install
%endif

#cmake
Expand All @@ -129,7 +141,7 @@ done

# Make rpmlint happy about install permissions
# admin tools
for file in %{buildroot}%{python3_sitelib}/opae/admin/tools/{fpgaflash,fpgaotsu,fpgaport,fpgasupdate,ihex2ipmi,rsu,super_rsu,bitstream_info,opaevfio,pci_device}.py; do
for file in %{buildroot}%{python3_sitelib}/opae/admin/tools/{fpgaflash,fpgaotsu,fpgaport,fpgasupdate,ihex2ipmi,rsu,super_rsu,bitstream_info,opaevfio,pci_device,fpgareg,n5010tool}.py; do
chmod a+x $file
done
# ethernet
Expand Down Expand Up @@ -298,6 +310,7 @@ done
%{_bindir}/nlb3
%{_bindir}/nlb7
%{_bindir}/vabtool
%{_bindir}/n5010tool

%{_usr}/share/opae/*
%{python3_sitelib}/ethernet*
Expand Down
1 change: 1 addition & 0 deletions packaging/opae/deb/opae-devel.install
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ usr/bin/nlb0
usr/bin/nlb3
usr/bin/nlb7
usr/bin/vabtool
usr/bin/n5010tool
usr/share/opae/*
usr/lib/python3/dist-packages/ethernet*
usr/lib/python3/dist-packages/hssi_ethernet*
Expand Down
4 changes: 2 additions & 2 deletions python/opae.admin/opae/admin/fpga.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,13 +258,13 @@ def max10_version(self):
def bmcfw_version(self):
spi = self.spi_bus
if spi:
node = spi.find_one('bmcfw_flash_ctrl/bmcfw_version')
node = spi.find_one('bmcfw_version')
value = int(node.value, 16)
return max10_or_nios_version(value)
else:
pmci = self.pmci_bus
if pmci:
node = spi.find_one('bmcfw_flash_ctrl/bmcfw_version')
node = spi.find_one('bmcfw_version')
value = int(node.value, 16)
return max10_or_nios_version(value)

Expand Down
200 changes: 200 additions & 0 deletions python/opae.admin/opae/admin/tools/n5010tool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
#!/usr/bin/env python3
# Copyright(c) 2023, Silicom Denmark A/S
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Intel Corporation nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.import opae.admin.tools.regmap_debugfs as regm

import argparse
import math
import sys
import re
import os

import opae.admin.tools.regmap_debugfs as regm
from opae.admin.utils import max10_or_nios_version
from opae.admin.fpga import fpga

regmap_path = '/sys/kernel/debug/regmap/'

PCI_VENDOR_ID_SILICOM_DENMARK = 0x1c2c
N5010_BMC_VERSION_QSFP_RXPWR = 0x10c00 # version 1.12.0

N5010_BMC_OFFSET = 0x300800
N5010_QSFP0_RXPWR = 0x1c8
N5010_PHY_CSR_0 = 0x40c
N5010_PHY_CSR_1 = 0x410
N5010_PHY_ABSENT_0 = 1 << 7
N5010_PHY_ABSENT_1 = 1 << 23


def normalize_bdf(bdf):
pat = r'[0-9a-fA-F]{4}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\.[0-9a-fA-F]$'
if re.match(pat, bdf):
return bdf

if re.match(r'[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\.[0-9a-fA-F]$', bdf):
return "0000:{}".format(bdf)
sys.stderr.write('invalid bdf: {}\n'.format(bdf))
raise SystemExit(os.EX_USAGE)


def init_regmap(regmap_dir):
"""Returns an initialized regmap object"""
try:
regm.is_regmap_dir(regmap_dir)
except argparse.ArgumentTypeError:
sys.stderr.write(
'Regmap not found, path name: {}. Root privileges required.\n'.
format(regmap_dir))
raise SystemExit(os.EX_UNAVAILABLE)

regmap = regm.RegmapDebugfs(regmap_dir)
regmap.get_range_info()
regmap.get_register_info()
return regmap


def read_power(regmap):
"""Returns list for each QSFP of list of Rx pwr"""
qsfps = []
for i in range(0, 16, 4):
rx_pwrs = []
addr = N5010_BMC_OFFSET + N5010_QSFP0_RXPWR + i
val = regmap.reg_read(addr)

for f in range(0, 4):
pwr = val & 0xff
rx_pwrs.append(pwr)
val >>= 8
qsfps.append(rx_pwrs)
return qsfps


def read_qsfp_insert(regmap):
"""Returns list of QSFP present bools."""
qsfps = []
for p in range(0, 4):
if p == 0:
offset = N5010_PHY_CSR_1
bit = N5010_PHY_ABSENT_0
elif p == 1:
offset = N5010_PHY_CSR_1
bit = N5010_PHY_ABSENT_1
elif p == 2:
offset = N5010_PHY_CSR_0
bit = N5010_PHY_ABSENT_0
elif p == 3:
offset = N5010_PHY_CSR_0
bit = N5010_PHY_ABSENT_1

val = regmap.reg_read(N5010_BMC_OFFSET + offset)
val &= bit
present = (val == 0)
qsfps.append(present)
return qsfps


def pwr2str(qsfps, unit):
out = []
for rx_pwrs in qsfps:
out2 = []
for rx_pwr in rx_pwrs:
if rx_pwr == 0:
out3 = " NA"
else:
# val read is in steps of 25.6 uW
val = 25.6 * rx_pwr
if unit == 'uW':
out3 = f"{val:>5.0f}"
else:
# conversion from uW to dBm
val = 10.0 * math.log10(val * 0.001)
out3 = f"{val:>5.2f}"
out2.append(out3)
out.append(out2)
return out


def print_power(qsfps, uW, qspfs_insert):
"""Print QSFP present and Rx pwr in chosen unit for each QSFP"""
if uW:
unit = 'uW'
else:
unit = 'dbm'
val = pwr2str(qsfps, unit)
port = 0
print("RX pwr: present\t lane1 \t lane2 \t lane3 \t lane4 \t unit")
for qsfp, present in zip(val, qspfs_insert):
if present:
qsfp_present = f"yes"
else:
qsfp_present = f"no"
p_str = f"Port {port}: {qsfp_present:>7s}\t {qsfp[0]:s}\t " +\
f"{qsfp[1]:s}\t {qsfp[2]:s}\t {qsfp[3]:s}\t {unit}"
print(p_str)
port += 1


def main():
descr = 'Show QSFP status and optical Rx power levels for N501x card(s)'
parser = argparse.ArgumentParser(description=descr)
parser.add_argument('bdf', nargs='?',
help=('PCIe address '
'(eg 04:00.0 or 0000:04:00.0)'))
parser.add_argument('--uW', action='store_true',
help='output in mW instead of dBm')

args = parser.parse_args()
if args.bdf:
args.bdf = normalize_bdf(args.bdf)
compatible = fpga.enum([
{'pci_node.pci_address': str(args.bdf),
'pci_node.vendor_id': PCI_VENDOR_ID_SILICOM_DENMARK}
])
else:
compatible = fpga.enum([
{'pci_node.vendor_id': PCI_VENDOR_ID_SILICOM_DENMARK}
])

if not compatible:
sys.stderr.write('No compatible devices found\n')
raise SystemExit(os.EX_USAGE)

for c in compatible:
print("\nQSFP info for card at: {}".format(c.pci_node.pci_address))
spi_bus = str(c.fme.spi_bus)

if not (c.fme.bmcfw_version >=
max10_or_nios_version(N5010_BMC_VERSION_QSFP_RXPWR)):
sys.stderr.write(
f'Device with BMC {c.fme.bmcfw_version} not supported\n')
else:
regmap = init_regmap(regmap_path+spi_bus)
rx_pwrs = read_power(regmap)
qsfps_insert = read_qsfp_insert(regmap)
print_power(rx_pwrs, args.uW, qsfps_insert)


if __name__ == "__main__":
main()
Loading

0 comments on commit 6369874

Please sign in to comment.