commit a60b96821be3fadaf89d643072488e4762b28d10 Author: Halil Pasic Date: Tue Dec 2 15:25:40 2025 +0100 smc_rnics: fix regression when PFT not available Before commit 0b965ae ("smc_rnics: Add support for Network Express RNIC in smc_rnics") the device type detection was based on PCI vendor and device ID. The aforementioned commit switched smc_rnics to doing the device type detection primarily on PCI function type (PFT), which is in general a sound thing to do. In certain virtualized environments however (most notably QEMU+KVM) PFT is generally not available, and even for passed through devices, as of now PFT 0 is reported regardless of the actual PFT as seen by G1 (i.e. LPAR). And that leads to not detecting passed through rnics as such, and generally displaying an empty list when smc_rnics is called with no parameters, even in a presence of rnics to display. The patch also degraded the ability of the script to handle unknown vendor id 0x15b3 devices gracefully. This can be relevant if a not enlightened version of the script is used on new hardware. Adding a warning about the surprise PFT 0 does not seem to be a good idea, because there are PCI devices which are readily available on s390x and for which PFT 0 is just expected: most notably virtio-pci, and frankly it isn't all that helpful either. On the other hand, using the PFT, when available and suitable, is still considered superior. Use the old PCI vendor and device ID based logic as a fall back when PFT is not available or not known. With this the regressions introduced by commit 0b965ae ("smc_rnics: Add support for Network Express RNIC in smc_rnics") shall be gone. While at it fix the handling of ports too. The call to set_RoCE_dev_and_port in the loop that iterates over network interfaces does not make sense; and 'RoCE Express' needs special handling as a device that has multiple ports and interfaces per PCI function regardless of the value the variable 'rawIDs'. I don't quite understand why grabbing port from the interface's dev_port attribute is a bad idea. That precedence was established by 05d1c7e ("smc_rnics: Fix RoCE Express2 port display"). My best guess is that dev_port is only valid if a PCI function can interact with multiple physical ports, which is not the case with RoCE Express2 and higher. So I am leaving that as is. Fixes: commit 0b965ae ("smc_rnics: Add support for Network Express RNIC in smc_rnics") Reviewed-by: Sidraya Jayagond Signed-off-by: Halil Pasic diff --git a/smc_rnics b/smc_rnics index 70b6f69..279da22 100755 --- a/smc_rnics +++ b/smc_rnics @@ -144,6 +144,26 @@ function set_by_firmware_lvl() { set_RoCE_dev_and_port $name; } +function set_by_pciid(){ + + case "$vend" in + "0x1014" ) # IBM + case "$id" in + "0x04ed") dev_type="ISM"; + int="n/a";; + esac;; + "0x15b3" ) # Mellanox + case "$id" in + "0x1003" | \ + "0x1004") dev_type="RoCE_Express"; + multiport_f=1;; + "0x1016") set_RoCE_dev_and_port "RoCE_Express2";; + "0x101e") set_by_firmware_lvl;; + *) set_RoCE_dev_and_port "Mlx_$id";; + esac;; + esac +} + function print_rnics() { # iterate over slots, as powered-off devices won't show elsewhere for fid in `ls -1 /sys/bus/pci/slots`; do @@ -188,12 +208,15 @@ function print_rnics() { dev_type="${vend#0x}:${id#0x}"; pft=`cat pft`; vfn=`cat vfn`; + multiport_f=0; if [ $rawIDs -eq 0 ]; then + # prefer PFT for disamgibuating devices case "$pft" in "0x05") dev_type="ISM"; int="n/a"; set_RoCE_pft_and_vfn "$pft" "$vfn";; "0x02") dev_type="RoCE_Express"; + multiport_f=1; set_RoCE_pft_and_vfn "$pft" "$vfn";; "0x0a") set_by_firmware_lvl; set_RoCE_pft_and_vfn "$pft" "$vfn";; @@ -201,15 +224,20 @@ function print_rnics() { "0x0f") set_RoCE_dev_and_port "Network_Express"; set_RoCE_pft_and_vfn "$pft" "$vfn";; *) + # but if that fails go via the pci IDs + set_by_pciid # For unknown PCI vendors, determine VF flag based on VFN value. # This ensures consistent handling even for unrecognized vendor devices - [ $all -eq 0 ] && continue + [ "$dev_type" = "${vend#0x}:${id#0x}" ] && [ $all -eq 0 ] && continue if (( 16#${vfn#0x} != 0 )); then vfn="y"; else vfn="n"; fi;; - esac + esac + else + set_RoCE_dev_and_port "$dev_type"; + [ "0x15b3" = "$vend" ] && [ "0x1004" = "$id" ] && multiport_f=1; fi pchid="`cat pchid | sed 's/^0x//'`"; pnetids="`cat util_string | sed 's/\x0/\x40/g' | iconv -f IBM-1047 -t ASCII`"; @@ -221,10 +249,10 @@ function print_rnics() { print_rnic; continue; fi - # one device can have multiple interfaces (one per port) for int in $interfaces; do + # one device can have multiple interfaces (one per port) cd /sys/bus/pci/devices/$addr/net/$int; - if [ "$dev_type" == "RoCE_Express" ] && [ -e dev_port ]; then + if [ $multiport_f -eq 1 ] && [ -e dev_port ]; then port=`cat dev_port`; fi print_rnic; -- 2.54.0